Merge "Zero-initialize CursorWindow buffer" into main
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 1b0ee63..f9cc125 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -348,6 +348,7 @@
     name: "android.location.flags-aconfig",
     package: "android.location.flags",
     container: "system",
+    exportable: true,
     srcs: [
         "location/java/android/location/flags/*.aconfig",
     ],
@@ -588,7 +589,6 @@
 java_aconfig_library {
     name: "android.view.inputmethod.flags-aconfig-java",
     aconfig_declarations: "android.view.inputmethod.flags-aconfig",
-    host_supported: true,
     defaults: ["framework-minus-apex-aconfig-java-defaults"],
 }
 
diff --git a/TEST_MAPPING b/TEST_MAPPING
index e469f16..ce0da7e 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -25,6 +25,12 @@
       "name": "FrameworksUiServicesTests"
     },
     {
+      "name": "FrameworksUiServicesNotificationTests"
+    },
+    {
+      "name": "FrameworksUiServicesZenTests"
+    },
+    {
       "name": "FrameworksInputMethodSystemServerTests_server_inputmethod"
     },
     {
diff --git a/apex/jobscheduler/service/aconfig/job.aconfig b/apex/jobscheduler/service/aconfig/job.aconfig
index 876274e..aae5bb3 100644
--- a/apex/jobscheduler/service/aconfig/job.aconfig
+++ b/apex/jobscheduler/service/aconfig/job.aconfig
@@ -126,3 +126,15 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "tune_quota_window_default_parameters"
+    namespace: "backstage_power"
+    description: "Tune default active/exempted bucket quota parameters"
+    bug: "401767691"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
index 54d337e..6dd7521 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/QuotaController.java
@@ -36,7 +36,6 @@
 import android.app.ActivityManager;
 import android.app.AlarmManager;
 import android.app.UidObserver;
-import android.app.compat.CompatChanges;
 import android.app.job.JobInfo;
 import android.app.usage.UsageEvents;
 import android.app.usage.UsageStatsManagerInternal;
@@ -54,6 +53,7 @@
 import android.os.Looper;
 import android.os.Message;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.Trace;
 import android.os.UserHandle;
 import android.provider.DeviceConfig;
@@ -74,6 +74,7 @@
 import com.android.server.AppSchedulingModuleThread;
 import com.android.server.LocalServices;
 import com.android.server.PowerAllowlistInternal;
+import com.android.server.compat.PlatformCompat;
 import com.android.server.job.ConstantsProto;
 import com.android.server.job.Flags;
 import com.android.server.job.JobSchedulerService;
@@ -157,6 +158,15 @@
     @Overridable // The change can be overridden in user build.
     static final long OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS = 374323858L;
 
+    /**
+     * When enabled this change id overrides the default quota parameters adjustment.
+     */
+    @VisibleForTesting
+    @ChangeId
+    @Disabled // Disabled by default
+    @Overridable // The change can be overridden in user build.
+    static final long OVERRIDE_QUOTA_ADJUST_DEFAULT_CONSTANTS = 378129159L;
+
     @VisibleForTesting
     static class ExecutionStats {
         /**
@@ -360,13 +370,13 @@
 
     /** How much time each app will have to run jobs within their standby bucket window. */
     private final long[] mAllowedTimePerPeriodMs = new long[]{
-            QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
+            QcConstants.DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
             QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
             QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_FREQUENT_MS,
             QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_RARE_MS,
             0, // NEVER
             QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS,
-            QcConstants.DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS
+            QcConstants.DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS
     };
 
     /**
@@ -536,6 +546,8 @@
      */
     private final SparseSetArray<String> mSystemInstallers = new SparseSetArray<>();
 
+    private final PlatformCompat mPlatformCompat;
+
     /** An app has reached its quota. The message should contain a {@link UserPackage} object. */
     @VisibleForTesting
     static final int MSG_REACHED_TIME_QUOTA = 0;
@@ -587,6 +599,13 @@
         PowerAllowlistInternal pai = LocalServices.getService(PowerAllowlistInternal.class);
         pai.registerTempAllowlistChangeListener(new TempAllowlistTracker());
 
+        mPlatformCompat = (PlatformCompat)
+                ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE);
+        if (Flags.adjustQuotaDefaultConstants()) {
+            mPlatformCompat.registerListener(OVERRIDE_QUOTA_ADJUST_DEFAULT_CONSTANTS,
+                    (packageName) -> handleQuotaDefaultConstantsCompatChange());
+        }
+
         try {
             ActivityManager.getService().registerUidObserver(new QcUidObserver(),
                     ActivityManager.UID_OBSERVER_PROCSTATE,
@@ -651,8 +670,9 @@
 
         final int uid = jobStatus.getSourceUid();
         if ((!Flags.enforceQuotaPolicyToTopStartedJobs()
-                || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
-                        uid)) && mTopAppCache.get(uid)) {
+                || mPlatformCompat.isChangeEnabledByUid(
+                        OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS, uid))
+                && mTopAppCache.get(uid)) {
             if (DEBUG) {
                 Slog.d(TAG, jobStatus.toShortString() + " is top started job");
             }
@@ -690,8 +710,8 @@
             }
         }
         if (!Flags.enforceQuotaPolicyToTopStartedJobs()
-                || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
-                        jobStatus.getSourceUid())) {
+                || mPlatformCompat.isChangeEnabledByUid(
+                        OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS, jobStatus.getSourceUid())) {
             mTopStartedJobs.remove(jobStatus);
         }
     }
@@ -805,8 +825,8 @@
     /** @return true if the job was started while the app was in the TOP state. */
     private boolean isTopStartedJobLocked(@NonNull final JobStatus jobStatus) {
         if (!Flags.enforceQuotaPolicyToTopStartedJobs()
-                || CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
-                        jobStatus.getSourceUid())) {
+                || mPlatformCompat.isChangeEnabledByUid(
+                        OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS, jobStatus.getSourceUid())) {
             return mTopStartedJobs.contains(jobStatus);
         }
 
@@ -1102,6 +1122,7 @@
             final int standbyBucket) {
         final long baseLimitMs = mAllowedTimePerPeriodMs[standbyBucket];
         if (Flags.adjustQuotaDefaultConstants()
+                && !isCompatOverridedForQuotaConstantAdjustment()
                 && Flags.additionalQuotaForSystemInstaller()
                 && standbyBucket == EXEMPTED_INDEX
                 && mSystemInstallers.contains(userId, pkgName)) {
@@ -1473,10 +1494,21 @@
         }
     }
 
+    void handleQuotaDefaultConstantsCompatChange() {
+        synchronized (mLock) {
+            final boolean isCompatEnabled = isCompatOverridedForQuotaConstantAdjustment();
+            mQcConstants.adjustDefaultBucketWindowSizes(isCompatEnabled);
+            mQcConstants.adjustDefaultEjLimits(isCompatEnabled);
+            mQcConstants.mShouldReevaluateConstraints = true;
+            onConstantsUpdatedLocked();
+        }
+    }
+
     void processQuotaConstantsAdjustment() {
-        if (Flags.adjustQuotaDefaultConstants()) {
-            mQcConstants.adjustDefaultBucketWindowSizes();
-            mQcConstants.adjustDefaultEjLimits();
+        if (Flags.adjustQuotaDefaultConstants()
+                && !isCompatOverridedForQuotaConstantAdjustment()) {
+            mQcConstants.adjustDefaultBucketWindowSizes(false);
+            mQcConstants.adjustDefaultEjLimits(false);
         }
     }
 
@@ -1505,6 +1537,11 @@
         }
     }
 
+    private boolean isCompatOverridedForQuotaConstantAdjustment() {
+        return mPlatformCompat.isChangeEnabledByPackageName(
+                OVERRIDE_QUOTA_ADJUST_DEFAULT_CONSTANTS, "android", UserHandle.USER_SYSTEM);
+    }
+
     private void incrementTimingSessionCountLocked(final int userId,
             @NonNull final String packageName) {
         final long now = sElapsedRealtimeClock.millis();
@@ -2689,7 +2726,8 @@
     @VisibleForTesting
     int getProcessStateQuotaFreeThreshold(int uid) {
         if (Flags.enforceQuotaPolicyToFgsJobs()
-                && !CompatChanges.isChangeEnabled(OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS, uid)) {
+                && !mPlatformCompat.isChangeEnabledByUid(
+                        OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS, uid)) {
             return ActivityManager.PROCESS_STATE_BOUND_TOP;
         }
 
@@ -3178,9 +3216,11 @@
         static final String KEY_EJ_GRACE_PERIOD_TOP_APP_MS =
                 QC_CONSTANT_PREFIX + "ej_grace_period_top_app_ms";
 
-        private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
+        // Legacy default time each app will have to run jobs within EXEMPTED bucket
+        private static final long DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
                 10 * 60 * 1000L; // 10 minutes
-        private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
+        // Legacy default time each app will have to run jobs within ACTIVE bucket
+        private static final long DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
                 10 * 60 * 1000L; // 10 minutes
         private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_WORKING_MS =
                 10 * 60 * 1000L; // 10 minutes
@@ -3192,14 +3232,26 @@
                 10 * 60 * 1000L; // 10 minutes
         private static final long DEFAULT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS =
                 10 * 60 * 1000L; // 10 minutes
+
+        // Current default time each app will have to run jobs within EXEMPTED bucket
+        private static final long DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
+                20 * 60 * 1000L; // 20 minutes
+        // Current default time each app will have to run jobs within ACTIVE bucket
+        private static final long DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
+                20 * 60 * 1000L; // 20 minutes
+        private static final long DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS =
+                20 * 60 * 1000L; // 20 minutes
+
         private static final long DEFAULT_IN_QUOTA_BUFFER_MS =
                 30 * 1000L; // 30 seconds
         // Legacy default window size for EXEMPTED bucket
+        // EXEMPT apps can run jobs at any time
         private static final long DEFAULT_LEGACY_WINDOW_SIZE_EXEMPTED_MS =
-                DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS; // EXEMPT apps can run jobs at any time
+                DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
         // Legacy default window size for ACTIVE bucket
+        // ACTIVE apps can run jobs at any time
         private static final long DEFAULT_LEGACY_WINDOW_SIZE_ACTIVE_MS =
-                DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS; // ACTIVE apps can run jobs at any time
+                DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
         // Legacy default window size for WORKING bucket
         private static final long DEFAULT_LEGACY_WINDOW_SIZE_WORKING_MS =
                 2 * 60 * 60 * 1000L; // 2 hours
@@ -3216,6 +3268,13 @@
         private static final long DEFAULT_CURRENT_WINDOW_SIZE_FREQUENT_MS =
                 12 * 60 * 60 * 1000L; // 12 hours
 
+        // Latest default window size for EXEMPTED bucket.
+        private static final long DEFAULT_LATEST_WINDOW_SIZE_EXEMPTED_MS =
+                40 * 60 * 1000L; // 40 minutes.
+        // Latest default window size for ACTIVE bucket.
+        private static final long DEFAULT_LATEST_WINDOW_SIZE_ACTIVE_MS =
+                60 * 60 * 1000L; // 60 minutes.
+
         private static final long DEFAULT_WINDOW_SIZE_RARE_MS =
                 24 * 60 * 60 * 1000L; // 24 hours
         private static final long DEFAULT_WINDOW_SIZE_RESTRICTED_MS =
@@ -3276,12 +3335,13 @@
          * bucket window.
          */
         public long ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
-                DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
+                DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
         /**
          * How much time each app in the active bucket will have to run jobs within their standby
          * bucket window.
          */
-        public long ALLOWED_TIME_PER_PERIOD_ACTIVE_MS = DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
+        public long ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
+                DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
         /**
          * How much time each app in the working set bucket will have to run jobs within their
          * standby bucket window.
@@ -3574,11 +3634,45 @@
          */
         public long EJ_GRACE_PERIOD_TOP_APP_MS = DEFAULT_EJ_GRACE_PERIOD_TOP_APP_MS;
 
-        void adjustDefaultBucketWindowSizes() {
-            WINDOW_SIZE_EXEMPTED_MS = DEFAULT_CURRENT_WINDOW_SIZE_EXEMPTED_MS;
-            WINDOW_SIZE_ACTIVE_MS = DEFAULT_CURRENT_WINDOW_SIZE_ACTIVE_MS;
-            WINDOW_SIZE_WORKING_MS = DEFAULT_CURRENT_WINDOW_SIZE_WORKING_MS;
-            WINDOW_SIZE_FREQUENT_MS = DEFAULT_CURRENT_WINDOW_SIZE_FREQUENT_MS;
+        void adjustDefaultBucketWindowSizes(boolean useLegacyQuotaConstants) {
+            if (useLegacyQuotaConstants) {
+                ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
+                        DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
+                ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
+                        DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
+                ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS =
+                        DEFAULT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS;
+
+                WINDOW_SIZE_EXEMPTED_MS = DEFAULT_LEGACY_WINDOW_SIZE_EXEMPTED_MS;
+                WINDOW_SIZE_ACTIVE_MS = DEFAULT_LEGACY_WINDOW_SIZE_ACTIVE_MS;
+                WINDOW_SIZE_WORKING_MS = DEFAULT_LEGACY_WINDOW_SIZE_WORKING_MS;
+                WINDOW_SIZE_FREQUENT_MS = DEFAULT_LEGACY_WINDOW_SIZE_FREQUENT_MS;
+            } else {
+                ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS = Flags.tuneQuotaWindowDefaultParameters()
+                        ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS :
+                        DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
+                ALLOWED_TIME_PER_PERIOD_ACTIVE_MS = Flags.tuneQuotaWindowDefaultParameters()
+                        ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS :
+                        DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
+                ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS =
+                        Flags.tuneQuotaWindowDefaultParameters()
+                                ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS :
+                                DEFAULT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS;
+
+                WINDOW_SIZE_EXEMPTED_MS = Flags.tuneQuotaWindowDefaultParameters()
+                        ? DEFAULT_LATEST_WINDOW_SIZE_EXEMPTED_MS :
+                        DEFAULT_CURRENT_WINDOW_SIZE_EXEMPTED_MS;
+                WINDOW_SIZE_ACTIVE_MS = Flags.tuneQuotaWindowDefaultParameters()
+                        ? DEFAULT_LATEST_WINDOW_SIZE_ACTIVE_MS :
+                        DEFAULT_CURRENT_WINDOW_SIZE_ACTIVE_MS;
+                WINDOW_SIZE_WORKING_MS = DEFAULT_CURRENT_WINDOW_SIZE_WORKING_MS;
+                WINDOW_SIZE_FREQUENT_MS = DEFAULT_CURRENT_WINDOW_SIZE_FREQUENT_MS;
+            }
+
+            mAllowedTimePerPeriodMs[EXEMPTED_INDEX] = Math.min(MAX_PERIOD_MS,
+                    Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS));
+            mAllowedTimePerPeriodMs[ACTIVE_INDEX] = Math.min(MAX_PERIOD_MS,
+                    Math.max(MINUTE_IN_MILLIS, ALLOWED_TIME_PER_PERIOD_ACTIVE_MS));
 
             mBucketPeriodsMs[EXEMPTED_INDEX] = Math.max(
                     mAllowedTimePerPeriodMs[EXEMPTED_INDEX],
@@ -3592,12 +3686,22 @@
             mBucketPeriodsMs[FREQUENT_INDEX] = Math.max(
                     mAllowedTimePerPeriodMs[FREQUENT_INDEX],
                     Math.min(MAX_PERIOD_MS, WINDOW_SIZE_FREQUENT_MS));
+
+            mAllowedTimePeriodAdditionaInstallerMs =
+                    Math.min(mBucketPeriodsMs[EXEMPTED_INDEX]
+                                    - mAllowedTimePerPeriodMs[EXEMPTED_INDEX],
+                            ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS);
         }
 
-        void adjustDefaultEjLimits() {
-            EJ_LIMIT_WORKING_MS = DEFAULT_CURRENT_EJ_LIMIT_WORKING_MS;
-            EJ_TOP_APP_TIME_CHUNK_SIZE_MS = DEFAULT_CURRENT_EJ_TOP_APP_TIME_CHUNK_SIZE_MS;
-            EJ_REWARD_INTERACTION_MS = DEFAULT_CURRENT_EJ_REWARD_INTERACTION_MS;
+        void adjustDefaultEjLimits(boolean useLegacyQuotaConstants) {
+            EJ_LIMIT_WORKING_MS = useLegacyQuotaConstants ? DEFAULT_LEGACY_EJ_LIMIT_WORKING_MS
+                    : DEFAULT_CURRENT_EJ_LIMIT_WORKING_MS;
+            EJ_TOP_APP_TIME_CHUNK_SIZE_MS = useLegacyQuotaConstants
+                    ? DEFAULT_LEGACY_EJ_TOP_APP_TIME_CHUNK_SIZE_MS :
+                    DEFAULT_CURRENT_EJ_TOP_APP_TIME_CHUNK_SIZE_MS;
+            EJ_REWARD_INTERACTION_MS = useLegacyQuotaConstants
+                    ? DEFAULT_LEGACY_EJ_REWARD_INTERACTION_MS
+                    : DEFAULT_CURRENT_EJ_REWARD_INTERACTION_MS;
 
             // The limit must be in the range [15 minutes, active limit].
             mEJLimitsMs[WORKING_INDEX] = Math.max(15 * MINUTE_IN_MILLIS,
@@ -3622,6 +3726,8 @@
 
         public void processConstantLocked(@NonNull DeviceConfig.Properties properties,
                 @NonNull String key) {
+            final boolean isCompatEnabled = isCompatOverridedForQuotaConstantAdjustment();
+
             switch (key) {
                 case KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS:
                 case KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS:
@@ -3789,7 +3895,8 @@
                 case KEY_EJ_TOP_APP_TIME_CHUNK_SIZE_MS:
                     // We don't need to re-evaluate execution stats or constraint status for this.
                     EJ_TOP_APP_TIME_CHUNK_SIZE_MS =
-                            properties.getLong(key, Flags.adjustQuotaDefaultConstants()
+                            properties.getLong(key,
+                                    Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
                                     ? DEFAULT_CURRENT_EJ_TOP_APP_TIME_CHUNK_SIZE_MS :
                                     DEFAULT_LEGACY_EJ_TOP_APP_TIME_CHUNK_SIZE_MS);
                     // Limit chunking to be in the range [1 millisecond, 15 minutes] per event.
@@ -3827,7 +3934,8 @@
                 case KEY_EJ_REWARD_INTERACTION_MS:
                     // We don't need to re-evaluate execution stats or constraint status for this.
                     EJ_REWARD_INTERACTION_MS =
-                            properties.getLong(key, Flags.adjustQuotaDefaultConstants()
+                            properties.getLong(key,
+                                    Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
                                     ? DEFAULT_CURRENT_EJ_REWARD_INTERACTION_MS :
                                     DEFAULT_LEGACY_EJ_REWARD_INTERACTION_MS);
                     // Limit interaction reward to be in the range [5 seconds, 15 minutes] per
@@ -3868,6 +3976,8 @@
             }
             mExecutionPeriodConstantsUpdated = true;
 
+            final boolean isCompatEnabled = isCompatOverridedForQuotaConstantAdjustment();
+
             // Query the values as an atomic set.
             final DeviceConfig.Properties properties = DeviceConfig.getProperties(
                     DeviceConfig.NAMESPACE_JOB_SCHEDULER,
@@ -3882,10 +3992,14 @@
                     KEY_WINDOW_SIZE_RESTRICTED_MS);
             ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS =
                     properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS,
-                            DEFAULT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS);
+                            Flags.tuneQuotaWindowDefaultParameters()
+                                    ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS :
+                                    DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS);
             ALLOWED_TIME_PER_PERIOD_ACTIVE_MS =
                     properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS,
-                            DEFAULT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS);
+                            Flags.tuneQuotaWindowDefaultParameters()
+                                    ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS :
+                                    DEFAULT_LEGACY_ALLOWED_TIME_PER_PERIOD_ACTIVE_MS);
             ALLOWED_TIME_PER_PERIOD_WORKING_MS =
                     properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_WORKING_MS,
                             DEFAULT_ALLOWED_TIME_PER_PERIOD_WORKING_MS);
@@ -3900,27 +4014,35 @@
                             DEFAULT_ALLOWED_TIME_PER_PERIOD_RESTRICTED_MS);
             ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS =
                     properties.getLong(KEY_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS,
-                            DEFAULT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS);
+                            Flags.tuneQuotaWindowDefaultParameters()
+                                    ? DEFAULT_CURRENT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS
+                                    : DEFAULT_ALLOWED_TIME_PER_PERIOD_ADDITION_INSTALLER_MS);
             IN_QUOTA_BUFFER_MS = properties.getLong(KEY_IN_QUOTA_BUFFER_MS,
                     DEFAULT_IN_QUOTA_BUFFER_MS);
             MAX_EXECUTION_TIME_MS = properties.getLong(KEY_MAX_EXECUTION_TIME_MS,
                     DEFAULT_MAX_EXECUTION_TIME_MS);
             WINDOW_SIZE_EXEMPTED_MS = properties.getLong(KEY_WINDOW_SIZE_EXEMPTED_MS,
-                    Flags.adjustQuotaDefaultConstants()
-                            ? DEFAULT_CURRENT_WINDOW_SIZE_EXEMPTED_MS :
-                            DEFAULT_LEGACY_WINDOW_SIZE_EXEMPTED_MS);
+                    (Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
+                            && Flags.tuneQuotaWindowDefaultParameters())
+                            ? DEFAULT_LATEST_WINDOW_SIZE_EXEMPTED_MS :
+                            (Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
+                                    ? DEFAULT_CURRENT_WINDOW_SIZE_EXEMPTED_MS :
+                                    DEFAULT_LEGACY_WINDOW_SIZE_EXEMPTED_MS));
             WINDOW_SIZE_ACTIVE_MS = properties.getLong(KEY_WINDOW_SIZE_ACTIVE_MS,
-                    Flags.adjustQuotaDefaultConstants()
-                            ? DEFAULT_CURRENT_WINDOW_SIZE_ACTIVE_MS :
-                            DEFAULT_LEGACY_WINDOW_SIZE_ACTIVE_MS);
+                    (Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
+                            && Flags.tuneQuotaWindowDefaultParameters())
+                            ? DEFAULT_LATEST_WINDOW_SIZE_ACTIVE_MS :
+                            (Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
+                                    ? DEFAULT_CURRENT_WINDOW_SIZE_ACTIVE_MS :
+                                    DEFAULT_LEGACY_WINDOW_SIZE_ACTIVE_MS));
             WINDOW_SIZE_WORKING_MS =
                     properties.getLong(KEY_WINDOW_SIZE_WORKING_MS,
-                            Flags.adjustQuotaDefaultConstants()
+                            Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
                                     ? DEFAULT_CURRENT_WINDOW_SIZE_WORKING_MS :
                                     DEFAULT_LEGACY_WINDOW_SIZE_WORKING_MS);
             WINDOW_SIZE_FREQUENT_MS =
                     properties.getLong(KEY_WINDOW_SIZE_FREQUENT_MS,
-                            Flags.adjustQuotaDefaultConstants()
+                            Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
                                     ? DEFAULT_CURRENT_WINDOW_SIZE_FREQUENT_MS :
                                     DEFAULT_LEGACY_WINDOW_SIZE_FREQUENT_MS);
             WINDOW_SIZE_RARE_MS = properties.getLong(KEY_WINDOW_SIZE_RARE_MS,
@@ -4091,6 +4213,8 @@
             }
             mEJLimitConstantsUpdated = true;
 
+            final boolean isCompatEnabled = isCompatOverridedForQuotaConstantAdjustment();
+
             // Query the values as an atomic set.
             final DeviceConfig.Properties properties = DeviceConfig.getProperties(
                     DeviceConfig.NAMESPACE_JOB_SCHEDULER,
@@ -4105,7 +4229,7 @@
             EJ_LIMIT_ACTIVE_MS = properties.getLong(
                     KEY_EJ_LIMIT_ACTIVE_MS, DEFAULT_EJ_LIMIT_ACTIVE_MS);
             EJ_LIMIT_WORKING_MS = properties.getLong(
-                    KEY_EJ_LIMIT_WORKING_MS, Flags.adjustQuotaDefaultConstants()
+                    KEY_EJ_LIMIT_WORKING_MS, Flags.adjustQuotaDefaultConstants() && !isCompatEnabled
                             ? DEFAULT_CURRENT_EJ_LIMIT_WORKING_MS :
                             DEFAULT_LEGACY_EJ_LIMIT_WORKING_MS);
             EJ_LIMIT_FREQUENT_MS = properties.getLong(
diff --git a/cmds/app_process/Android.bp b/cmds/app_process/Android.bp
index a157517..3c7609e 100644
--- a/cmds/app_process/Android.bp
+++ b/cmds/app_process/Android.bp
@@ -56,6 +56,7 @@
         "libsigchain",
 
         "libutils",
+        "libutilscallstack",
 
         // This is a list of libraries that need to be included in order to avoid
         // bad apps. This prevents a library from having a mismatch when resolving
diff --git a/core/api/current.txt b/core/api/current.txt
index 1630d80..bba21f4 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -24820,7 +24820,7 @@
     method public android.view.Surface getSurface();
     method public boolean isPrivacySensitive();
     method public void pause() throws java.lang.IllegalStateException;
-    method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
+    method @RequiresPermission(value=android.Manifest.permission.RECORD_AUDIO, conditional=true) public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
     method public void registerAudioRecordingCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioRecordingCallback);
     method public void release();
     method public void removeOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener);
@@ -24861,7 +24861,7 @@
     method public void setVideoProfile(@NonNull android.media.EncoderProfiles.VideoProfile);
     method public void setVideoSize(int, int) throws java.lang.IllegalStateException;
     method public void setVideoSource(int) throws java.lang.IllegalStateException;
-    method public void start() throws java.lang.IllegalStateException;
+    method @RequiresPermission(value=android.Manifest.permission.RECORD_AUDIO, conditional=true) public void start() throws java.lang.IllegalStateException;
     method public void stop() throws java.lang.IllegalStateException;
     method public void unregisterAudioRecordingCallback(@NonNull android.media.AudioManager.AudioRecordingCallback);
     field public static final int MEDIA_ERROR_SERVER_DIED = 100; // 0x64
@@ -34264,6 +34264,7 @@
     method public boolean hasFileDescriptors();
     method public boolean hasFileDescriptors(int, int);
     method public byte[] marshall();
+    method @FlaggedApi("android.os.parcel_marshall_bytebuffer") public void marshall(@NonNull java.nio.ByteBuffer);
     method @NonNull public static android.os.Parcel obtain();
     method @NonNull public static android.os.Parcel obtain(@NonNull android.os.IBinder);
     method @Deprecated @Nullable public Object[] readArray(@Nullable ClassLoader);
@@ -34333,6 +34334,7 @@
     method public void setDataSize(int);
     method public void setPropagateAllowBlocking();
     method public void unmarshall(@NonNull byte[], int, int);
+    method @FlaggedApi("android.os.parcel_marshall_bytebuffer") public void unmarshall(@NonNull java.nio.ByteBuffer);
     method public void writeArray(@Nullable Object[]);
     method public void writeBinderArray(@Nullable android.os.IBinder[]);
     method public void writeBinderList(@Nullable java.util.List<android.os.IBinder>);
@@ -46681,16 +46683,16 @@
     method public int getLastCauseCode();
     method @Nullable public android.net.LinkProperties getLinkProperties();
     method public int getNetworkType();
-    method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public int getNetworkValidationStatus();
+    method public int getNetworkValidationStatus();
     method public int getState();
     method public int getTransportType();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.telephony.PreciseDataConnectionState> CREATOR;
-    field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_FAILURE = 4; // 0x4
-    field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; // 0x2
-    field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; // 0x1
-    field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_SUCCESS = 3; // 0x3
-    field @FlaggedApi("com.android.internal.telephony.flags.network_validation") public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; // 0x0
+    field public static final int NETWORK_VALIDATION_FAILURE = 4; // 0x4
+    field public static final int NETWORK_VALIDATION_IN_PROGRESS = 2; // 0x2
+    field public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1; // 0x1
+    field public static final int NETWORK_VALIDATION_SUCCESS = 3; // 0x3
+    field public static final int NETWORK_VALIDATION_UNSUPPORTED = 0; // 0x0
   }
 
   public final class RadioAccessSpecifier implements android.os.Parcelable {
@@ -55423,6 +55425,7 @@
     method public void dispatchOnDraw();
     method public void dispatchOnGlobalLayout();
     method public boolean dispatchOnPreDraw();
+    method @FlaggedApi("android.view.flags.enable_dispatch_on_scroll_changed") public void dispatchOnScrollChanged();
     method public boolean isAlive();
     method public void registerFrameCommitCallback(@NonNull Runnable);
     method @Deprecated public void removeGlobalOnLayoutListener(android.view.ViewTreeObserver.OnGlobalLayoutListener);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 32b170a..2ce3609 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2941,6 +2941,7 @@
 package android.app.supervision {
 
   @FlaggedApi("android.app.supervision.flags.supervision_manager_apis") public class SupervisionManager {
+    method @FlaggedApi("android.app.supervision.flags.supervision_manager_apis") @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS}) public android.content.Intent createConfirmSupervisionCredentialsIntent();
     method @FlaggedApi("android.app.supervision.flags.supervision_manager_apis") @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_USERS}) public boolean isSupervisionEnabled();
   }
 
@@ -3642,11 +3643,26 @@
     method public int getDeviceId();
     method @NonNull public String getName();
     method public int getType();
+    method @FlaggedApi("android.companion.virtualdevice.flags.virtual_sensor_additional_info") public void sendAdditionalInfo(@NonNull android.companion.virtual.sensor.VirtualSensorAdditionalInfo);
     method public void sendEvent(@NonNull android.companion.virtual.sensor.VirtualSensorEvent);
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.sensor.VirtualSensor> CREATOR;
   }
 
+  @FlaggedApi("android.companion.virtualdevice.flags.virtual_sensor_additional_info") public final class VirtualSensorAdditionalInfo implements android.os.Parcelable {
+    method public int describeContents();
+    method public int getType();
+    method @NonNull public java.util.List<float[]> getValues();
+    method public void writeToParcel(@NonNull android.os.Parcel, int);
+    field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.sensor.VirtualSensorAdditionalInfo> CREATOR;
+  }
+
+  public static final class VirtualSensorAdditionalInfo.Builder {
+    ctor public VirtualSensorAdditionalInfo.Builder(int);
+    method @NonNull public android.companion.virtual.sensor.VirtualSensorAdditionalInfo.Builder addValues(@NonNull float[]);
+    method @NonNull public android.companion.virtual.sensor.VirtualSensorAdditionalInfo build();
+  }
+
   public interface VirtualSensorCallback {
     method public void onConfigurationChanged(@NonNull android.companion.virtual.sensor.VirtualSensor, boolean, @NonNull java.time.Duration, @NonNull java.time.Duration);
   }
@@ -3664,6 +3680,7 @@
     method public float getResolution();
     method public int getType();
     method @Nullable public String getVendor();
+    method @FlaggedApi("android.companion.virtualdevice.flags.virtual_sensor_additional_info") public boolean isAdditionalInfoSupported();
     method @FlaggedApi("android.companion.virtualdevice.flags.device_aware_display_power") public boolean isWakeUpSensor();
     method public void writeToParcel(@NonNull android.os.Parcel, int);
     field @NonNull public static final android.os.Parcelable.Creator<android.companion.virtual.sensor.VirtualSensorConfig> CREATOR;
@@ -3672,6 +3689,7 @@
   public static final class VirtualSensorConfig.Builder {
     ctor public VirtualSensorConfig.Builder(@IntRange(from=1) int, @NonNull String);
     method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig build();
+    method @FlaggedApi("android.companion.virtualdevice.flags.virtual_sensor_additional_info") @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setAdditionalInfoSupported(boolean);
     method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setDirectChannelTypesSupported(int);
     method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setHighestDirectReportRateLevel(int);
     method @NonNull public android.companion.virtual.sensor.VirtualSensorConfig.Builder setMaxDelay(int);
@@ -7336,7 +7354,15 @@
 
   public class AudioDeviceVolumeManager {
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public android.media.VolumeInfo getDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes);
+    method @FlaggedApi("android.media.audio.unify_absolute_volume_management") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
     method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public void setDeviceVolume(@NonNull android.media.VolumeInfo, @NonNull android.media.AudioDeviceAttributes);
+    method @FlaggedApi("android.media.audio.unify_absolute_volume_management") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
+    field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
+    field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5; // 0x5
+    field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
+    field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
+    field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
+    field @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
   }
 
   public final class AudioFocusInfo implements android.os.Parcelable {
@@ -7381,7 +7407,7 @@
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static java.util.List<android.media.audiopolicy.AudioVolumeGroup> getAudioVolumeGroups();
     method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioRecord getCallDownlinkExtractionAudioRecord(@NonNull android.media.AudioFormat);
     method @NonNull @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public android.media.AudioTrack getCallUplinkInjectionAudioTrack(@NonNull android.media.AudioFormat);
-    method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
+    method @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE", android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public int getDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes);
     method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, "android.permission.QUERY_AUDIO_STATE"}) public java.util.List<android.media.AudioDeviceAttributes> getDevicesForAttributes(@NonNull android.media.AudioAttributes);
     method @NonNull @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public java.util.List<java.lang.Integer> getIndependentStreamTypes();
     method @RequiresPermission("android.permission.QUERY_AUDIO_STATE") public int getLastAudibleStreamVolume(int);
@@ -7427,7 +7453,7 @@
     method public void setAudioServerStateCallback(@NonNull java.util.concurrent.Executor, @NonNull android.media.AudioManager.AudioServerStateCallback);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setBluetoothVariableLatencyEnabled(boolean);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setDeviceAsNonDefaultForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
-    method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
+    method @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public void setDeviceVolumeBehavior(@NonNull android.media.AudioDeviceAttributes, int);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public void setFocusRequestResult(@NonNull android.media.AudioFocusInfo, int, @NonNull android.media.audiopolicy.AudioPolicy);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForCapturePreset(int, @NonNull android.media.AudioDeviceAttributes);
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public boolean setPreferredDeviceForStrategy(@NonNull android.media.audiopolicy.AudioProductStrategy, @NonNull android.media.AudioDeviceAttributes);
@@ -7447,12 +7473,12 @@
     field public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 2; // 0x2
     field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int DEVICE_CONNECTION_STATE_CONNECTED = 1; // 0x1
     field @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING) public static final int DEVICE_CONNECTION_STATE_DISCONNECTED = 0; // 0x0
-    field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
-    field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5; // 0x5
-    field public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
-    field public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
-    field public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
-    field public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
+    field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3; // 0x3
+    field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5; // 0x5
+    field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4; // 0x4
+    field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2; // 0x2
+    field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1; // 0x1
+    field @Deprecated @FlaggedApi("android.media.audio.unify_absolute_volume_management") public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0; // 0x0
     field public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
     field public static final String EXTRA_VOLUME_STREAM_VALUE = "android.media.EXTRA_VOLUME_STREAM_VALUE";
     field public static final int FLAG_BLUETOOTH_ABS_VOLUME = 64; // 0x40
@@ -16442,7 +16468,7 @@
     method @Deprecated public int getMtu();
     method public int getMtuV4();
     method public int getMtuV6();
-    method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public int getNetworkValidationStatus();
+    method public int getNetworkValidationStatus();
     method @NonNull public java.util.List<java.net.InetAddress> getPcscfAddresses();
     method public int getPduSessionId();
     method public int getProtocolType();
@@ -16479,7 +16505,7 @@
     method @Deprecated @NonNull public android.telephony.data.DataCallResponse.Builder setMtu(int);
     method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV4(int);
     method @NonNull public android.telephony.data.DataCallResponse.Builder setMtuV6(int);
-    method @FlaggedApi("com.android.internal.telephony.flags.network_validation") @NonNull public android.telephony.data.DataCallResponse.Builder setNetworkValidationStatus(int);
+    method @NonNull public android.telephony.data.DataCallResponse.Builder setNetworkValidationStatus(int);
     method @NonNull public android.telephony.data.DataCallResponse.Builder setPcscfAddresses(@NonNull java.util.List<java.net.InetAddress>);
     method @NonNull public android.telephony.data.DataCallResponse.Builder setPduSessionId(@IntRange(from=android.telephony.data.DataCallResponse.PDU_SESSION_ID_NOT_SET, to=15) int);
     method @NonNull public android.telephony.data.DataCallResponse.Builder setProtocolType(int);
@@ -16559,7 +16585,7 @@
     method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
     method public final void notifyDataProfileUnthrottled(@NonNull android.telephony.data.DataProfile);
     method public void requestDataCallList(@NonNull android.telephony.data.DataServiceCallback);
-    method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @NonNull android.telephony.data.DataServiceCallback);
     method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @NonNull android.telephony.data.DataServiceCallback);
     method public void setupDataCall(int, @NonNull android.telephony.data.DataProfile, boolean, boolean, int, @Nullable android.net.LinkProperties, @NonNull android.telephony.data.DataServiceCallback);
@@ -16621,7 +16647,7 @@
     method public final int getSlotIndex();
     method public void reportEmergencyDataNetworkPreferredTransportChanged(int);
     method public void reportThrottleStatusChanged(@NonNull java.util.List<android.telephony.data.ThrottleStatus>);
-    method @FlaggedApi("com.android.internal.telephony.flags.network_validation") public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
+    method public void requestNetworkValidation(int, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Integer>);
     method public final void updateQualifiedNetworkTypes(int, @NonNull java.util.List<java.lang.Integer>);
   }
 
@@ -19245,7 +19271,6 @@
     method @Deprecated public abstract void setUseWebViewBackgroundForOverscrollBackground(boolean);
     method @Deprecated public abstract void setUserAgent(int);
     method public abstract void setVideoOverlayForEmbeddedEncryptedVideoEnabled(boolean);
-    field @FlaggedApi("android.webkit.enable_chips") public static final long ENABLE_CHIPS = 380890146L; // 0x16b3ec22L
     field public static final long ENABLE_SIMPLIFIED_DARK_MODE = 214741472L; // 0xcccb1e0L
     field @FlaggedApi("android.webkit.user_agent_reduction") public static final long ENABLE_USER_AGENT_REDUCTION = 371034303L; // 0x161d88bfL
   }
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 4c82839..daa1902 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1955,6 +1955,10 @@
     method public static void enforceValidAudioDeviceTypeOut(int);
   }
 
+  public class AudioDeviceVolumeManager {
+    method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public boolean isFullVolumeDevice();
+  }
+
   public final class AudioFocusRequest {
     method @Nullable public android.media.AudioManager.OnAudioFocusChangeListener getOnAudioFocusChangeListener();
   }
@@ -2010,7 +2014,6 @@
     method @NonNull public android.media.VolumePolicy getVolumePolicy();
     method public boolean hasRegisteredDynamicPolicy();
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public boolean isCsdEnabled();
-    method @RequiresPermission(anyOf={android.Manifest.permission.MODIFY_AUDIO_ROUTING, android.Manifest.permission.QUERY_AUDIO_STATE, android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED}) public boolean isFullVolumeDevice();
     method @RequiresPermission(android.Manifest.permission.CALL_AUDIO_INTERCEPTION) public boolean isPstnCallAudioInterceptable();
     method @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED) public boolean isVolumeControlUsingVolumeGroups();
     method public void permissionUpdateBarrier();
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 4a07de0..36308e5 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -423,17 +423,21 @@
             notifyListeners(AnimatorCaller.ON_CANCEL, false);
             callOnPlayingSet(Animator::cancel);
             mPlayingSet.clear();
-            // If the end callback is pending, invoke the end callbacks of the animator nodes before
-            // ending this set. Pass notifyListeners=false because this endAnimation will do that.
-            if (consumePendingEndListeners(false /* notifyListeners */)) {
-                for (int i = mNodeMap.size() - 1; i >= 0; i--) {
-                    mNodeMap.keyAt(i).consumePendingEndListeners(true /* notifyListeners */);
-                }
-            }
-            endAnimation();
+            endAnimationAndNotifyEndListenersImmediately();
         }
     }
 
+    private void endAnimationAndNotifyEndListenersImmediately() {
+        // If the end callback is pending, invoke the end callbacks of the animator nodes before
+        // ending this set. Pass notifyListeners=false because endAnimation will do that.
+        if (consumePendingEndListeners(false /* notifyListeners */)) {
+            for (int i = mNodeMap.size() - 1; i >= 0; i--) {
+                mNodeMap.keyAt(i).consumePendingEndListeners(true /* notifyListeners */);
+            }
+        }
+        endAnimation();
+    }
+
     /**
      * Calls consumer on every Animator of mPlayingSet.
      *
@@ -529,7 +533,7 @@
                 }
             }
         }
-        endAnimation();
+        endAnimationAndNotifyEndListenersImmediately();
     }
 
     /**
@@ -1455,8 +1459,6 @@
     private void endAnimation(boolean fromLastFrame) {
         final boolean postNotifyEndListener = sPostNotifyEndListenerEnabled && mListeners != null
                 && fromLastFrame && mTotalDuration > 0;
-        mStarted = false;
-        mLastFrameTime = -1;
         mFirstFrame = -1;
         mLastEventId = -1;
         mPaused = false;
@@ -1466,11 +1468,18 @@
 
         // No longer receive callbacks
         removeAnimationCallback();
+        // If postNotifyEndListener is false (most cases), then it is the same as calling
+        // completeEndAnimation directly.
         notifyEndListenersFromEndAnimation(mReversing, postNotifyEndListener);
     }
 
     @Override
     void completeEndAnimation(boolean isReversing, String notifyListenerTraceName) {
+        // The mStarted and mLastFrameTime are reset here because isStarted() and isRunning()
+        // can be true before notifying the end listeners. When notifying the end listeners,
+        // isStarted() and isRunning() should be false.
+        mStarted = false;
+        mLastFrameTime = -1;
         super.completeEndAnimation(isReversing, notifyListenerTraceName);
         removeAnimationEndListener();
         mSelfPulse = true;
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index fbcc73e..8d34090 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -1212,6 +1212,10 @@
             initAnimation();
         }
         animateValue(shouldPlayBackward(mRepeatCount, mReversing) ? 0f : 1f);
+        if (mAnimationEndRequested) {
+            consumePendingEndListeners(true /* notifyListeners */);
+            return;
+        }
         endAnimation();
     }
 
@@ -1308,8 +1312,8 @@
         mLastFrameTime = -1;
         mFirstFrameTime = -1;
         mStartTime = -1;
-        mRunning = false;
-        mStarted = false;
+        // If postNotifyEndListener is false (most cases), then it is the same as calling
+        // completeEndAnimation directly.
         notifyEndListenersFromEndAnimation(mReversing, postNotifyEndListener);
         if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
             Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW, getNameForTrace(),
@@ -1319,6 +1323,11 @@
 
     @Override
     void completeEndAnimation(boolean isReversing, String notifyListenerTraceName) {
+        // The mRunning and mStarted are reset here because isStarted() and isRunning()
+        // can be true before notifying the end listeners. When notifying the end listeners,
+        // isStarted() and isRunning() should be false.
+        mRunning = false;
+        mStarted = false;
         super.completeEndAnimation(isReversing, notifyListenerTraceName);
         // mReversing needs to be reset *after* notifying the listeners for the end callbacks.
         mReversing = false;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 62816a2..9cc7b8f 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -1188,7 +1188,7 @@
 
     /** @hide Should this process state be considered jank perceptible? */
     public static final boolean isProcStateJankPerceptible(int procState) {
-        if (Flags.jankPerceptibleNarrow()) {
+        if (Flags.jankPerceptibleNarrow() && !Flags.jankPerceptibleNarrowHoldback()) {
             return procState == PROCESS_STATE_PERSISTENT_UI
                 || procState == PROCESS_STATE_TOP
                 || procState == PROCESS_STATE_IMPORTANT_FOREGROUND
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 0a2b1ea..f44c230 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -4014,7 +4014,7 @@
             return VM_PROCESS_STATE_JANK_PERCEPTIBLE;
         }
 
-        if (Flags.jankPerceptibleNarrow()) {
+        if (Flags.jankPerceptibleNarrow() && !Flags.jankPerceptibleNarrowHoldback()) {
             // Unlike other persistent processes, system server is often on
             // the critical path for application startup. Mark it explicitly
             // as jank perceptible regardless of processState.
@@ -7831,9 +7831,10 @@
 
         // Register callback to report native memory metrics post GC cleanup
         // Note: we do not report memory metrics of isolated processes unless
-        // their native allocations become more significant
-        if (!Process.isIsolated() && Flags.reportPostgcMemoryMetrics() &&
-            com.android.libcore.readonly.Flags.postCleanupApis()) {
+        // their native allocations become more significant. Instrumentation is
+        // also excluded because the metrics from test cases are not meaningful.
+        if (!Process.isIsolated() && ii == null && Flags.reportPostgcMemoryMetrics()
+                && com.android.libcore.readonly.Flags.postCleanupApis()) {
             VMRuntime.addPostCleanupCallback(new Runnable() {
                 @Override public void run() {
                     MetricsLoggerWrapper.logPostGcMemorySnapshot();
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 1ed64f9..bdecbae 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -200,6 +200,8 @@
     @GuardedBy("mPackageMonitorCallbacks")
     private final ArraySet<IRemoteCallback> mPackageMonitorCallbacks = new ArraySet<>();
 
+    private final boolean mUseSystemFeaturesCache;
+
     UserManager getUserManager() {
         if (mUserManager == null) {
             mUserManager = UserManager.get(mContext);
@@ -300,13 +302,23 @@
 
     @Override
     public Intent getLaunchIntentForPackage(String packageName) {
+        return getLaunchIntentForPackage(packageName, false);
+    }
+
+    @Override
+    @Nullable
+    public Intent getLaunchIntentForPackage(@NonNull String packageName,
+            boolean includeDirectBootUnaware) {
+        ResolveInfoFlags queryFlags = ResolveInfoFlags.of(
+                includeDirectBootUnaware ? MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE : 0);
+
         // First see if the package has an INFO activity; the existence of
         // such an activity is implied to be the desired front-door for the
         // overall package (such as if it has multiple launcher entries).
         Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
         intentToResolve.addCategory(Intent.CATEGORY_INFO);
         intentToResolve.setPackage(packageName);
-        List<ResolveInfo> ris = queryIntentActivities(intentToResolve, 0);
+        List<ResolveInfo> ris = queryIntentActivities(intentToResolve, queryFlags);
 
         // Otherwise, try to find a main launcher activity.
         if (ris == null || ris.size() <= 0) {
@@ -314,7 +326,7 @@
             intentToResolve.removeCategory(Intent.CATEGORY_INFO);
             intentToResolve.addCategory(Intent.CATEGORY_LAUNCHER);
             intentToResolve.setPackage(packageName);
-            ris = queryIntentActivities(intentToResolve, 0);
+            ris = queryIntentActivities(intentToResolve, queryFlags);
         }
         if (ris == null || ris.size() <= 0) {
             return null;
@@ -824,8 +836,7 @@
         if (maybeHasSystemFeature != null) {
             return maybeHasSystemFeature;
         }
-        if (com.android.internal.os.Flags.applicationSharedMemoryEnabled()
-                && android.content.pm.Flags.cacheSdkSystemFeatures()) {
+        if (mUseSystemFeaturesCache) {
             maybeHasSystemFeature =
                     SystemFeaturesCache.getInstance().maybeHasFeature(name, version);
             if (maybeHasSystemFeature != null) {
@@ -2221,6 +2232,25 @@
     protected ApplicationPackageManager(ContextImpl context, IPackageManager pm) {
         mContext = context;
         mPM = pm;
+        mUseSystemFeaturesCache = isSystemFeaturesCacheEnabledAndAvailable();
+    }
+
+    private static boolean isSystemFeaturesCacheEnabledAndAvailable() {
+        if (!android.content.pm.Flags.cacheSdkSystemFeatures()) {
+            return false;
+        }
+        if (!com.android.internal.os.Flags.applicationSharedMemoryEnabled()) {
+            return false;
+        }
+        if (ActivityThread.isSystem() && !SystemFeaturesCache.hasInstance()) {
+            // There are a handful of utility "system" processes that are neither system_server nor
+            // bound as applications. For these processes, we don't have access to application
+            // shared memory or the dependent system features cache.
+            // TODO(b/400713460): Revisit this exception after deprecating these command-like
+            // system processes.
+            return false;
+        }
+        return true;
     }
 
     /**
diff --git a/core/java/android/app/ApplicationStartInfo.java b/core/java/android/app/ApplicationStartInfo.java
index 2e8031d..2559bd0 100644
--- a/core/java/android/app/ApplicationStartInfo.java
+++ b/core/java/android/app/ApplicationStartInfo.java
@@ -231,9 +231,9 @@
     public static final int START_COMPONENT_OTHER = 5;
 
     /**
-     * @see #getMonoticCreationTimeMs
+     * @see #getMonotonicCreationTimeMs
      */
-    private long mMonoticCreationTimeMs;
+    private long mMonotonicCreationTimeMs;
 
     /**
      * @see #getStartupState
@@ -545,8 +545,8 @@
      *
      * @hide
      */
-    public long getMonoticCreationTimeMs() {
-        return mMonoticCreationTimeMs;
+    public long getMonotonicCreationTimeMs() {
+        return mMonotonicCreationTimeMs;
     }
 
     /**
@@ -751,14 +751,14 @@
         dest.writeParcelable(mStartIntent, flags);
         dest.writeInt(mLaunchMode);
         dest.writeBoolean(mWasForceStopped);
-        dest.writeLong(mMonoticCreationTimeMs);
+        dest.writeLong(mMonotonicCreationTimeMs);
         dest.writeInt(mStartComponent);
     }
     // LINT.ThenChange(:read_parcel)
 
     /** @hide */
     public ApplicationStartInfo(long monotonicCreationTimeMs) {
-        mMonoticCreationTimeMs = monotonicCreationTimeMs;
+        mMonotonicCreationTimeMs = monotonicCreationTimeMs;
     }
 
     /** @hide */
@@ -776,7 +776,7 @@
         mStartIntent = other.mStartIntent;
         mLaunchMode = other.mLaunchMode;
         mWasForceStopped = other.mWasForceStopped;
-        mMonoticCreationTimeMs = other.mMonoticCreationTimeMs;
+        mMonotonicCreationTimeMs = other.mMonotonicCreationTimeMs;
         mStartComponent = other.mStartComponent;
     }
 
@@ -803,7 +803,7 @@
                 in.readParcelable(Intent.class.getClassLoader(), android.content.Intent.class);
         mLaunchMode = in.readInt();
         mWasForceStopped = in.readBoolean();
-        mMonoticCreationTimeMs = in.readLong();
+        mMonotonicCreationTimeMs = in.readLong();
         mStartComponent = in.readInt();
     }
     // LINT.ThenChange(:write_parcel)
@@ -887,7 +887,7 @@
         }
         proto.write(ApplicationStartInfoProto.LAUNCH_MODE, mLaunchMode);
         proto.write(ApplicationStartInfoProto.WAS_FORCE_STOPPED, mWasForceStopped);
-        proto.write(ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS, mMonoticCreationTimeMs);
+        proto.write(ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS, mMonotonicCreationTimeMs);
         proto.write(ApplicationStartInfoProto.START_COMPONENT, mStartComponent);
         proto.end(token);
     }
@@ -980,7 +980,7 @@
                             ApplicationStartInfoProto.WAS_FORCE_STOPPED);
                     break;
                 case (int) ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS:
-                    mMonoticCreationTimeMs = proto.readLong(
+                    mMonotonicCreationTimeMs = proto.readLong(
                             ApplicationStartInfoProto.MONOTONIC_CREATION_TIME_MS);
                     break;
                 case (int) ApplicationStartInfoProto.START_COMPONENT:
@@ -999,7 +999,7 @@
         sb.append(prefix)
                 .append("ApplicationStartInfo ").append(seqSuffix).append(':')
                 .append('\n')
-                .append(" monotonicCreationTimeMs=").append(mMonoticCreationTimeMs)
+                .append(" monotonicCreationTimeMs=").append(mMonotonicCreationTimeMs)
                 .append('\n')
                 .append(" pid=").append(mPid)
                 .append(" realUid=").append(mRealUid)
@@ -1094,7 +1094,7 @@
                 && TextUtils.equals(mProcessName, o.mProcessName)
                 && timestampsEquals(o)
                 && mWasForceStopped == o.mWasForceStopped
-                && mMonoticCreationTimeMs == o.mMonoticCreationTimeMs
+                && mMonotonicCreationTimeMs == o.mMonotonicCreationTimeMs
                 && mStartComponent == o.mStartComponent;
     }
 
@@ -1102,7 +1102,7 @@
     public int hashCode() {
         return Objects.hash(mPid, mRealUid, mPackageUid, mDefiningUid, mReason, mStartupState,
                 mStartType, mLaunchMode, mPackageName, mProcessName, mStartupTimestampsNs,
-                mMonoticCreationTimeMs, mStartComponent);
+                mMonotonicCreationTimeMs, mStartComponent);
     }
 
     private boolean timestampsEquals(@NonNull ApplicationStartInfo other) {
diff --git a/core/java/android/app/AutomaticZenRule.aidl b/core/java/android/app/AutomaticZenRule.aidl
index feb21d6..92f7d52 100644
--- a/core/java/android/app/AutomaticZenRule.aidl
+++ b/core/java/android/app/AutomaticZenRule.aidl
@@ -16,4 +16,6 @@
 
 package android.app;
 
-parcelable AutomaticZenRule;
\ No newline at end of file
+parcelable AutomaticZenRule;
+
+parcelable AutomaticZenRule.AzrWithId;
\ No newline at end of file
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
index 2daa52b..1ce38ac 100644
--- a/core/java/android/app/AutomaticZenRule.java
+++ b/core/java/android/app/AutomaticZenRule.java
@@ -843,4 +843,41 @@
             return rule;
         }
     }
+
+    /** @hide */
+    public static final class AzrWithId implements Parcelable {
+        public final String mId;
+        public final AutomaticZenRule mRule;
+
+        public AzrWithId(String id, AutomaticZenRule rule) {
+            mId = id;
+            mRule = rule;
+        }
+
+        public static final Creator<AzrWithId> CREATOR = new Creator<>() {
+            @Override
+            public AzrWithId createFromParcel(Parcel in) {
+                return new AzrWithId(
+                        in.readString8(),
+                        in.readParcelable(AutomaticZenRule.class.getClassLoader(),
+                                AutomaticZenRule.class));
+            }
+
+            @Override
+            public AzrWithId[] newArray(int size) {
+                return new AzrWithId[size];
+            }
+        };
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeString8(mId);
+            dest.writeParcelable(mRule, flags);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+    }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 7e5c0fb..99a2763 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -2473,11 +2473,9 @@
     @Override
     public int getPermissionRequestState(String permission) {
         Objects.requireNonNull(permission, "Permission name can't be null");
-        int deviceId = PermissionManager.resolveDeviceIdForPermissionCheck(this, getDeviceId(),
-                permission);
         PermissionManager permissionManager = getSystemService(PermissionManager.class);
         return permissionManager.getPermissionRequestState(getOpPackageName(), permission,
-                deviceId);
+                getDeviceId());
     }
 
     @Override
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index 6efc4ef..3003b79 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -49,11 +49,14 @@
 import android.annotation.SuppressLint;
 import android.app.compat.CompatChanges;
 import android.app.role.RoleManager;
+import android.companion.virtual.VirtualDevice;
+import android.companion.virtual.VirtualDeviceManager;
 import android.compat.Compatibility;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.Disabled;
 import android.compat.annotation.EnabledAfter;
 import android.compat.annotation.Overridable;
+import android.content.AttributionSource;
 import android.content.Context;
 import android.content.PermissionChecker;
 import android.content.pm.PackageManager;
@@ -67,6 +70,7 @@
 import android.os.ServiceManager;
 import android.os.UserHandle;
 import android.permission.PermissionCheckerManager;
+import android.permission.PermissionManager;
 import android.provider.DeviceConfig;
 import android.text.TextUtils;
 import android.util.ArrayMap;
@@ -1174,17 +1178,48 @@
         @PackageManager.PermissionResult
         public int checkPermission(@NonNull Context context, int callerUid, int callerPid,
                 String packageName, boolean allowWhileInUse) {
-            return checkPermission(context, mName, callerUid, callerPid, packageName,
-                    allowWhileInUse);
+            int permissionResult = checkPermission(context, mName, callerUid, callerPid,
+                    packageName, allowWhileInUse, Context.DEVICE_ID_DEFAULT);
+
+            if (permissionResult == PERMISSION_GRANTED
+                    || !PermissionManager.DEVICE_AWARE_PERMISSIONS.contains(mName)) {
+                return permissionResult;
+            }
+
+            // For device aware permissions, check if the permission is granted on any other
+            // active virtual device
+            VirtualDeviceManager vdm = context.getSystemService(VirtualDeviceManager.class);
+            if (vdm == null) {
+                return permissionResult;
+            }
+
+            final List<VirtualDevice> virtualDevices = vdm.getVirtualDevices();
+            for (int i = 0, size = virtualDevices.size(); i < size; i++) {
+                final VirtualDevice virtualDevice = virtualDevices.get(i);
+                int resolvedDeviceId = PermissionManager.resolveDeviceIdForPermissionCheck(
+                        context, virtualDevice.getDeviceId(), mName);
+                // we already checked on the default device context
+                if (resolvedDeviceId == Context.DEVICE_ID_DEFAULT) {
+                    continue;
+                }
+                permissionResult = checkPermission(context, mName, callerUid, callerPid,
+                        packageName, allowWhileInUse, resolvedDeviceId);
+                if (permissionResult == PERMISSION_GRANTED) {
+                    break;
+                }
+            }
+
+            return permissionResult;
         }
 
         @SuppressLint("AndroidFrameworkRequiresPermission")
         @PackageManager.PermissionResult
         int checkPermission(@NonNull Context context, @NonNull String name, int callerUid,
-                int callerPid, String packageName, boolean allowWhileInUse) {
+                int callerPid, String packageName, boolean allowWhileInUse, int deviceId) {
+            final AttributionSource attributionSource = new AttributionSource(callerUid,
+                    packageName, null /*attributionTag*/, deviceId);
             @PermissionCheckerManager.PermissionResult final int result =
-                    PermissionChecker.checkPermissionForPreflight(context, name,
-                            callerPid, callerUid, packageName);
+                    PermissionChecker.checkPermissionForPreflight(context, name, attributionSource);
             if (result == PERMISSION_HARD_DENIED) {
                 // If the user didn't grant this permission at all.
                 return PERMISSION_DENIED;
@@ -1196,7 +1231,7 @@
                         ? PERMISSION_GRANTED : PERMISSION_DENIED;
             }
             final AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
-            final int mode = appOpsManager.unsafeCheckOpRawNoThrow(opCode, callerUid, packageName);
+            final int mode = appOpsManager.unsafeCheckOpRawNoThrow(opCode, attributionSource);
             switch (mode) {
                 case MODE_ALLOWED:
                     // The appop is just allowed, plain and simple.
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index 00df724..1f0cd39 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -224,7 +224,7 @@
     void setNotificationPolicyAccessGrantedForUser(String pkg, int userId, boolean granted);
     ZenPolicy getDefaultZenPolicy();
     AutomaticZenRule getAutomaticZenRule(String id);
-    Map<String, AutomaticZenRule> getAutomaticZenRules();
+    ParceledListSlice getAutomaticZenRules();
     String addAutomaticZenRule(in AutomaticZenRule automaticZenRule, String pkg, boolean fromUser);
     boolean updateAutomaticZenRule(String id, in AutomaticZenRule automaticZenRule, boolean fromUser);
     boolean removeAutomaticZenRule(String id, boolean fromUser);
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index 8af5b1b..19fecb9 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -101,14 +101,20 @@
      */
     public static final String REPORT_KEY_STREAMRESULT = "stream";
 
-    static final String TAG = "Instrumentation";
+    /**
+     * @hide
+     */
+    public static final String TAG = "Instrumentation";
 
     private static final long CONNECT_TIMEOUT_MILLIS = 60_000;
 
     private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
 
-    // If set, will print the stack trace for activity starts within the process
-    static final boolean DEBUG_START_ACTIVITY = Build.IS_DEBUGGABLE &&
+    /**
+     * If set, will print the stack trace for activity starts within the process
+     * @hide
+     */
+    public static final boolean DEBUG_START_ACTIVITY = Build.IS_DEBUGGABLE &&
             SystemProperties.getBoolean("persist.wm.debug.start_activity", false);
     static final boolean DEBUG_FINISH_ACTIVITY = Build.IS_DEBUGGABLE &&
             SystemProperties.getBoolean("persist.wm.debug.finish_activity", false);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index feaa98f..7c293cb 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6470,9 +6470,11 @@
             contentView.setViewVisibility(R.id.notification_material_reply_text_3, View.GONE);
             contentView.setTextViewText(R.id.notification_material_reply_text_3, null);
 
-            // This may get erased by bindSnoozeAction, or if we're showing the bubble icon
-            contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
-                    RemoteViews.MARGIN_BOTTOM, R.dimen.notification_content_margin);
+            if (!notificationsRedesignTemplates()) {
+                // This may get erased by bindSnoozeAction, or if we're showing the bubble icon
+                contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
+                        RemoteViews.MARGIN_BOTTOM, R.dimen.notification_content_margin);
+            }
         }
 
         private boolean bindSnoozeAction(RemoteViews contentView, StandardTemplateParams p) {
@@ -6489,7 +6491,7 @@
             final boolean snoozeEnabled = !hideSnoozeButton
                     && mContext.getContentResolver() != null
                     && isSnoozeSettingEnabled();
-            if (snoozeEnabled) {
+            if (!notificationsRedesignTemplates() && snoozeEnabled) {
                 contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
                         RemoteViews.MARGIN_BOTTOM, 0);
             }
@@ -6569,44 +6571,18 @@
             }
 
             boolean validRemoteInput = false;
+            // With the new design, the actions_container should always be visible to act as padding
+            // when there are no actions. We're making its child GONE instead.
+            int actionsContainerForVisibilityChange = notificationsRedesignTemplates()
+                    ? R.id.actions_container_layout : R.id.actions_container;
             if (numActions > 0 && !p.mHideActions) {
-                contentView.setViewVisibility(R.id.actions_container, View.VISIBLE);
+                contentView.setViewVisibility(actionsContainerForVisibilityChange, View.VISIBLE);
                 contentView.setViewVisibility(R.id.actions, View.VISIBLE);
-                contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
-                        RemoteViews.MARGIN_BOTTOM, 0);
-                if (notificationsRedesignTemplates()) {
-                    // No need for additional space under smart replies/smart actions.
-                    contentView.setViewLayoutMarginDimen(R.id.smart_reply_container,
-                            RemoteViews.MARGIN_BOTTOM, 0);
-                    if (emphasizedMode) {
-                        // Emphasized actions look similar to smart replies, so let's use the same
-                        // margins.
-                        contentView.setViewLayoutMarginDimen(R.id.actions_container,
-                                RemoteViews.MARGIN_TOP,
-                                R.dimen.notification_2025_smart_reply_container_margin);
-                        contentView.setViewLayoutMarginDimen(R.id.actions_container,
-                                RemoteViews.MARGIN_BOTTOM,
-                                R.dimen.notification_2025_smart_reply_container_margin);
-                    } else {
-                        contentView.setViewLayoutMarginDimen(R.id.actions_container,
-                                RemoteViews.MARGIN_TOP, 0);
-                        contentView.setViewLayoutMarginDimen(R.id.actions_container,
-                                RemoteViews.MARGIN_BOTTOM,
-                                R.dimen.notification_2025_action_list_margin_bottom);
-                    }
-                }
+                updateMarginsForActions(contentView, emphasizedMode);
                 validRemoteInput = populateActionsContainer(contentView, p, nonContextualActions,
                         numActions, emphasizedMode);
             } else {
-                contentView.setViewVisibility(R.id.actions_container, View.GONE);
-                if (notificationsRedesignTemplates() && !snoozeEnabled) {
-                    // Make sure smart replies & smart actions have enough space at the bottom
-                    // (if present) when there are no actions. This should be set to 0 if we're
-                    // showing the snooze or bubble buttons.
-                    contentView.setViewLayoutMarginDimen(R.id.smart_reply_container,
-                            RemoteViews.MARGIN_BOTTOM,
-                            R.dimen.notification_2025_smart_reply_container_margin);
-                }
+                contentView.setViewVisibility(actionsContainerForVisibilityChange, View.GONE);
             }
 
             RemoteInputHistoryItem[] replyText = getParcelableArrayFromBundle(
@@ -6652,6 +6628,30 @@
             return contentView;
         }
 
+        private void updateMarginsForActions(RemoteViews contentView, boolean emphasizedMode) {
+            if (notificationsRedesignTemplates()) {
+                if (emphasizedMode) {
+                    // Emphasized actions look similar to smart replies, so let's use the same
+                    // margins.
+                    contentView.setViewLayoutMarginDimen(R.id.actions_container,
+                            RemoteViews.MARGIN_TOP,
+                            R.dimen.notification_2025_smart_reply_container_margin);
+                    contentView.setViewLayoutMarginDimen(R.id.actions_container,
+                            RemoteViews.MARGIN_BOTTOM,
+                            R.dimen.notification_2025_smart_reply_container_margin);
+                } else {
+                    contentView.setViewLayoutMarginDimen(R.id.actions_container,
+                            RemoteViews.MARGIN_TOP, 0);
+                    contentView.setViewLayoutMarginDimen(R.id.actions_container,
+                            RemoteViews.MARGIN_BOTTOM,
+                            R.dimen.notification_2025_action_list_margin_bottom);
+                }
+            } else {
+                contentView.setViewLayoutMarginDimen(R.id.notification_action_list_margin_target,
+                        RemoteViews.MARGIN_BOTTOM, 0);
+            }
+        }
+
         private boolean populateActionsContainer(RemoteViews contentView, StandardTemplateParams p,
                 List<Action> nonContextualActions, int numActions, boolean emphasizedMode) {
             boolean validRemoteInput = false;
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 050ef23..69e3ef9 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1747,7 +1747,15 @@
     public Map<String, AutomaticZenRule> getAutomaticZenRules() {
         INotificationManager service = service();
         try {
-            return service.getAutomaticZenRules();
+            Map<String, AutomaticZenRule> result = new HashMap<>();
+            ParceledListSlice<AutomaticZenRule.AzrWithId> parceledRules =
+                    service.getAutomaticZenRules();
+            if (parceledRules != null) {
+                for (AutomaticZenRule.AzrWithId rule : parceledRules.getList()) {
+                    result.put(rule.mId, rule.mRule);
+                }
+            }
+            return result;
         } catch (RemoteException e) {
             throw e.rethrowFromSystemServer();
         }
diff --git a/core/java/android/app/PictureInPictureParams.java b/core/java/android/app/PictureInPictureParams.java
index afe915e..dd87d28 100644
--- a/core/java/android/app/PictureInPictureParams.java
+++ b/core/java/android/app/PictureInPictureParams.java
@@ -594,7 +594,7 @@
      * @see PictureInPictureParams.Builder#setSeamlessResizeEnabled(boolean)
      */
     public boolean isSeamlessResizeEnabled() {
-        return mSeamlessResizeEnabled == null ? true : mSeamlessResizeEnabled;
+        return mSeamlessResizeEnabled == null ? false : mSeamlessResizeEnabled;
     }
 
     /**
diff --git a/core/java/android/app/PropertyInvalidatedCache.java b/core/java/android/app/PropertyInvalidatedCache.java
index 38141cf..6e49576 100644
--- a/core/java/android/app/PropertyInvalidatedCache.java
+++ b/core/java/android/app/PropertyInvalidatedCache.java
@@ -1417,7 +1417,36 @@
     }
 
     /**
-     * Enable or disable testing.  The protocol requires that the mode toggle: for instance, it is
+     * Throw if the current process is not allowed to use test APIs.
+     */
+    @android.ravenwood.annotation.RavenwoodReplace
+    private static void throwIfNotTest() {
+        final ActivityThread activityThread = ActivityThread.currentActivityThread();
+        if (activityThread == null) {
+            // Only tests can reach here.
+            return;
+        }
+        final Instrumentation instrumentation = activityThread.getInstrumentation();
+        if (instrumentation == null) {
+            // Only tests can reach here.
+            return;
+        }
+        if (instrumentation.isInstrumenting()) {
+            return;
+        }
+        if (Flags.enforcePicTestmodeProtocol()) {
+            throw new IllegalStateException("Test-only API called not from a test.");
+        }
+    }
+
+    /**
+     * Do not throw if running under ravenwood.
+     */
+    private static void throwIfNotTest$ravenwood() {
+    }
+
+    /**
+     * Enable or disable test mode.  The protocol requires that the mode toggle: for instance, it is
      * illegal to clear the test mode if the test mode is already off.  Enabling test mode puts
      * all caches in the process into test mode; all nonces are initialized to UNSET and
      * subsequent reads and writes are to process memory.  This has the effect of disabling all
@@ -1425,10 +1454,12 @@
      * operation.
      * @param mode The desired test mode.
      * @throws IllegalStateException if the supplied mode is already set.
+     * @throws IllegalStateException if the process is not running an instrumentation test.
      * @hide
      */
     @VisibleForTesting
     public static void setTestMode(boolean mode) {
+        throwIfNotTest();
         synchronized (sGlobalLock) {
             if (sTestMode == mode) {
                 final String msg = "cannot set test mode redundantly: mode=" + mode;
@@ -1464,9 +1495,11 @@
      * for which it would not otherwise have permission.  Caches in test mode do NOT write their
      * values to the system properties.  The effect is local to the current process.  Test mode
      * must be true when this method is called.
+     * @throws IllegalStateException if the process is not running an instrumentation test.
      * @hide
      */
     public void testPropertyName() {
+        throwIfNotTest();
         synchronized (sGlobalLock) {
             if (sTestMode == false) {
                 throw new IllegalStateException("cannot test property name with test mode off");
@@ -1777,10 +1810,12 @@
      * When multiple caches share a single property value, using an instance method on one of
      * the cache objects to invalidate all of the cache objects becomes confusing and you should
      * just use the static version of this function.
+     * @throws IllegalStateException if the process is not running an instrumentation test.
      * @hide
      */
     @VisibleForTesting
     public void disableSystemWide() {
+        throwIfNotTest();
         disableSystemWide(mPropertyName);
     }
 
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 9574824..e8d2e28 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -20,6 +20,7 @@
 import static android.Manifest.permission.READ_WALLPAPER_INTERNAL;
 import static android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT;
 import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
+import static android.app.Flags.enableConnectedDisplaysWallpaper;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
 
@@ -248,7 +249,9 @@
     /**
      * Command for {@link #sendWallpaperCommand}: reported by System UI when the device keyguard
      * starts going away.
-     * This command is triggered by {@link android.app.IActivityTaskManager#keyguardGoingAway(int)}.
+     * <p>
+     * This command is triggered by {@link android.app.IActivityTaskManager#keyguardGoingAway(int)}
+     * or by {@link android.app.IActivityTaskManager#setLockScreenShown(boolean, boolean)}.
      *
      * @hide
      */
@@ -256,6 +259,18 @@
             "android.wallpaper.keyguardgoingaway";
 
     /**
+     * Command for {@link #sendWallpaperCommand}: reported by System UI when the device keyguard
+     * starts going away.
+     *
+     * <p>This command is triggered by
+     * {@link android.app.IActivityTaskManager#setLockScreenShown(boolean, boolean)}.
+     *
+     * @hide
+     */
+    public static final String COMMAND_KEYGUARD_APPEARING =
+            "android.wallpaper.keyguardappearing";
+
+    /**
      * Command for {@link #sendWallpaperCommand}: reported by System UI when the device is going to
      * sleep. The x and y arguments are a location (possibly very roughly) corresponding to the
      * action that caused the device to go to sleep. For example, if the power button was pressed,
@@ -860,7 +875,13 @@
                     return null;
                 }
                 try (InputStream is = new ParcelFileDescriptor.AutoCloseInputStream(pfd)) {
-                    ImageDecoder.Source src = ImageDecoder.createSource(context.getResources(), is);
+                    ImageDecoder.Source src;
+                    if (enableConnectedDisplaysWallpaper()) {
+                        src = ImageDecoder.createSource(context.getResources(), is,
+                                /* density= */ 0);
+                    } else {
+                        src = ImageDecoder.createSource(context.getResources(), is);
+                    }
                     return ImageDecoder.decodeBitmap(src, ((decoder, info, source) -> {
                         // Mutable and hardware config can't be set at the same time.
                         decoder.setMutableRequired(!hardware);
diff --git a/core/java/android/app/WindowConfiguration.java b/core/java/android/app/WindowConfiguration.java
index c6d0f61..8c99bd8 100644
--- a/core/java/android/app/WindowConfiguration.java
+++ b/core/java/android/app/WindowConfiguration.java
@@ -790,12 +790,6 @@
                 || mWindowingMode == WINDOWING_MODE_MULTI_WINDOW;
     }
 
-    /** Returns true if the task bounds should persist across power cycles.
-     * @hide */
-    public boolean persistTaskBounds() {
-        return mWindowingMode == WINDOWING_MODE_FREEFORM;
-    }
-
     /**
      * Returns true if the tasks associated with this window configuration are floating.
      * Floating tasks are laid out differently as they are allowed to extend past the display bounds
diff --git a/core/java/android/app/activity_manager.aconfig b/core/java/android/app/activity_manager.aconfig
index 720e045..29c84ee 100644
--- a/core/java/android/app/activity_manager.aconfig
+++ b/core/java/android/app/activity_manager.aconfig
@@ -163,3 +163,30 @@
     description: "Narrow the scope of Jank Perceptible"
     bug: "304837972"
 }
+
+flag {
+    name: "jank_perceptible_narrow_holdback"
+    namespace: "system_performance"
+    description: "Holdback study for jank_perceptible_narrow"
+    bug: "304837972"
+}
+
+flag {
+     namespace: "system_performance"
+     name: "app_start_info_cleanup_old_records"
+     description: "Cleanup old records to reduce size of in memory store."
+     bug: "384539178"
+     metadata {
+         purpose: PURPOSE_BUGFIX
+     }
+}
+
+flag {
+     namespace: "system_performance"
+     name: "app_start_info_keep_records_sorted"
+     description: "Ensure records are kept sorted to avoid extra work"
+     bug: "384539178"
+     metadata {
+         purpose: PURPOSE_BUGFIX
+     }
+}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index c74bd1a..c528db8 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -224,7 +224,7 @@
  * <li>A <i id="deviceowner">Device Owner</i>, which only ever exists on the
  * {@link UserManager#isSystemUser System User} or Main User, is
  * the most powerful type of Device Policy Controller and can affect policy across the device.
- * <li>A <i id="profileowner">Profile Owner<i>, which can exist on any user, can
+ * <li>A <i id="profileowner">Profile Owner</i>, which can exist on any user, can
  * affect policy on the user it is on, and when it is running on
  * {@link UserManager#isProfile a profile} has
  * <a href="#profile-on-parent">limited</a> ability to affect policy on its parent.
diff --git a/core/java/android/app/admin/StringSetIntersection.java b/core/java/android/app/admin/StringSetIntersection.java
new file mode 100644
index 0000000..5f2031e
--- /dev/null
+++ b/core/java/android/app/admin/StringSetIntersection.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.admin;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Set;
+
+/**
+ * Class to identify a intersection resolution mechanism for {@code Set<String>} policies, it's
+ * used to resolve the enforced policy when being set by multiple admins (see {@link
+ * PolicyState#getResolutionMechanism()}).
+ *
+ * @hide
+ */
+public final class StringSetIntersection extends ResolutionMechanism<Set<String>> {
+
+    /**
+     * Intersection resolution for policies represented {@code Set<String>} which resolves as the
+     * intersection of all sets.
+     */
+    @NonNull
+    public static final StringSetIntersection STRING_SET_INTERSECTION = new StringSetIntersection();
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        return o != null && getClass() == o.getClass();
+    }
+
+    @Override
+    public int hashCode() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "StringSetIntersection {}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {}
+
+    @NonNull
+    public static final Parcelable.Creator<StringSetIntersection> CREATOR =
+            new Parcelable.Creator<StringSetIntersection>() {
+                @Override
+                public StringSetIntersection createFromParcel(Parcel source) {
+                    return new StringSetIntersection();
+                }
+
+                @Override
+                public StringSetIntersection[] newArray(int size) {
+                    return new StringSetIntersection[size];
+                }
+            };
+}
diff --git a/core/java/android/app/admin/flags/flags.aconfig b/core/java/android/app/admin/flags/flags.aconfig
index 572bffe..b87ef70 100644
--- a/core/java/android/app/admin/flags/flags.aconfig
+++ b/core/java/android/app/admin/flags/flags.aconfig
@@ -412,3 +412,13 @@
     purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+  name: "use_policy_intersection_for_permitted_input_methods"
+  namespace: "enterprise"
+  description: "When deciding on permitted input methods, use policy intersection instead of last recorded policy."
+  bug: "340914586"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
diff --git a/core/java/android/app/jank/JankDataProcessor.java b/core/java/android/app/jank/JankDataProcessor.java
index 7718d15..3c8b1a0 100644
--- a/core/java/android/app/jank/JankDataProcessor.java
+++ b/core/java/android/app/jank/JankDataProcessor.java
@@ -366,7 +366,7 @@
                 30, 40, 50, 60, 70, 80, 90, 100, 150, 200, 300, 400, 500, 600, 700, 800, 900, 1000,
                 Integer.MAX_VALUE
         };
-        private final int[] mFrameOverrunBuckets = new int[sFrameOverrunHistogramBounds.length];
+        private final int[] mFrameOverrunBuckets = new int[sFrameOverrunHistogramBounds.length - 1];
 
         // Histogram of frame duration overruns encoded in predetermined buckets.
         public PendingJankStat() {
@@ -511,7 +511,7 @@
             if (overrunTime <= 1000) {
                 return (overrunTime - 200) / 100 + 43;
             }
-            return sFrameOverrunHistogramBounds.length - 1;
+            return mFrameOverrunBuckets.length - 1;
         }
 
     }
diff --git a/core/java/android/app/jank/TEST_MAPPING b/core/java/android/app/jank/TEST_MAPPING
new file mode 100644
index 0000000..271eb4332
--- /dev/null
+++ b/core/java/android/app/jank/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "postsubmit": [
+    {
+      "name": "CoreAppJankTestCases"
+    },
+    {
+      "name": "CtsAppJankTestCases"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/core/java/android/app/notification.aconfig b/core/java/android/app/notification.aconfig
index 5891bdd..6f0eafe 100644
--- a/core/java/android/app/notification.aconfig
+++ b/core/java/android/app/notification.aconfig
@@ -269,7 +269,7 @@
   namespace: "systemui"
   description: "enables metrics when redacting notifications on the lockscreen"
   bug: "343631648"
-    metadata {
+  metadata {
     purpose: PURPOSE_BUGFIX
   }
 }
@@ -279,7 +279,16 @@
   namespace: "systemui"
   description: "enables user expanding the public view of a notification"
   bug: "398853084"
-    metadata {
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+ }
+flag {
+  name: "notif_entry_creation_time_use_elapsed_realtime"
+  namespace: "systemui"
+  description: "makes the notification entry expect its creation time to be elapsedRealtime, not uptimeMillis"
+  bug: "343631648"
+  metadata {
     purpose: PURPOSE_BUGFIX
   }
 }
diff --git a/core/java/android/app/supervision/SupervisionManager.java b/core/java/android/app/supervision/SupervisionManager.java
index 8217ca1..172ed23 100644
--- a/core/java/android/app/supervision/SupervisionManager.java
+++ b/core/java/android/app/supervision/SupervisionManager.java
@@ -97,6 +97,8 @@
      *
      * @hide
      */
+    @SystemApi
+    @FlaggedApi(Flags.FLAG_SUPERVISION_MANAGER_APIS)
     @RequiresPermission(anyOf = {MANAGE_USERS, QUERY_USERS})
     @Nullable
     public Intent createConfirmSupervisionCredentialsIntent() {
diff --git a/core/java/android/app/wallpaper.aconfig b/core/java/android/app/wallpaper.aconfig
index 7aba172..4a15a72 100644
--- a/core/java/android/app/wallpaper.aconfig
+++ b/core/java/android/app/wallpaper.aconfig
@@ -24,6 +24,16 @@
 }
 
 flag {
+  name: "notify_keyguard_events"
+  namespace: "systemui"
+  description: "Send keyguard showing/hiding/going-away events to wallpaper as wallpaper commands (guarded by permission)"
+  bug: "395897130"
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "accurate_wallpaper_downsampling"
   namespace: "systemui"
   description: "Accurate downsampling of wallpaper bitmap for high resolution images"
diff --git a/core/java/android/app/wallpaper/WallpaperDescription.java b/core/java/android/app/wallpaper/WallpaperDescription.java
index a13af7f..d7d6262 100644
--- a/core/java/android/app/wallpaper/WallpaperDescription.java
+++ b/core/java/android/app/wallpaper/WallpaperDescription.java
@@ -168,6 +168,12 @@
         return mSampleSize;
     }
 
+    @Override
+    public String toString() {
+        String component = (mComponent != null) ? mComponent.toString() : "{null}";
+        return  component + ":" + mId;
+    }
+
     ////// Comparison overrides
 
     @Override
diff --git a/core/java/android/companion/virtual/IVirtualDevice.aidl b/core/java/android/companion/virtual/IVirtualDevice.aidl
index f8ac27d..db77ade 100644
--- a/core/java/android/companion/virtual/IVirtualDevice.aidl
+++ b/core/java/android/companion/virtual/IVirtualDevice.aidl
@@ -24,6 +24,7 @@
 import android.companion.virtual.audio.IAudioConfigChangedCallback;
 import android.companion.virtual.audio.IAudioRoutingCallback;
 import android.companion.virtual.sensor.VirtualSensor;
+import android.companion.virtual.sensor.VirtualSensorAdditionalInfo;
 import android.companion.virtual.sensor.VirtualSensorConfig;
 import android.companion.virtual.sensor.VirtualSensorEvent;
 import android.companion.virtual.camera.VirtualCameraConfig;
@@ -251,6 +252,11 @@
     boolean sendSensorEvent(IBinder token, in VirtualSensorEvent event);
 
     /**
+     * Sends additional information about the virtual sensor corresponding to the given token.
+     */
+    boolean sendSensorAdditionalInfo(IBinder token, in VirtualSensorAdditionalInfo info);
+
+    /**
      * Launches a pending intent on the given display that is owned by this virtual device.
      */
     void launchPendingIntent(int displayId, in PendingIntent pendingIntent,
diff --git a/core/java/android/companion/virtual/flags/flags.aconfig b/core/java/android/companion/virtual/flags/flags.aconfig
index 4fb3982..615a6df 100644
--- a/core/java/android/companion/virtual/flags/flags.aconfig
+++ b/core/java/android/companion/virtual/flags/flags.aconfig
@@ -158,3 +158,11 @@
     bug: "370720522"
     is_exported: true
 }
+
+flag {
+    name: "virtual_sensor_additional_info"
+    namespace: "virtual_devices"
+    description: "API for injecting SensorAdditionalInfo for VirtualSensor"
+    bug: "393517834"
+    is_exported: true
+}
diff --git a/core/java/android/companion/virtual/sensor/VirtualSensor.java b/core/java/android/companion/virtual/sensor/VirtualSensor.java
index 934a1a8..8d4acfc 100644
--- a/core/java/android/companion/virtual/sensor/VirtualSensor.java
+++ b/core/java/android/companion/virtual/sensor/VirtualSensor.java
@@ -16,12 +16,15 @@
 
 package android.companion.virtual.sensor;
 
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.companion.virtual.IVirtualDevice;
+import android.companion.virtualdevice.flags.Flags;
 import android.hardware.Sensor;
+import android.hardware.SensorAdditionalInfo;
 import android.os.IBinder;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -37,20 +40,33 @@
  */
 @SystemApi
 public final class VirtualSensor implements Parcelable {
+
     private final int mHandle;
     private final int mType;
     private final String mName;
+    private final int mFlags;
     private final IVirtualDevice mVirtualDevice;
     private final IBinder mToken;
+    // Only one additional info frame set at a time.
+    private final Object mAdditionalInfoLock = new Object();
 
     /**
      * @hide
      */
     public VirtualSensor(int handle, int type, String name, IVirtualDevice virtualDevice,
             IBinder token) {
+        this(handle, type, name, /*flags=*/0, virtualDevice, token);
+    }
+
+    /**
+     * @hide
+     */
+    public VirtualSensor(int handle, int type, String name, int flags, IVirtualDevice virtualDevice,
+            IBinder token) {
         mHandle = handle;
         mType = type;
         mName = name;
+        mFlags = flags;
         mVirtualDevice = virtualDevice;
         mToken = token;
     }
@@ -61,13 +77,14 @@
     @SuppressLint("UnflaggedApi") // @TestApi without associated feature.
     @TestApi
     public VirtualSensor(int handle, int type, @NonNull String name) {
-        this(handle, type, name, /*virtualDevice=*/null, /*token=*/null);
+        this(handle, type, name, /*flags=*/0, /*virtualDevice=*/null, /*token=*/null);
     }
 
     private VirtualSensor(Parcel parcel) {
         mHandle = parcel.readInt();
         mType = parcel.readInt();
         mName = parcel.readString8();
+        mFlags = parcel.readInt();
         mVirtualDevice = IVirtualDevice.Stub.asInterface(parcel.readStrongBinder());
         mToken = parcel.readStrongBinder();
     }
@@ -123,6 +140,7 @@
         parcel.writeInt(mHandle);
         parcel.writeInt(mType);
         parcel.writeString8(mName);
+        parcel.writeInt(mFlags);
         parcel.writeStrongBinder(mVirtualDevice.asBinder());
         parcel.writeStrongBinder(mToken);
     }
@@ -143,6 +161,33 @@
         }
     }
 
+    /**
+     * Send additional information about the sensor to the system.
+     *
+     * @param info the additional sensor information to send.
+     * @throws UnsupportedOperationException if the sensor does not support sending additional info.
+     * @see Sensor#isAdditionalInfoSupported()
+     * @see VirtualSensorConfig.Builder#setAdditionalInfoSupported(boolean)
+     * @see SensorAdditionalInfo
+     * @see VirtualSensorAdditionalInfo
+     */
+    @FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO)
+    public void sendAdditionalInfo(@NonNull VirtualSensorAdditionalInfo info) {
+        if (!Flags.virtualSensorAdditionalInfo()) {
+            return;
+        }
+        if ((mFlags & VirtualSensorConfig.ADDITIONAL_INFO_MASK) == 0) {
+            throw new UnsupportedOperationException("Sensor additional info not supported.");
+        }
+        try {
+            synchronized (mAdditionalInfoLock) {
+                mVirtualDevice.sendSensorAdditionalInfo(mToken, info);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
     @NonNull
     public static final Parcelable.Creator<VirtualSensor> CREATOR =
             new Parcelable.Creator<VirtualSensor>() {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt b/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.aidl
similarity index 75%
copy from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt
copy to core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.aidl
index 260729b..7267be8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt
+++ b/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.aidl
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package android.companion.virtual.sensor;
 
-@JvmInline value class IssueRecordingModel(val isRecording: Boolean)
+parcelable VirtualSensorAdditionalInfo;
\ No newline at end of file
diff --git a/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.java b/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.java
new file mode 100644
index 0000000..a4fca50
--- /dev/null
+++ b/core/java/android/companion/virtual/sensor/VirtualSensorAdditionalInfo.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.companion.virtual.sensor;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.companion.virtualdevice.flags.Flags;
+import android.hardware.SensorAdditionalInfo;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * An additional information frame for a {@link VirtualSensor}, which is reported through listener
+ * callback {@link android.hardware.SensorEventCallback#onSensorAdditionalInfo}.
+ *
+ * @see SensorAdditionalInfo
+ * @see VirtualSensorConfig.Builder#setAdditionalInfoSupported(boolean)
+ * @hide
+ */
+@FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO)
+@SystemApi
+public final class VirtualSensorAdditionalInfo implements Parcelable {
+
+    private final int mType;
+    @NonNull
+    private final List<float[]> mValues;
+
+    /** @hide */
+    @IntDef(prefix = "TYPE_", value = {
+            SensorAdditionalInfo.TYPE_UNTRACKED_DELAY,
+            SensorAdditionalInfo.TYPE_INTERNAL_TEMPERATURE,
+            SensorAdditionalInfo.TYPE_VEC3_CALIBRATION,
+            SensorAdditionalInfo.TYPE_SENSOR_PLACEMENT,
+            SensorAdditionalInfo.TYPE_SAMPLING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    private VirtualSensorAdditionalInfo(int type, @NonNull List<float[]> values) {
+        mType = type;
+        mValues = values;
+    }
+
+    private VirtualSensorAdditionalInfo(@NonNull Parcel parcel) {
+        mType = parcel.readInt();
+        final int valuesLength = parcel.readInt();
+        mValues = new ArrayList<>(valuesLength);
+        for (int i = 0; i < valuesLength; ++i) {
+            mValues.add(parcel.createFloatArray());
+        }
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel parcel, int parcelableFlags) {
+        parcel.writeInt(mType);
+        parcel.writeInt(mValues.size());
+        for (int i = 0; i < mValues.size(); ++i) {
+            parcel.writeFloatArray(mValues.get(i));
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Returns the type of this information frame.
+     *
+     * @see SensorAdditionalInfo#type
+     */
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Returns the float values of this information frame, if any.
+     *
+     * @see SensorAdditionalInfo#floatValues
+     */
+    @NonNull
+    public List<float[]> getValues() {
+        return mValues;
+    }
+
+    /**
+     * Builder for {@link VirtualSensorAdditionalInfo}.
+     */
+    public static final class Builder {
+
+        @VirtualSensorAdditionalInfo.Type
+        private final int mType;
+        @NonNull
+        private final ArrayList<float[]> mValues = new ArrayList<>();
+
+        /**
+         * Creates a new builder.
+         *
+         * @param type type of this additional info frame.
+         * @see SensorAdditionalInfo
+         */
+        public Builder(@VirtualSensorAdditionalInfo.Type int type) {
+            switch (type) {
+                case SensorAdditionalInfo.TYPE_UNTRACKED_DELAY:
+                case SensorAdditionalInfo.TYPE_SAMPLING:
+                case SensorAdditionalInfo.TYPE_INTERNAL_TEMPERATURE:
+                case SensorAdditionalInfo.TYPE_VEC3_CALIBRATION:
+                case SensorAdditionalInfo.TYPE_SENSOR_PLACEMENT:
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unsupported type " + type);
+            }
+            mType = type;
+        }
+
+        /**
+         * Additional info payload data represented in float values. Depending on the type of
+         * information, this may be null.
+         *
+         * @see SensorAdditionalInfo#floatValues
+         */
+        @NonNull
+        public Builder addValues(@NonNull float[] values) {
+            if (values.length > 14) {
+                throw new IllegalArgumentException("Maximum payload value size is 14.");
+            }
+            if (mValues.isEmpty()) {
+                switch (mType) {
+                    case SensorAdditionalInfo.TYPE_UNTRACKED_DELAY:
+                    case SensorAdditionalInfo.TYPE_SAMPLING:
+                        assertValuesLength(values, 2);
+                        break;
+                    case SensorAdditionalInfo.TYPE_INTERNAL_TEMPERATURE:
+                        assertValuesLength(values, 1);
+                        break;
+                    case SensorAdditionalInfo.TYPE_VEC3_CALIBRATION:
+                    case SensorAdditionalInfo.TYPE_SENSOR_PLACEMENT:
+                        assertValuesLength(values, 11);
+                        break;
+                }
+            } else if (values.length != mValues.getFirst().length) {
+                throw new IllegalArgumentException("All payload values must have the same length");
+            }
+
+            mValues.add(values);
+            return this;
+        }
+
+        private void assertValuesLength(float[] values, int expected) {
+            if (values.length != expected) {
+                throw new IllegalArgumentException(
+                        "Payload values must have size " + expected + " for type " + mType);
+            }
+        }
+
+        /**
+         * Creates a new {@link VirtualSensorAdditionalInfo}.
+         *
+         * @throws IllegalArgumentException if the payload doesn't match the expectation for the
+         *   given type, as documented in {@link SensorAdditionalInfo}.
+         */
+        @NonNull
+        public VirtualSensorAdditionalInfo build() {
+            if (mValues.isEmpty()) {
+                throw new IllegalArgumentException("Payload is required");
+            }
+            return new VirtualSensorAdditionalInfo(mType, mValues);
+        }
+    }
+
+    public static final @NonNull Creator<VirtualSensorAdditionalInfo> CREATOR =
+            new Creator<>() {
+                public VirtualSensorAdditionalInfo createFromParcel(Parcel source) {
+                    return new VirtualSensorAdditionalInfo(source);
+                }
+
+                public VirtualSensorAdditionalInfo[] newArray(int size) {
+                    return new VirtualSensorAdditionalInfo[size];
+                }
+            };
+}
diff --git a/core/java/android/companion/virtual/sensor/VirtualSensorConfig.java b/core/java/android/companion/virtual/sensor/VirtualSensorConfig.java
index 68bc9bc..be8974e 100644
--- a/core/java/android/companion/virtual/sensor/VirtualSensorConfig.java
+++ b/core/java/android/companion/virtual/sensor/VirtualSensorConfig.java
@@ -59,10 +59,14 @@
     private static final int REPORTING_MODE_MASK = 0xE;
     private static final int REPORTING_MODE_SHIFT = 1;
 
+    // Mask for indication bit of sensor additional information support, bit 6.
+    static final int ADDITIONAL_INFO_MASK = 0x40;
+
     // Mask for direct mode highest rate level, bit 7, 8, 9.
     private static final int DIRECT_REPORT_MASK = 0x380;
     private static final int DIRECT_REPORT_SHIFT = 7;
 
+
     // Mask for supported direct channel, bit 10, 11
     private static final int DIRECT_CHANNEL_SHIFT = 10;
 
@@ -253,6 +257,18 @@
     }
 
     /**
+     * Returns whether the sensor supports additional information.
+     *
+     * @see Builder#setAdditionalInfoSupported(boolean)
+     * @see Sensor#isAdditionalInfoSupported()
+     * @see android.hardware.SensorAdditionalInfo
+     */
+    @FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO)
+    public boolean isAdditionalInfoSupported() {
+        return (mFlags & ADDITIONAL_INFO_MASK) > 0;
+    }
+
+    /**
      * Returns the reporting mode of this sensor.
      *
      * @see Builder#setReportingMode(int)
@@ -450,6 +466,25 @@
         }
 
         /**
+         * Sets whether this sensor supports sensor additional information.
+         *
+         * @see Sensor#isAdditionalInfoSupported()
+         * @see android.hardware.SensorAdditionalInfo
+         * @see VirtualSensorAdditionalInfo
+         */
+        @FlaggedApi(Flags.FLAG_VIRTUAL_SENSOR_ADDITIONAL_INFO)
+        @NonNull
+        public VirtualSensorConfig.Builder setAdditionalInfoSupported(
+                boolean additionalInfoSupported) {
+            if (additionalInfoSupported) {
+                mFlags |= ADDITIONAL_INFO_MASK;
+            } else {
+                mFlags &= ~ADDITIONAL_INFO_MASK;
+            }
+            return this;
+        }
+
+        /**
          * Sets the reporting mode of this sensor.
          *
          * @throws IllegalArgumentException if the reporting mode is not one of
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 49fd634..53966b8 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -5964,7 +5964,39 @@
      *
      * @see #getLaunchIntentSenderForPackage(String)
      */
-    public abstract @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName);
+     public abstract @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName);
+
+    /**
+     * Returns a "good" intent to launch a front-door activity in a package.
+     * This is used, for example, to implement an "open" button when browsing
+     * through packages.  The current implementation looks first for a main
+     * activity in the category {@link Intent#CATEGORY_INFO}, and next for a
+     * main activity in the category {@link Intent#CATEGORY_LAUNCHER}. Returns
+     * <code>null</code> if neither are found.
+     *
+     * <p>Consider using {@link #getLaunchIntentSenderForPackage(String)} if
+     * the caller is not allowed to query for the <code>packageName</code>.
+     *
+     * @param packageName The name of the package to inspect.
+     * @param includeDirectBootUnaware When {@code true}, activities that are direct-boot-unaware
+     *    will be considered even if the device hasn't been unlocked (i.e. querying will be done
+     *    with {@code MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE}).
+     *
+     * @return A fully-qualified {@link Intent} that can be used to launch the
+     * main activity in the package. Returns <code>null</code> if the package
+     * does not contain such an activity, or if <em>packageName</em> is not
+     * recognized.
+     *
+     * @see #getLaunchIntentSenderForPackage(String)
+     *
+     * @hide
+     */
+    public @Nullable Intent getLaunchIntentForPackage(@NonNull String packageName,
+            boolean includeDirectBootUnaware) {
+        throw new UnsupportedOperationException(
+                "getLaunchIntentForPackage(packageName, includeDirectBootUnaware) not implemented"
+                        + " in subclass");
+    }
 
     /**
      * Return a "good" intent to launch a front-door Leanback activity in a
diff --git a/core/java/android/content/pm/RegisteredServicesCache.java b/core/java/android/content/pm/RegisteredServicesCache.java
index 10d3051..ded35b2 100644
--- a/core/java/android/content/pm/RegisteredServicesCache.java
+++ b/core/java/android/content/pm/RegisteredServicesCache.java
@@ -31,13 +31,13 @@
 import android.os.Handler;
 import android.os.UserHandle;
 import android.os.UserManager;
-import android.util.ArrayMap;
 import android.util.AtomicFile;
 import android.util.AttributeSet;
 import android.util.IntArray;
 import android.util.Log;
 import android.util.Slog;
 import android.util.SparseArray;
+import android.util.SparseArrayMap;
 import android.util.Xml;
 
 import com.android.internal.annotations.GuardedBy;
@@ -98,15 +98,16 @@
     @GuardedBy("mServicesLock")
     private final SparseArray<UserServices<V>> mUserServices = new SparseArray<UserServices<V>>(2);
 
-    @GuardedBy("mServiceInfoCaches")
-    private final ArrayMap<ComponentName, ServiceInfo<V>> mServiceInfoCaches = new ArrayMap<>();
+    @GuardedBy("mUserIdToServiceInfoCaches")
+    private final SparseArrayMap<ComponentName, ServiceInfo<V>> mUserIdToServiceInfoCaches =
+            new SparseArrayMap<>();
 
     private final Handler mBackgroundHandler;
 
     private final Runnable mClearServiceInfoCachesRunnable = new Runnable() {
         public void run() {
-            synchronized (mServiceInfoCaches) {
-                mServiceInfoCaches.clear();
+            synchronized (mUserIdToServiceInfoCaches) {
+                mUserIdToServiceInfoCaches.clear();
             }
         }
     };
@@ -537,8 +538,8 @@
                     Slog.d(TAG, "Fail to get the PackageInfo in generateServicesMap: " + e);
                 }
                 if (lastUpdateTime >= 0) {
-                    ServiceInfo<V> serviceInfo = getServiceInfoFromServiceCache(componentName,
-                            lastUpdateTime);
+                    ServiceInfo<V> serviceInfo = getServiceInfoFromServiceCache(userId,
+                            componentName, lastUpdateTime);
                     if (serviceInfo != null) {
                         serviceInfos.add(serviceInfo);
                         continue;
@@ -553,8 +554,8 @@
                 }
                 serviceInfos.add(info);
                 if (Flags.optimizeParsingInRegisteredServicesCache()) {
-                    synchronized (mServiceInfoCaches) {
-                        mServiceInfoCaches.put(componentName, info);
+                    synchronized (mUserIdToServiceInfoCaches) {
+                        mUserIdToServiceInfoCaches.add(userId, componentName, info);
                     }
                 }
             } catch (XmlPullParserException | IOException e) {
@@ -563,8 +564,8 @@
         }
 
         if (Flags.optimizeParsingInRegisteredServicesCache()) {
-            synchronized (mServiceInfoCaches) {
-                if (!mServiceInfoCaches.isEmpty()) {
+            synchronized (mUserIdToServiceInfoCaches) {
+                if (mUserIdToServiceInfoCaches.numMaps() > 0) {
                     mBackgroundHandler.removeCallbacks(mClearServiceInfoCachesRunnable);
                     mBackgroundHandler.postDelayed(mClearServiceInfoCachesRunnable,
                             SERVICE_INFO_CACHES_TIMEOUT_MILLIS);
@@ -873,6 +874,11 @@
         synchronized (mServicesLock) {
             mUserServices.remove(userId);
         }
+        if (Flags.optimizeParsingInRegisteredServicesCache()) {
+            synchronized (mUserIdToServiceInfoCaches) {
+                mUserIdToServiceInfoCaches.delete(userId);
+            }
+        }
     }
 
     @VisibleForTesting
@@ -916,10 +922,10 @@
         mContext.unregisterReceiver(mUserRemovedReceiver);
     }
 
-    private ServiceInfo<V> getServiceInfoFromServiceCache(@NonNull ComponentName componentName,
-            long lastUpdateTime) {
-        synchronized (mServiceInfoCaches) {
-            ServiceInfo<V> serviceCache = mServiceInfoCaches.get(componentName);
+    private ServiceInfo<V> getServiceInfoFromServiceCache(int userId,
+            @NonNull ComponentName componentName, long lastUpdateTime) {
+        synchronized (mUserIdToServiceInfoCaches) {
+            ServiceInfo<V> serviceCache = mUserIdToServiceInfoCaches.get(userId, componentName);
             if (serviceCache != null && serviceCache.lastUpdateTime == lastUpdateTime) {
                 return serviceCache;
             }
diff --git a/core/java/android/content/pm/SystemFeaturesCache.java b/core/java/android/content/pm/SystemFeaturesCache.java
index b3d70fa..57dd1e6 100644
--- a/core/java/android/content/pm/SystemFeaturesCache.java
+++ b/core/java/android/content/pm/SystemFeaturesCache.java
@@ -74,6 +74,11 @@
         return instance;
     }
 
+    /** Checks for existence of the process-global instance. */
+    public static boolean hasInstance() {
+        return sInstance != null;
+    }
+
     /** Clears the process-global cache instance for testing. */
     @VisibleForTesting
     public static void clearInstance() {
diff --git a/core/java/android/content/pm/TEST_MAPPING b/core/java/android/content/pm/TEST_MAPPING
index 23f1ff8..92ae15a 100644
--- a/core/java/android/content/pm/TEST_MAPPING
+++ b/core/java/android/content/pm/TEST_MAPPING
@@ -136,6 +136,28 @@
             ]
         },
         {
+          "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases",
+          "options":[
+              {
+                  "exclude-annotation":"androidx.test.filters.FlakyTest"
+              },
+              {
+                  "exclude-annotation":"org.junit.Ignore"
+              }
+          ]
+        },
+        {
+          "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases",
+          "options":[
+              {
+                  "exclude-annotation":"androidx.test.filters.FlakyTest"
+              },
+              {
+                  "exclude-annotation":"org.junit.Ignore"
+              }
+          ]
+        },
+        {
             "name": "CtsPackageInstallerCUJMultiUsersTestCases",
             "options":[
                {
@@ -261,6 +283,28 @@
             ]
         },
         {
+            "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases",
+            "options":[
+               {
+                   "exclude-annotation":"androidx.test.filters.FlakyTest"
+               },
+               {
+                   "exclude-annotation":"org.junit.Ignore"
+               }
+            ]
+        },
+        {
+            "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases",
+            "options":[
+               {
+                   "exclude-annotation":"androidx.test.filters.FlakyTest"
+               },
+               {
+                   "exclude-annotation":"org.junit.Ignore"
+               }
+            ]
+        },
+        {
             "name": "CtsPackageInstallerCUJMultiUsersTestCases",
             "options":[
                {
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 53203eb..c5412a9 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -494,10 +494,14 @@
     // TODO(b/142482943): Make this logic more specific and customizable. (canHaveProfile(userType))
     /* @hide */
     public boolean canHaveProfile() {
-        if (isProfile() || isGuest() || isRestricted()) {
+        if (!isFull() || isProfile() || isGuest() || isRestricted() || isDemo()) {
             return false;
         }
-        return isMain();
+        // NOTE: profiles used to be restricted just to the system user (and later to the main
+        // user), but from the framework point of view there is no need for such restriction, hence
+        // it's lifted
+        // TODO(b/374832167): check value of config_supportProfilesOnNonMainUser
+        return isMain() || android.multiuser.Flags.profilesForAll();
     }
 
     // TODO(b/142482943): Get rid of this (after removing it from all tests) if feasible.
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index 7f57f5dbf0..3dbd5b2 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -636,3 +636,20 @@
     description: "Enables support for new supervising user type"
     bug: "389712089"
 }
+
+flag {
+    name: "use_unified_resources"
+    namespace: "multiuser"
+    description: "Use same resources"
+    bug: "392972139"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+     name: "profiles_for_all"
+     namespace: "multiuser"
+     description: "Allows any regular user to have profiles"
+     bug: "374832167"
+}
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index a7fbce5..7dc6afb 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -188,24 +188,6 @@
     int BIOMETRIC_ERROR_CONTENT_VIEW_MORE_OPTIONS_BUTTON = 22;
 
     /**
-     * The error code returned after lock out error happens, the error dialog shows, and the users
-     * dismisses the dialog. This is a placeholder that is currently only used by the support
-     * library.
-     *
-     * @hide
-     */
-    int BIOMETRIC_ERROR_LOCKOUT_ERROR_DIALOG_DISMISSED = 23;
-
-    /**
-     * The error code returned after biometric hardware error happens, the error dialog shows, and
-     * the users dismisses the dialog.This is a placeholder that is currently only used by the
-     * support library.
-     *
-     * @hide
-     */
-    int BIOMETRIC_ERROR_BIOMETRIC_HARDWARE_ERROR_DIALOG_DISMISSED = 24;
-
-    /**
      * This constant is only used by SystemUI. It notifies SystemUI that authentication was paused
      * because the authentication attempt was unsuccessful.
      * @hide
@@ -237,8 +219,6 @@
             BIOMETRIC_ERROR_IDENTITY_CHECK_NOT_ACTIVE,
             BIOMETRIC_ERROR_NOT_ENABLED_FOR_APPS,
             BIOMETRIC_ERROR_CONTENT_VIEW_MORE_OPTIONS_BUTTON,
-            BIOMETRIC_ERROR_LOCKOUT_ERROR_DIALOG_DISMISSED,
-            BIOMETRIC_ERROR_BIOMETRIC_HARDWARE_ERROR_DIALOG_DISMISSED,
             BIOMETRIC_PAUSED_REJECTED})
     @Retention(RetentionPolicy.SOURCE)
     @interface Errors {}
diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java
index fdde205..de3bafb 100644
--- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java
+++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableParcelable.java
@@ -75,7 +75,6 @@
             }
 
             Parcel parcel = Parcel.obtain();
-            byte[] parcelContents;
 
             try {
                 value.writeToParcel(parcel, /*flags*/0);
@@ -85,17 +84,15 @@
                             "Parcelable " + value + " must not have file descriptors");
                 }
 
-                parcelContents = parcel.marshall();
+                final int position = buffer.position();
+                parcel.marshall(buffer);
+                if (buffer.position() == position) {
+                    throw new AssertionError("No data marshaled for " + value);
+                }
             }
             finally {
                 parcel.recycle();
             }
-
-            if (parcelContents.length == 0) {
-                throw new AssertionError("No data marshaled for " + value);
-            }
-
-            buffer.put(parcelContents);
         }
 
         @Override
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
index 92a56fc..8216130 100644
--- a/core/java/android/hardware/display/DisplayManager.java
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -433,8 +433,9 @@
     public static final int VIRTUAL_DISPLAY_FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 8;
 
     /**
-     * Virtual display flag: Indicates that the display should support system decorations. Virtual
-     * displays without this flag shouldn't show home, navigation bar or wallpaper.
+     * Virtual display flag: Indicates that the display supports and should always show system
+     * decorations. Virtual displays without this flag shouldn't show home, navigation bar or
+     * wallpaper.
      * <p>This flag doesn't work without {@link #VIRTUAL_DISPLAY_FLAG_TRUSTED}</p>
      *
      * @see #createVirtualDisplay
diff --git a/core/java/android/hardware/display/DisplayTopology.java b/core/java/android/hardware/display/DisplayTopology.java
index 4ed0fc0..c3c8c3d 100644
--- a/core/java/android/hardware/display/DisplayTopology.java
+++ b/core/java/android/hardware/display/DisplayTopology.java
@@ -600,8 +600,7 @@
 
     private void addDisplay(int displayId, float width, float height, boolean shouldLog) {
         if (findDisplay(displayId, mRoot) != null) {
-            throw new IllegalArgumentException(
-                    "DisplayTopology: attempting to add a display that already exists");
+            return;
         }
         if (mRoot == null) {
             mRoot = new TreeNode(displayId, width, height, POSITION_LEFT, /* offset= */ 0);
diff --git a/core/java/android/hardware/serial/OWNERS b/core/java/android/hardware/serial/OWNERS
index bc2c66a..13f6774 100644
--- a/core/java/android/hardware/serial/OWNERS
+++ b/core/java/android/hardware/serial/OWNERS
@@ -3,4 +3,5 @@
 chominskib@google.com
 wzwonarz@google.com
 gstepniewski@google.com
-xutan@google.com
\ No newline at end of file
+xutan@google.com
+ovn@google.com
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 894b068..84d96bd 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -428,6 +428,9 @@
      */
     @AnyThread
     public static boolean canImeRenderGesturalNavButtons() {
+        if (Flags.disallowDisablingImeNavigationBar()) {
+            return true;
+        }
         return SystemProperties.getBoolean(PROP_CAN_RENDER_GESTURAL_NAV_BUTTONS, true);
     }
 
@@ -3501,6 +3504,10 @@
                 mInlineSuggestionSessionController.notifyOnStartInputView();
                 onStartInputView(mInputEditorInfo, restarting);
                 startExtractingText(true);
+                // Back callback is typically registered in {@link #showWindow()}, but it's possible
+                // for {@link #doStartInput()} to be called without {@link #showWindow()} so we also
+                // register here.
+                registerDefaultOnBackInvokedCallback();
             } else if (mCandidatesVisibility == View.VISIBLE) {
                 if (DEBUG) Log.v(TAG, "CALL: onStartCandidatesView");
                 mCandidatesViewStarted = true;
diff --git a/core/java/android/inputmethodservice/NavigationBarController.java b/core/java/android/inputmethodservice/NavigationBarController.java
index f420b5d..7da053d 100644
--- a/core/java/android/inputmethodservice/NavigationBarController.java
+++ b/core/java/android/inputmethodservice/NavigationBarController.java
@@ -236,7 +236,12 @@
                             systemInsets.bottom, Gravity.BOTTOM));
                     mLastInsets = systemInsets;
                 } else {
-                    decorView.addView(mNavigationBarFrame);
+                    // If systemInsets are null, the DecorView is not attached to the window yet.
+                    // Use the final captionBar height as the initial one, otherwise it resolves to
+                    // match parent, and can lead to full size IME insets.
+                    final int height = getImeCaptionBarHeight(true /* imeDrawsImeNavBar */);
+                    decorView.addView(mNavigationBarFrame, new FrameLayout.LayoutParams(
+                            ViewGroup.LayoutParams.MATCH_PARENT, height, Gravity.BOTTOM));
                 }
                 final NavigationBarView navigationBarView = mNavigationBarFrame.findViewByPredicate(
                         NavigationBarView.class::isInstance);
@@ -461,7 +466,7 @@
             final Insets systemInsets = getSystemInsets();
             if (systemInsets != null) {
                 if (!Objects.equals(systemInsets, mLastInsets)) {
-                    mNavigationBarFrame.setLayoutParams(new NavigationBarFrame.LayoutParams(
+                    mNavigationBarFrame.setLayoutParams(new FrameLayout.LayoutParams(
                             ViewGroup.LayoutParams.MATCH_PARENT,
                             systemInsets.bottom, Gravity.BOTTOM));
                     mLastInsets = systemInsets;
diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java
index ee62dea..6b1e918 100644
--- a/core/java/android/os/Binder.java
+++ b/core/java/android/os/Binder.java
@@ -149,6 +149,11 @@
     private static volatile boolean sStackTrackingEnabled = false;
 
     /**
+     * The extension binder object
+     */
+    private IBinder mExtension = null;
+
+    /**
      * Enable Binder IPC stack tracking. If enabled, every binder transaction will be logged to
      * {@link TransactionTracker}.
      *
@@ -1237,7 +1242,9 @@
 
     /** @hide */
     @Override
-    public final native @Nullable IBinder getExtension();
+    public final @Nullable IBinder getExtension() {
+        return mExtension;
+    }
 
     /**
      * Set the binder extension.
@@ -1245,7 +1252,12 @@
      *
      * @hide
      */
-    public final native void setExtension(@Nullable IBinder extension);
+    public final void setExtension(@Nullable IBinder extension) {
+        mExtension = extension;
+        setExtensionNative(extension);
+    }
+
+    private final native void setExtensionNative(@Nullable IBinder extension);
 
     /**
      * Default implementation rewinds the parcels and calls onTransact. On
diff --git a/core/java/android/os/IpcDataCache.java b/core/java/android/os/IpcDataCache.java
index 2e7c3be..07a7f8b 100644
--- a/core/java/android/os/IpcDataCache.java
+++ b/core/java/android/os/IpcDataCache.java
@@ -718,7 +718,7 @@
     }
 
     /**
-     * Enable or disable testing.  The protocol requires that the mode toggle: for instance, it is
+     * Enable or disable test mode.  The protocol requires that the mode toggle: for instance, it is
      * illegal to clear the test mode if the test mode is already off.  Enabling test mode puts
      * all caches in the process into test mode; all nonces are initialized to UNSET and
      * subsequent reads and writes are to process memory.  This has the effect of disabling all
@@ -726,6 +726,7 @@
      * operation.
      * @param mode The desired test mode.
      * @throws IllegalStateException if the supplied mode is already set.
+     * @throws IllegalStateException if the process is not running an instrumentation test.
      * @hide
      */
     @TestApi
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 49d3f06..4a99285 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -20,6 +20,7 @@
 
 import static java.util.Objects.requireNonNull;
 
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -27,6 +28,7 @@
 import android.annotation.TestApi;
 import android.app.AppOpsManager;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Flags;
 import android.ravenwood.annotation.RavenwoodClassLoadHook;
 import android.ravenwood.annotation.RavenwoodKeepWholeClass;
 import android.ravenwood.annotation.RavenwoodReplace;
@@ -52,6 +54,8 @@
 import dalvik.annotation.optimization.CriticalNative;
 import dalvik.annotation.optimization.FastNative;
 
+import java.nio.BufferOverflowException;
+import java.nio.ReadOnlyBufferException;
 import libcore.util.SneakyThrow;
 
 import java.io.ByteArrayInputStream;
@@ -62,6 +66,7 @@
 import java.io.ObjectOutputStream;
 import java.io.ObjectStreamClass;
 import java.io.Serializable;
+import java.nio.ByteBuffer;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.lang.reflect.Array;
@@ -457,8 +462,15 @@
     private static native void nativeDestroy(long nativePtr);
 
     private static native byte[] nativeMarshall(long nativePtr);
+    private static native int nativeMarshallArray(
+            long nativePtr, byte[] data, int offset, int length);
+    private static native int nativeMarshallBuffer(
+            long nativePtr, ByteBuffer buffer, int offset, int length);
     private static native void nativeUnmarshall(
             long nativePtr, byte[] data, int offset, int length);
+    private static native void nativeUnmarshallBuffer(
+            long nativePtr, ByteBuffer buffer, int offset, int length);
+
     private static native int nativeCompareData(long thisNativePtr, long otherNativePtr);
     private static native boolean nativeCompareDataInRange(
             long ptrA, int offsetA, long ptrB, int offsetB, int length);
@@ -814,12 +826,78 @@
     }
 
     /**
+     * Writes the raw bytes of the parcel to a buffer.
+     *
+     * <p class="note">The data you retrieve here <strong>must not</strong>
+     * be placed in any kind of persistent storage (on local disk, across
+     * a network, etc).  For that, you should use standard serialization
+     * or another kind of general serialization mechanism.  The Parcel
+     * marshalled representation is highly optimized for local IPC, and as
+     * such does not attempt to maintain compatibility with data created
+     * in different versions of the platform.
+     *
+     * @param buffer The ByteBuffer to write the data to.
+     * @throws ReadOnlyBufferException if the buffer is read-only.
+     * @throws BufferOverflowException if the buffer is too small.
+     */
+    @FlaggedApi(Flags.FLAG_PARCEL_MARSHALL_BYTEBUFFER)
+    public final void marshall(@NonNull ByteBuffer buffer) {
+        if (buffer == null) {
+            throw new NullPointerException();
+        }
+        if (buffer.isReadOnly()) {
+            throw new ReadOnlyBufferException();
+        }
+
+        final int position = buffer.position();
+        final int remaining = buffer.remaining();
+
+        int marshalledSize = 0;
+        if (buffer.isDirect()) {
+            marshalledSize = nativeMarshallBuffer(mNativePtr, buffer, position, remaining);
+        } else if (buffer.hasArray()) {
+            marshalledSize = nativeMarshallArray(
+                    mNativePtr, buffer.array(), buffer.arrayOffset() + position, remaining);
+        } else {
+            throw new IllegalArgumentException();
+        }
+
+        buffer.position(position + marshalledSize);
+    }
+
+    /**
      * Fills the raw bytes of this Parcel with the supplied data.
      */
     public final void unmarshall(@NonNull byte[] data, int offset, int length) {
         nativeUnmarshall(mNativePtr, data, offset, length);
     }
 
+    /**
+     * Fills the raw bytes of this Parcel with data from the supplied buffer.
+     *
+     * @param buffer will read buffer.remaining() bytes from the buffer.
+     */
+    @FlaggedApi(Flags.FLAG_PARCEL_MARSHALL_BYTEBUFFER)
+    public final void unmarshall(@NonNull ByteBuffer buffer) {
+        if (buffer == null) {
+            throw new NullPointerException();
+        }
+
+        final int position = buffer.position();
+        final int remaining = buffer.remaining();
+
+        if (buffer.isDirect()) {
+            nativeUnmarshallBuffer(mNativePtr, buffer, position, remaining);
+        } else if (buffer.hasArray()) {
+            nativeUnmarshall(
+                    mNativePtr, buffer.array(), buffer.arrayOffset() + position, remaining);
+        } else {
+            throw new IllegalArgumentException();
+        }
+
+        buffer.position(position + remaining);
+    }
+
     public final void appendFrom(Parcel parcel, int offset, int length) {
         nativeAppendFrom(mNativePtr, parcel.mNativePtr, offset, length);
     }
diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig
index 86acb2b..0150d17 100644
--- a/core/java/android/os/flags.aconfig
+++ b/core/java/android/os/flags.aconfig
@@ -354,6 +354,15 @@
 
 flag {
      namespace: "system_performance"
+     name: "parcel_marshall_bytebuffer"
+     is_exported: true
+     description: "Parcel marshal/unmarshall APIs that use ByteBuffer."
+     is_fixed_read_only: true
+     bug: "401362825"
+}
+
+flag {
+     namespace: "system_performance"
      name: "perfetto_sdk_tracing"
      description: "Tracing using Perfetto SDK."
      bug: "303199244"
diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java
index 561a2c9..17033d1 100644
--- a/core/java/android/permission/PermissionManager.java
+++ b/core/java/android/permission/PermissionManager.java
@@ -1907,8 +1907,9 @@
     @Context.PermissionRequestState
     public int getPermissionRequestState(@NonNull String packageName, @NonNull String permission,
             int deviceId) {
+        int resolvedDeviceId = resolveDeviceIdForPermissionCheck(mContext, deviceId, permission);
         return sPermissionRequestStateCache.query(
-                new PermissionRequestStateQuery(packageName, permission, deviceId));
+                new PermissionRequestStateQuery(packageName, permission, resolvedDeviceId));
     }
 
     /**
@@ -2035,7 +2036,8 @@
      */
     public int checkPackageNamePermission(String permName, String pkgName,
             int deviceId, @UserIdInt int userId) {
-        String persistentDeviceId = getPersistentDeviceId(deviceId);
+        int resolvedDeviceId = resolveDeviceIdForPermissionCheck(mContext, deviceId, permName);
+        String persistentDeviceId = getPersistentDeviceId(resolvedDeviceId);
         return sPackageNamePermissionCache.query(
                 new PackageNamePermissionQuery(permName, pkgName, persistentDeviceId, userId));
     }
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5b708b3..b7e2962 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6484,6 +6484,14 @@
         public static final String SCREEN_FLASH_NOTIFICATION = "screen_flash_notification";
 
         /**
+         * Setting to enable CV (proprietary)
+         *
+         * @hide
+         */
+        public static final String CV_ENABLED =
+                "cv_enabled";
+
+        /**
          * Integer property that specifes the color for screen flash notification as a
          * packed 32-bit color.
          *
@@ -15514,7 +15522,8 @@
          * <ul>
          * <li><pre>secure</pre>: creates a secure display</li>
          * <li><pre>own_content_only</pre>: only shows this display's own content</li>
-         * <li><pre>should_show_system_decorations</pre>: supports system decorations</li>
+         * <li><pre>should_show_system_decorations</pre>: always shows system decorations</li>
+         * <li><pre>fixed_content_mode</pre>: does not allow the content mode switch</li>
          * </ul>
          * </p><p>
          * Example:
@@ -19806,6 +19815,14 @@
         public static final String REPAIR_MODE_ACTIVE = "repair_mode_active";
 
         /**
+         * Whether the notification manager service should redact notifications that contain otps
+         * from untrusted listeners. Defaults to 1/true.
+         * @hide
+         */
+        public static final String REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS =
+                "redact_otp_notifications_from_untrusted_listeners";
+
+        /**
          * Settings migrated from Wear OS settings provider.
          * @hide
          */
@@ -20815,6 +20832,24 @@
             @Readable
             public static final String WEAR_LAUNCHER_UI_MODE = "wear_launcher_ui_mode";
 
+            /**
+             * Setting indicating whether the primary gesture input action has been enabled by the
+             * user.
+             *
+             * @hide
+             */
+            public static final String GESTURE_PRIMARY_ACTION_USER_PREFERENCE =
+                    "gesture_primary_action_user_preference";
+
+            /**
+             * Setting indicating whether the dismiss gesture input action has been enabled by the
+             * user.
+             *
+             * @hide
+             */
+            public static final String GESTURE_DISMISS_ACTION_USER_PREFERENCE =
+                    "gesture_dismiss_action_user_preference";
+
             /** Whether Wear Power Anomaly Service is enabled.
              *
              * (0 = false, 1 = true)
diff --git a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
index 0b2239a..cb2b13d 100644
--- a/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
+++ b/core/java/android/security/advancedprotection/AdvancedProtectionManager.java
@@ -124,6 +124,18 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface FeatureId {}
 
+    /** @hide */
+    public static String featureIdToString(@FeatureId int featureId) {
+        return switch(featureId) {
+            case FEATURE_ID_DISALLOW_CELLULAR_2G -> "DISALLOW_CELLULAR_2G";
+            case FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES -> "DISALLOW_INSTALL_UNKNOWN_SOURCES";
+            case FEATURE_ID_DISALLOW_USB -> "DISALLOW_USB";
+            case FEATURE_ID_DISALLOW_WEP -> "DISALLOW_WEP";
+            case FEATURE_ID_ENABLE_MTE -> "ENABLE_MTE";
+            default -> "UNKNOWN";
+        };
+    }
+
     private static final Set<Integer> ALL_FEATURE_IDS = Set.of(
             FEATURE_ID_DISALLOW_CELLULAR_2G,
             FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES,
@@ -147,7 +159,7 @@
             "android.security.advancedprotection.action.SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG";
 
     /**
-     * A string extra used with {@link #createSupportIntent} to identify the feature that needs to
+     * An int extra used with {@link #createSupportIntent} to identify the feature that needs to
      * show a support dialog explaining it was disabled by advanced protection.
      *
      * @hide */
@@ -156,7 +168,7 @@
             "android.security.advancedprotection.extra.SUPPORT_DIALOG_FEATURE";
 
     /**
-     * A string extra used with {@link #createSupportIntent} to identify the type of the action that
+     * An int extra used with {@link #createSupportIntent} to identify the type of the action that
      * needs to be explained in the support dialog.
      *
      * @hide */
@@ -194,6 +206,16 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface SupportDialogType {}
 
+    /** @hide */
+    public static String supportDialogTypeToString(@SupportDialogType int type) {
+        return switch(type) {
+            case SUPPORT_DIALOG_TYPE_UNKNOWN -> "UNKNOWN";
+            case SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION -> "BLOCKED_INTERACTION";
+            case SUPPORT_DIALOG_TYPE_DISABLED_SETTING -> "DISABLED_SETTING";
+            default -> "UNKNOWN";
+        };
+    }
+
     private static final Set<Integer> ALL_SUPPORT_DIALOG_TYPES = Set.of(
             SUPPORT_DIALOG_TYPE_UNKNOWN,
             SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION,
@@ -327,7 +349,8 @@
      *
      * @param featureId The feature identifier.
      * @param type The type of the feature describing the action that needs to be explained
-     *                 in the dialog or null for default explanation.
+     *                 in the dialog or {@link #SUPPORT_DIALOG_TYPE_UNKNOWN} for default
+     *                 explanation.
      * @return Intent An intent to be used to start the dialog-activity that explains a feature was
      *                disabled by advanced protection.
      * @hide
@@ -351,7 +374,27 @@
         return intent;
     }
 
-    /** @hide */
+    /**
+     * Called by a feature to display a support dialog when a feature was disabled by advanced
+     * protection based on a policy identifier or restriction. This returns an intent that can be
+     * used with {@link Context#startActivity(Intent)} to display the dialog.
+     *
+     * <p>At the moment, if the dialog is for {@link #FEATURE_ID_DISALLOW_CELLULAR_2G} or
+     * {@link #FEATURE_ID_ENABLE_MTE} and the provided type is
+     * {@link #SUPPORT_DIALOG_TYPE_UNKNOWN}, the type will be changed to
+     * {@link #SUPPORT_DIALOG_TYPE_DISABLED_SETTING} in the returned intent, as these features only
+     * have a disabled setting UI.
+     *
+     * <p>Note that this method doesn't check if the feature is actually disabled, i.e. this method
+     * will always return an intent.
+     *
+     * @param identifier The policy identifier or restriction.
+     * @param type The type of the feature describing the action that needs to be explained
+     *                 in the dialog or {@link #SUPPORT_DIALOG_TYPE_UNKNOWN} for default
+     *                 explanation.
+     * @return Intent An intent to be used to start the dialog-activity that explains a feature was
+     *                disabled by advanced protection.
+     * @hide */
     public static @NonNull Intent createSupportIntentForPolicyIdentifierOrRestriction(
             @NonNull String identifier, @SupportDialogType int type) {
         Objects.requireNonNull(identifier);
@@ -360,16 +403,32 @@
                     + " SUPPORT_DIALOG_TYPE_* APIs.");
         }
         final int featureId;
+        int dialogType = type;
         if (DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY.equals(identifier)) {
             featureId = FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
         } else if (DISALLOW_CELLULAR_2G.equals(identifier)) {
             featureId = FEATURE_ID_DISALLOW_CELLULAR_2G;
+            dialogType = (dialogType == SUPPORT_DIALOG_TYPE_UNKNOWN)
+                    ? SUPPORT_DIALOG_TYPE_DISABLED_SETTING : dialogType;
         } else if (MEMORY_TAGGING_POLICY.equals(identifier)) {
             featureId = FEATURE_ID_ENABLE_MTE;
+            dialogType = (dialogType == SUPPORT_DIALOG_TYPE_UNKNOWN)
+                    ? SUPPORT_DIALOG_TYPE_DISABLED_SETTING : dialogType;
         } else {
             throw new UnsupportedOperationException("Unsupported identifier: " + identifier);
         }
-        return createSupportIntent(featureId, type);
+        return createSupportIntent(featureId, dialogType);
+    }
+
+    /** @hide */
+    @RequiresPermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
+    public void logDialogShown(@FeatureId int featureId, @SupportDialogType int type,
+            boolean learnMoreClicked) {
+        try {
+            mService.logDialogShown(featureId, type, learnMoreClicked);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
     }
 
     /**
diff --git a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
index 1939f82..0fc0fbe 100644
--- a/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
+++ b/core/java/android/security/advancedprotection/IAdvancedProtectionService.aidl
@@ -35,4 +35,6 @@
     void setAdvancedProtectionEnabled(boolean enabled);
     @EnforcePermission("MANAGE_ADVANCED_PROTECTION_MODE")
     List<AdvancedProtectionFeature> getAdvancedProtectionFeatures();
+    @EnforcePermission("MANAGE_ADVANCED_PROTECTION_MODE")
+    void logDialogShown(int featureId, int type, boolean learnMoreClicked);
 }
\ No newline at end of file
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 7013f7d..0a922d6 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -83,13 +83,6 @@
 }
 
 flag {
-    name: "report_primary_auth_attempts"
-    namespace: "biometrics"
-    description: "Report primary auth attempts from LockSettingsService"
-    bug: "285053096"
-}
-
-flag {
     name: "dump_attestation_verifications"
     namespace: "hardware_backed_security"
     description: "Add a dump capability for attestation_verification service"
@@ -104,10 +97,13 @@
 }
 
 flag {
-    name: "clear_strong_auth_on_add_primary_credential"
+    name: "clear_strong_auth_on_adding_primary_credential"
     namespace: "biometrics"
-    description: "Clear StrongAuth on add credential"
+    description: "Clear StrongAuth on adding credential"
     bug: "320817991"
+    metadata {
+      purpose: PURPOSE_BUGFIX
+    }
 }
 
 flag {
diff --git a/core/java/android/service/notification/NotificationRankingUpdate.java b/core/java/android/service/notification/NotificationRankingUpdate.java
index 7660ed9..815444d 100644
--- a/core/java/android/service/notification/NotificationRankingUpdate.java
+++ b/core/java/android/service/notification/NotificationRankingUpdate.java
@@ -219,7 +219,7 @@
                 // Gets a read/write buffer mapping the entire shared memory region.
                 buffer = mRankingMapFd.mapReadWrite();
                 // Puts the ranking map into the shared memory region buffer.
-                buffer.put(mapParcel.marshall(), 0, mapSize);
+                mapParcel.marshall(buffer);
                 // Protects the region from being written to, by setting it to be read-only.
                 mRankingMapFd.setProtect(OsConstants.PROT_READ);
                 // Puts the SharedMemory object in the parcel.
diff --git a/core/java/android/service/notification/TEST_MAPPING b/core/java/android/service/notification/TEST_MAPPING
index dc7129cd..ea7ee4a 100644
--- a/core/java/android/service/notification/TEST_MAPPING
+++ b/core/java/android/service/notification/TEST_MAPPING
@@ -4,7 +4,10 @@
       "name": "CtsNotificationTestCases_notification"
     },
     {
-      "name": "FrameworksUiServicesTests_notification"
+      "name": "FrameworksUiServicesNotificationTests"
+    },
+    {
+      "name": "FrameworksUiServicesZenTests"
     }
   ],
   "postsubmit": [
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index 1cf43d4..fce2df1 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -62,6 +62,7 @@
 import android.content.Context;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.ParceledListSlice;
 import android.content.res.Resources;
 import android.net.Uri;
 import android.os.Build;
@@ -460,14 +461,21 @@
     }
 
     private static void readRulesFromParcel(ArrayMap<String, ZenRule> ruleMap, Parcel source) {
-        final int len = source.readInt();
+        int len = source.readInt();
         if (len > 0) {
             final String[] ids = new String[len];
-            final ZenRule[] rules = new ZenRule[len];
-            source.readStringArray(ids);
-            source.readTypedArray(rules, ZenRule.CREATOR);
+            source.readString8Array(ids);
+            ParceledListSlice<?> parceledRules = source.readParcelable(
+                    ZenRule.class.getClassLoader(), ParceledListSlice.class);
+            List<?> rules = parceledRules != null ? parceledRules.getList() : new ArrayList<>();
+            if (rules.size() != len) {
+                Slog.wtf(TAG, String.format(
+                        "Unexpected parceled rules count (%s != %s), throwing them out",
+                        rules.size(), len));
+                len = 0;
+            }
             for (int i = 0; i < len; i++) {
-                ruleMap.put(ids[i], rules[i]);
+                ruleMap.put(ids[i], (ZenRule) rules.get(i));
             }
         }
     }
@@ -485,8 +493,8 @@
         }
         dest.writeInt(user);
         dest.writeParcelable(manualRule, 0);
-        writeRulesToParcel(automaticRules, dest);
-        writeRulesToParcel(deletedRules, dest);
+        writeRulesToParcel(automaticRules, dest, flags);
+        writeRulesToParcel(deletedRules, dest, flags);
         if (!Flags.modesUi()) {
             dest.writeInt(allowAlarms ? 1 : 0);
             dest.writeInt(allowMedia ? 1 : 0);
@@ -501,18 +509,19 @@
         }
     }
 
-    private static void writeRulesToParcel(ArrayMap<String, ZenRule> ruleMap, Parcel dest) {
+    private static void writeRulesToParcel(ArrayMap<String, ZenRule> ruleMap, Parcel dest,
+            int flags) {
         if (!ruleMap.isEmpty()) {
             final int len = ruleMap.size();
             final String[] ids = new String[len];
-            final ZenRule[] rules = new ZenRule[len];
+            final ArrayList<ZenRule> rules = new ArrayList<>();
             for (int i = 0; i < len; i++) {
                 ids[i] = ruleMap.keyAt(i);
-                rules[i] = ruleMap.valueAt(i);
+                rules.add(ruleMap.valueAt(i));
             }
             dest.writeInt(len);
-            dest.writeStringArray(ids);
-            dest.writeTypedArray(rules, 0);
+            dest.writeString8Array(ids);
+            dest.writeParcelable(new ParceledListSlice<>(rules), flags);
         } else {
             dest.writeInt(0);
         }
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
index 6ed8c6d..929e39f 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletClientImpl.java
@@ -421,7 +421,12 @@
         Intent intent = new Intent(SERVICE_INTERFACE);
         intent.setComponent(serviceInfo.getComponentName());
         int flags = Context.BIND_AUTO_CREATE | Context.BIND_WAIVE_PRIORITY;
-        mLifecycleExecutor.execute(() -> mContext.bindService(intent, this, flags));
+        if (mServiceInfo == null) {
+            mLifecycleExecutor.execute(() -> mContext.bindService(intent, this, flags));
+        } else {
+            mLifecycleExecutor.execute(() -> mContext.bindServiceAsUser(intent, this, flags,
+                    UserHandle.of(mServiceInfo.getUserId())));
+        }
         resetServiceConnectionTimeout();
     }
 
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 3f45e29..5c81654 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -286,7 +286,7 @@
     /**
      * Display flag: Indicates that the display should show system decorations.
      * <p>
-     * This flag identifies secondary displays that should show system decorations, such as
+     * This flag identifies secondary displays that should always show system decorations, such as
      * navigation bar, home activity or wallpaper.
      * </p>
      * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p>
@@ -401,6 +401,18 @@
     public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 14;
 
     /**
+     * Display flag: Indicates that the display is allowed to switch the content mode between
+     * projected/extended and mirroring. This allows the display to dynamically add or remove the
+     * home and system decorations.
+     *
+     * Note that this flag shouldn't be enabled with {@link #FLAG_PRIVATE} or
+     * {@link #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS} at the same time; otherwise it will be ignored.
+     *
+     * @hide
+     */
+    public static final int FLAG_ALLOWS_CONTENT_MODE_SWITCH = 1 << 15;
+
+    /**
      * Display flag: Indicates that the contents of the display should not be scaled
      * to fit the physical screen dimensions.  Used for development only to emulate
      * devices with smaller physicals screens while preserving density.
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
index d880072..bf000d5 100644
--- a/core/java/android/view/DisplayInfo.java
+++ b/core/java/android/view/DisplayInfo.java
@@ -1125,6 +1125,9 @@
         if ((flags & Display.FLAG_REAR) != 0) {
             result.append(", FLAG_REAR_DISPLAY");
         }
+        if ((flags & Display.FLAG_ALLOWS_CONTENT_MODE_SWITCH) != 0) {
+            result.append(", FLAG_ALLOWS_CONTENT_MODE_SWITCH");
+        }
         return result.toString();
     }
 }
diff --git a/core/java/android/view/ISurfaceControlViewHost.aidl b/core/java/android/view/ISurfaceControlViewHost.aidl
index fd4b329..83aceb3 100644
--- a/core/java/android/view/ISurfaceControlViewHost.aidl
+++ b/core/java/android/view/ISurfaceControlViewHost.aidl
@@ -21,6 +21,7 @@
 import android.view.InsetsState;
 import android.view.ISurfaceControlViewHostParent;
 import android.window.ISurfaceSyncGroup;
+import android.window.InputTransferToken;
 
 /**
  * API from content embedder back to embedded content in SurfaceControlViewHost
@@ -32,6 +33,7 @@
      * APIs that are blocking
      */
     oneway void onConfigurationChanged(in Configuration newConfig);
+    oneway void onDispatchAttachedToWindow(in InputTransferToken token);
     oneway void onDispatchDetachedFromWindow();
     oneway void onInsetsChanged(in InsetsState state, in Rect insetFrame);
     ISurfaceSyncGroup getSurfaceSyncGroup();
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 4fc894c..237d8f9 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -699,7 +699,7 @@
     /**
      * Indicates the display should show system decors.
      * <p>
-     * System decors include status bar, navigation bar, launcher.
+     * System decors include status bar, navigation bar, launcher, and wallpaper.
      * </p>
      *
      * @param displayId The id of the display.
@@ -719,6 +719,23 @@
     void setShouldShowSystemDecors(int displayId, boolean shouldShow);
 
     /**
+     * Indicates that the display is eligible for the desktop mode from WindowManager's perspective.
+     * This includes:
+     * - The default display;
+     * - Any display that is allowed to switch the content mode between extended and mirroring
+     * (which means it can dynamically add or remove system decors), and it is now in extended mode
+     * (should currently show system decors).
+     * <p>
+     * System decors include status bar, navigation bar, launcher, and wallpaper.
+     * </p>
+     *
+     * @param displayId The id of the display.
+     * @return {@code true} if the display is eligible for the desktop mode from WindowManager's
+     * perspective.
+     */
+    boolean isEligibleForDesktopMode(int displayId);
+
+    /**
      * Indicates the policy for how the display should show IME.
      *
      * @param displayId The id of the display.
@@ -792,7 +809,8 @@
      * Updates the currently animating insets types of a remote process.
      */
     @EnforcePermission("MANAGE_APP_TOKENS")
-    void updateDisplayWindowAnimatingTypes(int displayId, int animatingTypes);
+    void updateDisplayWindowAnimatingTypes(int displayId, int animatingTypes,
+            in @nullable ImeTracker.Token statsToken);
 
     /**
      * Called to get the expected window insets.
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 7d6d5a2..a029303 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -277,8 +277,10 @@
      *
      * @param window The window that is insets animaiton is running.
      * @param animatingTypes Indicates the currently animating insets types.
+     * @param imeStatsToken the token tracking the current IME request or {@code null} otherwise.
      */
-    oneway void updateAnimatingTypes(IWindow window, int animatingTypes);
+    oneway void updateAnimatingTypes(IWindow window, int animatingTypes,
+            in @nullable ImeTracker.Token imeStatsToken);
 
     /**
      * Called when the system gesture exclusion has changed.
@@ -311,8 +313,9 @@
     /**
      * Update the flags on an input channel associated with a particular surface.
      */
-    oneway void updateInputChannel(in IBinder channelToken, int displayId,
-            in SurfaceControl surface, int flags, int privateFlags, int inputFeatures,
+    oneway void updateInputChannel(in IBinder channelToken,
+            in @nullable InputTransferToken hostInputTransferToken,
+            int displayId, in SurfaceControl surface, int flags, int privateFlags, int inputFeatures,
             in Region region);
 
     /**
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index 394ac8f..7e9dfe6 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -215,8 +215,11 @@
          * contain all types, which have an ongoing animation.
          *
          * @param animatingTypes the {@link InsetsType}s that are currently animating
+         * @param statsToken the token tracking the current IME request or {@code null} otherwise.
          */
-        default void updateAnimatingTypes(@InsetsType int animatingTypes) {}
+        default void updateAnimatingTypes(@InsetsType int animatingTypes,
+                @Nullable ImeTracker.Token statsToken) {
+        }
 
         /** @see ViewRootImpl#isHandlingPointerEvent */
         default boolean isHandlingPointerEvent() {
@@ -748,7 +751,9 @@
                             mFrame, mFromState, mToState, RESIZE_INTERPOLATOR,
                             ANIMATION_DURATION_RESIZE, mTypes, InsetsController.this);
                     if (mRunningAnimations.isEmpty()) {
-                        mHost.updateAnimatingTypes(runner.getTypes());
+                        mHost.updateAnimatingTypes(runner.getTypes(),
+                                runner.getAnimationType() == ANIMATION_TYPE_HIDE
+                                        ? runner.getStatsToken() : null);
                     }
                     mRunningAnimations.add(new RunningAnimation(runner, runner.getAnimationType()));
                     mAnimatingTypes |= runner.getTypes();
@@ -1025,10 +1030,18 @@
                 handlePendingControlRequest(statsToken);
             } else {
                 if (showTypes[0] != 0) {
+                    if ((showTypes[0] & ime()) != 0) {
+                        ImeTracker.forLogging().onProgress(statsToken,
+                                ImeTracker.PHASE_CLIENT_ON_CONTROLS_CHANGED);
+                    }
                     applyAnimation(showTypes[0], true /* show */, false /* fromIme */,
                             false /* skipsCallbacks */, statsToken);
                 }
                 if (hideTypes[0] != 0) {
+                    if ((hideTypes[0] & ime()) != 0) {
+                        ImeTracker.forLogging().onProgress(statsToken,
+                                ImeTracker.PHASE_CLIENT_ON_CONTROLS_CHANGED);
+                    }
                     applyAnimation(hideTypes[0], false /* show */, false /* fromIme */,
                             // The animation of hiding transient types shouldn't be detected by the
                             // app. Otherwise, it might be able to react to the callbacks and cause
@@ -1036,6 +1049,10 @@
                             (hideTypes[0] & ~transientTypes[0]) == 0 /* skipsCallbacks */,
                             statsToken);
                 }
+                if ((showTypes[0] & ime()) == 0 && (hideTypes[0] & ime()) == 0) {
+                    ImeTracker.forLogging().onCancelled(statsToken,
+                            ImeTracker.PHASE_CLIENT_ON_CONTROLS_CHANGED);
+                }
             }
         } else {
             if (showTypes[0] != 0) {
@@ -1421,6 +1438,7 @@
             if (DEBUG) Log.d(TAG, "no types to animate in controlAnimationUnchecked");
             Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApi", 0);
             Trace.asyncTraceEnd(TRACE_TAG_VIEW, "IC.showRequestFromApiToImeReady", 0);
+            ImeTracker.forLogging().onFailed(statsToken, ImeTracker.PHASE_CLIENT_CONTROL_ANIMATION);
             return;
         }
         if (DEBUG) Log.d(TAG, "controlAnimation types: " + types);
@@ -1569,7 +1587,7 @@
         }
         ImeTracker.forLogging().onProgress(statsToken, ImeTracker.PHASE_CLIENT_ANIMATION_RUNNING);
         mAnimatingTypes |= runner.getTypes();
-        mHost.updateAnimatingTypes(mAnimatingTypes);
+        mHost.updateAnimatingTypes(mAnimatingTypes, null /* statsToken */);
         mRunningAnimations.add(new RunningAnimation(runner, animationType));
         if (DEBUG) Log.d(TAG, "Animation added to runner. useInsetsAnimationThread: "
                 + useInsetsAnimationThread);
@@ -1778,7 +1796,7 @@
                 ImeTracker.forLogging().onHidden(statsToken);
             }
         }
-        reportRequestedVisibleTypes(shown ? null : runner.getStatsToken());
+        reportRequestedVisibleTypes(null /* statsToken */);
     }
 
     @Override
@@ -1835,7 +1853,8 @@
                             if (mHost != null) {
                                 // if the (hide) animation is cancelled, the
                                 // requestedVisibleTypes should be reported at this point.
-                                reportRequestedVisibleTypes(control.getStatsToken());
+                                reportRequestedVisibleTypes(!Flags.reportAnimatingInsetsTypes()
+                                        ? control.getStatsToken() : null);
                                 mHost.getInputMethodManager().removeImeSurface(
                                         mHost.getWindowToken());
                             }
@@ -1847,7 +1866,13 @@
         }
         if (removedTypes > 0) {
             mAnimatingTypes &= ~removedTypes;
-            mHost.updateAnimatingTypes(mAnimatingTypes);
+            if (mHost != null) {
+                final boolean dispatchStatsToken =
+                        Flags.reportAnimatingInsetsTypes() && (removedTypes & ime()) != 0
+                                && control.getAnimationType() == ANIMATION_TYPE_HIDE;
+                mHost.updateAnimatingTypes(mAnimatingTypes,
+                        dispatchStatsToken ? control.getStatsToken() : null);
+            }
         }
 
         onAnimationStateChanged(removedTypes, false /* running */);
@@ -2003,6 +2028,11 @@
             if (Flags.refactorInsetsController()) {
                 ImeTracker.forLogging().onProgress(statsToken,
                         ImeTracker.PHASE_CLIENT_REPORT_REQUESTED_VISIBLE_TYPES);
+                if (Flags.reportAnimatingInsetsTypes() && (typesToReport & ime()) == 0) {
+                    // The IME hide animating flow should not be followed from here, but after
+                    // the hide animation has finished and Host.updateAnimatingTypes is called.
+                    statsToken = null;
+                }
             }
             mReportedRequestedVisibleTypes = mRequestedVisibleTypes;
             mHost.updateRequestedVisibleTypes(mReportedRequestedVisibleTypes, statsToken);
diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java
index 04ec4d0..ecbf1f6 100644
--- a/core/java/android/view/SurfaceControlViewHost.java
+++ b/core/java/android/view/SurfaceControlViewHost.java
@@ -79,6 +79,20 @@
         }
 
         @Override
+        public void onDispatchAttachedToWindow(InputTransferToken hostInputTransferToken) {
+            boolean hostInputTransferTokenChanged =
+                    !Objects.equals(hostInputTransferToken, mWm.mHostInputTransferToken);
+            if (!hostInputTransferTokenChanged) {
+                return;
+            }
+
+            mWm.setHostInputTransferToken(hostInputTransferToken);
+            if (mViewRoot != null && mViewRoot.mView != null) {
+                mWm.updateInputChannel(getWindowToken().asBinder());
+            }
+        }
+
+        @Override
         public void onDispatchDetachedFromWindow() {
             if (mViewRoot == null) {
                 return;
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 4f6c730..94e9aa7 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -16,6 +16,7 @@
 
 package android.view;
 
+
 import static android.view.flags.Flags.FLAG_DEPRECATE_SURFACE_VIEW_Z_ORDER_APIS;
 import static android.view.flags.Flags.FLAG_SURFACE_VIEW_GET_SURFACE_PACKAGE;
 import static android.view.flags.Flags.FLAG_SURFACE_VIEW_SET_COMPOSITION_ORDER;
@@ -23,6 +24,8 @@
 import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_OVERLAY_SUBLAYER;
 import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_SUBLAYER;
 import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAYER;
+import static android.view.flags.Flags.FLAG_SURFACE_VIEW_GET_SURFACE_PACKAGE;
+import static android.view.flags.Flags.FLAG_SURFACE_VIEW_SET_COMPOSITION_ORDER;
 
 import android.annotation.FlaggedApi;
 import android.annotation.FloatRange;
@@ -59,6 +62,7 @@
 import android.view.SurfaceControl.Transaction;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.IAccessibilityEmbeddedConnection;
+import android.window.InputTransferToken;
 import android.window.SurfaceSyncGroup;
 
 import com.android.graphics.hwui.flags.Flags;
@@ -347,7 +351,7 @@
                     sv.mSurfacePackage.getRemoteInterface().attachParentInterface(this);
                     mSurfaceView = sv;
                 } catch (RemoteException e) {
-                    Log.d(TAG, "Failed to attach parent interface to SCVH. Likely SCVH is alraedy "
+                    Log.d(TAG, "Failed to attach parent interface to SCVH. Likely SCVH is already "
                             + "dead.");
                 }
             }
@@ -492,10 +496,37 @@
         mTag = "SV[" + System.identityHashCode(this) + windowName + "]";
     }
 
+    private void dispatchScvhAttachedToHost() {
+        final ViewRootImpl viewRoot = getViewRootImpl();
+        if (viewRoot == null) {
+            return;
+        }
+
+        IBinder inputToken = viewRoot.getInputToken();
+        if (inputToken == null) {
+            // We don't have an input channel so we can't transfer focus or active
+            // touch gestures to embedded.
+            return;
+        }
+
+        try {
+            mSurfacePackage
+                    .getRemoteInterface()
+                    .onDispatchAttachedToWindow(new InputTransferToken(inputToken));
+        } catch (RemoteException e) {
+            Log.d(TAG,
+                    "Failed to onDispatchAttachedToWindow to SCVH. Likely SCVH is already "
+                            + "dead.");
+        }
+    }
+
     @Override
     protected void onAttachedToWindow() {
         super.onAttachedToWindow();
         setTag();
+        if (mSurfacePackage != null) {
+            dispatchScvhAttachedToHost();
+        }
         getViewRootImpl().addSurfaceChangedCallback(this);
         mWindowStopped = false;
         mViewVisibility = getVisibility() == VISIBLE;
@@ -1039,9 +1070,9 @@
             }
 
             if (mSurfacePackage != null) {
-                mSurfaceControlViewHostParent.detach();
                 mEmbeddedWindowParams.clear();
                 if (releaseSurfacePackage) {
+                    mSurfaceControlViewHostParent.detach();
                     mSurfacePackage.release();
                     mSurfacePackage = null;
                 }
@@ -2189,6 +2220,7 @@
             applyTransactionOnVriDraw(transaction);
         }
         mSurfacePackage = p;
+        dispatchScvhAttachedToHost();
         mSurfaceControlViewHostParent.attach(this);
 
         if (isFocused()) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f50d77e..f32ce6f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -34271,6 +34271,12 @@
                 frameRateToSet = velocityFrameRate;
             }
             viewRootImpl.votePreferredFrameRate(frameRateToSet, compatibility);
+
+            if (Trace.isTagEnabled(TRACE_TAG_VIEW)) {
+                Trace.instant(TRACE_TAG_VIEW,
+                        getClass().getSimpleName()
+                            + " - votePreferredFrameRate: " + frameRateToSet);
+            }
         }
 
         if (viewRootImpl.shouldCheckFrameRateCategory()) {
@@ -34306,6 +34312,13 @@
                                 | FRAME_RATE_CATEGORY_REASON_INVALID;
                     }
                 }
+
+                if (Trace.isTagEnabled(TRACE_TAG_VIEW)) {
+                    Trace.instant(TRACE_TAG_VIEW,
+                            getClass().getSimpleName() + " - votePreferredFrameRate: "
+                                + viewRootImpl.categoryToString(
+                                    frameRateCategory & ~FRAME_RATE_CATEGORY_REASON_MASK));
+                }
             } else {
                 // Category doesn't control it. It is directly controlled by frame rate
                 frameRateCategory = FRAME_RATE_CATEGORY_NO_PREFERENCE
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index da91e8d..4e3ff90 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -37,8 +37,8 @@
 import static android.view.Surface.FRAME_RATE_CATEGORY_LOW;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NORMAL;
 import static android.view.Surface.FRAME_RATE_CATEGORY_NO_PREFERENCE;
-import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
 import static android.view.Surface.FRAME_RATE_COMPATIBILITY_AT_LEAST;
+import static android.view.Surface.FRAME_RATE_COMPATIBILITY_FIXED_SOURCE;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_BOOST;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_CONFLICTED;
 import static android.view.View.FRAME_RATE_CATEGORY_REASON_INTERMITTENT;
@@ -555,8 +555,6 @@
     @UiContext
     public final Context mContext;
 
-    private UiModeManager mUiModeManager;
-
     @UnsupportedAppUsage
     final IWindowSession mWindowSession;
     @NonNull Display mDisplay;
@@ -2079,8 +2077,7 @@
                 // We also ignore dark theme, since the app developer can override the user's
                 // preference for dark mode in configuration.uiMode. Instead, we assume that both
                 // force invert and the system's dark theme are enabled.
-                if (getUiModeManager().getForceInvertState() ==
-                        UiModeManager.FORCE_INVERT_TYPE_DARK) {
+                if (shouldApplyForceInvertDark()) {
                     final boolean isLightTheme =
                         a.getBoolean(R.styleable.Theme_isLightTheme, false);
                     // TODO: b/372558459 - Also check the background ColorDrawable color lightness
@@ -2108,6 +2105,14 @@
         }
     }
 
+    private boolean shouldApplyForceInvertDark() {
+        final UiModeManager uiModeManager = mContext.getSystemService(UiModeManager.class);
+        if (uiModeManager == null) {
+            return false;
+        }
+        return uiModeManager.getForceInvertState() == UiModeManager.FORCE_INVERT_TYPE_DARK;
+    }
+
     private void updateForceDarkMode() {
         if (mAttachInfo.mThreadedRenderer == null) return;
         if (mAttachInfo.mThreadedRenderer.setForceDark(determineForceDarkType())) {
@@ -2550,9 +2555,11 @@
 
     /**
      * Notify the when the animating insets types have changed.
+     *
+     * @hide
      */
-    @VisibleForTesting
-    public void updateAnimatingTypes(@InsetsType int animatingTypes) {
+    public void updateAnimatingTypes(@InsetsType int animatingTypes,
+            @Nullable ImeTracker.Token statsToken) {
         if (sToolkitSetFrameRateReadOnlyFlagValue) {
             boolean running = animatingTypes != 0;
             if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
@@ -2562,7 +2569,7 @@
             }
             mInsetsAnimationRunning = running;
             try {
-                mWindowSession.updateAnimatingTypes(mWindow, animatingTypes);
+                mWindowSession.updateAnimatingTypes(mWindow, animatingTypes, statsToken);
             } catch (RemoteException e) {
             }
         }
@@ -2676,7 +2683,8 @@
             mStopped = stopped;
             final ThreadedRenderer renderer = mAttachInfo.mThreadedRenderer;
             if (renderer != null) {
-                if (DEBUG_DRAW) Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped);
+                if (DEBUG_DRAW)
+                    Log.d(mTag, "WindowStopped on " + getTitle() + " set to " + mStopped);
                 renderer.setStopped(mStopped);
             }
             if (!mStopped) {
@@ -9413,13 +9421,6 @@
         return mAudioManager;
     }
 
-    private UiModeManager getUiModeManager() {
-        if (mUiModeManager == null) {
-            mUiModeManager = mContext.getSystemService(UiModeManager.class);
-        }
-        return mUiModeManager;
-    }
-
     private Vibrator getSystemVibrator() {
         if (mVibrator == null) {
             mVibrator = mContext.getSystemService(Vibrator.class);
@@ -13218,7 +13219,7 @@
         }
     }
 
-    private static String categoryToString(int frameRateCategory) {
+    static String categoryToString(int frameRateCategory) {
         String category;
         switch (frameRateCategory) {
             case FRAME_RATE_CATEGORY_NO_PREFERENCE -> category = "no preference";
diff --git a/core/java/android/view/ViewRootInsetsControllerHost.java b/core/java/android/view/ViewRootInsetsControllerHost.java
index 8954df6..20fa77b 100644
--- a/core/java/android/view/ViewRootInsetsControllerHost.java
+++ b/core/java/android/view/ViewRootInsetsControllerHost.java
@@ -171,9 +171,15 @@
     }
 
     @Override
-    public void updateAnimatingTypes(@WindowInsets.Type.InsetsType int animatingTypes) {
+    public void updateAnimatingTypes(@WindowInsets.Type.InsetsType int animatingTypes,
+            @Nullable ImeTracker.Token statsToken) {
         if (mViewRoot != null) {
-            mViewRoot.updateAnimatingTypes(animatingTypes);
+            ImeTracker.forLogging().onProgress(statsToken,
+                    ImeTracker.PHASE_CLIENT_UPDATE_ANIMATING_TYPES);
+            mViewRoot.updateAnimatingTypes(animatingTypes, statsToken);
+        } else {
+            ImeTracker.forLogging().onFailed(statsToken,
+                    ImeTracker.PHASE_CLIENT_UPDATE_ANIMATING_TYPES);
         }
     }
 
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 3b444c4..fc66e49 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -16,6 +16,9 @@
 
 package android.view;
 
+import static android.view.flags.Flags.FLAG_ENABLE_DISPATCH_ON_SCROLL_CHANGED;
+
+import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
@@ -1258,8 +1261,9 @@
     /**
      * Notifies registered listeners that something has scrolled.
      */
+    @FlaggedApi(FLAG_ENABLE_DISPATCH_ON_SCROLL_CHANGED)
     @UnsupportedAppUsage
-    final void dispatchOnScrollChanged() {
+    public final void dispatchOnScrollChanged() {
         // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
         // perform the dispatching. The iterator is a safe guard against listeners that
         // could mutate the list by calling the various add/remove methods. This prevents
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 3953334..9097849 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -1840,6 +1840,16 @@
     @NonNull
     public abstract LayoutInflater getLayoutInflater();
 
+    /**
+     * Sets a user-facing title for the window.
+     * <p>
+     * This title may be shown to the user in the window's title or action bar
+     * if the {@link #requestFeature requested features} provide such a bar.
+     * It is also exposed through {@link
+     * android.view.accessibility.AccessibilityWindowInfo#getTitle}.
+     *
+     * @see WindowManager.LayoutParams#setTitle
+     */
     public abstract void setTitle(CharSequence title);
 
     @Deprecated
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 315f1ba..9d21f1a 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -5095,6 +5095,15 @@
             format = _format;
         }
 
+        /**
+         * Sets a title for the window.
+         * <p>
+         * This title will be used primarily for debugging, and may be exposed via {@link
+         * android.view.accessibility.AccessibilityWindowInfo#getTitle} if no {@link Window#setTitle
+         * user-facing title} has been set.
+         *
+         * @see Window#setTitle
+         */
         public final void setTitle(CharSequence title) {
             if (null == title)
                 title = "";
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index 0a86ff8..5af4abd 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -89,7 +89,7 @@
     protected final SurfaceControl mRootSurface;
     private final Configuration mConfiguration;
     private final IWindowSession mRealWm;
-    final InputTransferToken mHostInputTransferToken;
+    InputTransferToken mHostInputTransferToken;
     private final InputTransferToken mInputTransferToken = new InputTransferToken();
     private InsetsState mInsetsState;
     private final ClientWindowFrames mTmpFrames = new ClientWindowFrames();
@@ -128,9 +128,11 @@
         return null;
     }
 
-    /**
-     * Utility API.
-     */
+    void setHostInputTransferToken(InputTransferToken token) {
+        mHostInputTransferToken = token;
+    }
+
+    /** Utility API. */
     void setCompletionCallback(IBinder window, ResizeCompleteCallback callback) {
         if (mResizeCompletionForWindow.get(window) != null) {
             Log.w(TAG, "Unsupported overlapping resizes");
@@ -151,11 +153,25 @@
                 return;
             }
             state.mInputRegion = region != null ? new Region(region) : null;
+            updateInputChannel(window);
+        }
+    }
+
+    protected void updateInputChannel(IBinder window) {
+        State state;
+        synchronized (this) {
+            // Do everything while locked so that we synchronize with relayout. This should be a
+            // very infrequent operation.
+            state = mStateForWindow.get(window);
+            if (state == null) {
+                return;
+            }
             if (state.mInputChannelToken != null) {
                 try {
-                    mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
-                            state.mSurfaceControl, state.mParams.flags, state.mParams.privateFlags,
-                            state.mParams.inputFeatures, state.mInputRegion);
+                    mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken,
+                            state.mDisplayId, state.mSurfaceControl, state.mParams.flags,
+                            state.mParams.privateFlags, state.mParams.inputFeatures,
+                            state.mInputRegion);
                 } catch (RemoteException e) {
                     Log.e(TAG, "Failed to update surface input channel: ", e);
                 }
@@ -174,9 +190,7 @@
         }
     }
 
-    /**
-     * IWindowSession implementation.
-     */
+    /** IWindowSession implementation. */
     @Override
     public int addToDisplay(IWindow window, WindowManager.LayoutParams attrs,
             int viewVisibility, int displayId, @InsetsType int requestedVisibleTypes,
@@ -437,14 +451,15 @@
         if ((attrChanges & inputChangeMask) != 0 && state.mInputChannelToken != null) {
             try {
                 if (mRealWm instanceof IWindowSession.Stub) {
-                    mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
+                    mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken,
+                            state.mDisplayId,
                             new SurfaceControl(sc, "WindowlessWindowManager.relayout"),
                             attrs.flags, attrs.privateFlags, attrs.inputFeatures,
                             state.mInputRegion);
                 } else {
-                    mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, sc,
-                            attrs.flags, attrs.privateFlags, attrs.inputFeatures,
-                            state.mInputRegion);
+                    mRealWm.updateInputChannel(state.mInputChannelToken, mHostInputTransferToken,
+                            state.mDisplayId, sc, attrs.flags, attrs.privateFlags,
+                            attrs.inputFeatures, state.mInputRegion);
                 }
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to update surface input channel: ", e);
@@ -597,7 +612,8 @@
     }
 
     @Override
-    public void updateAnimatingTypes(IWindow window, @InsetsType int animatingTypes) {
+    public void updateAnimatingTypes(IWindow window, @InsetsType int animatingTypes,
+            @Nullable ImeTracker.Token statsToken) {
         // NO-OP
     }
 
@@ -623,8 +639,9 @@
     }
 
     @Override
-    public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
-            int flags, int privateFlags, int inputFeatures, Region region) {
+    public void updateInputChannel(IBinder channelToken, InputTransferToken hostInputToken,
+            int displayId, SurfaceControl surface, int flags, int privateFlags, int inputFeatures,
+            Region region) {
     }
 
     @Override
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index 7b6e070..c17002e 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -160,6 +160,9 @@
 
     /**
      * Gets the title of the window.
+     * <p>
+     * This is taken from the {@link android.view.Window}'s title, or its {@link
+     * android.view.WindowManager.LayoutParams} if that is unset.
      *
      * @return The title of the window, or {@code null} if none is available.
      */
diff --git a/core/java/android/view/flags/view_tree_observer_flags.aconfig b/core/java/android/view/flags/view_tree_observer_flags.aconfig
new file mode 100644
index 0000000..82f3300
--- /dev/null
+++ b/core/java/android/view/flags/view_tree_observer_flags.aconfig
@@ -0,0 +1,9 @@
+package: "android.view.flags"
+container: "system"
+
+flag {
+    name: "enable_dispatch_on_scroll_changed"
+    namespace: "toolkit"
+    description: "Feature flag for enabling the dispatchOnScrollChanged method in ViewTreeObserver."
+    bug: "238109286"
+}
\ No newline at end of file
diff --git a/core/java/android/view/inputmethod/ImeTracker.java b/core/java/android/view/inputmethod/ImeTracker.java
index 60178cd..b1ba8b3 100644
--- a/core/java/android/view/inputmethod/ImeTracker.java
+++ b/core/java/android/view/inputmethod/ImeTracker.java
@@ -226,6 +226,12 @@
             PHASE_WM_DISPLAY_IME_CONTROLLER_SET_IME_REQUESTED_VISIBLE,
             PHASE_WM_UPDATE_DISPLAY_WINDOW_REQUESTED_VISIBLE_TYPES,
             PHASE_WM_REQUESTED_VISIBLE_TYPES_NOT_CHANGED,
+            PHASE_CLIENT_UPDATE_ANIMATING_TYPES,
+            PHASE_WM_UPDATE_ANIMATING_TYPES,
+            PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED,
+            PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED,
+            PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES,
+            PHASE_CLIENT_ON_CONTROLS_CHANGED,
     })
     @Retention(RetentionPolicy.SOURCE)
     @interface Phase {}
@@ -449,6 +455,24 @@
     /** The requestedVisibleTypes have not been changed, so this request is not continued. */
     int PHASE_WM_REQUESTED_VISIBLE_TYPES_NOT_CHANGED =
             ImeProtoEnums.PHASE_WM_REQUESTED_VISIBLE_TYPES_NOT_CHANGED;
+    /** Updating the currently animating types on the client side. */
+    int PHASE_CLIENT_UPDATE_ANIMATING_TYPES =
+            ImeProtoEnums.PHASE_CLIENT_UPDATE_ANIMATING_TYPES;
+    /** Updating the animating types in the WindowState on the WindowManager side. */
+    int PHASE_WM_UPDATE_ANIMATING_TYPES =
+            ImeProtoEnums.PHASE_WM_UPDATE_ANIMATING_TYPES;
+    /** Animating types of the WindowState have changed, now sending them to state controller. */
+    int PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED =
+            ImeProtoEnums.PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED;
+    /** ImeInsetsSourceProvider got notified that the hide animation is finished. */
+    int PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED =
+            ImeProtoEnums.PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED;
+    /** The control target reported its animatingTypes back to WindowManagerService. */
+    int PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES =
+            ImeProtoEnums.PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES;
+    /** InsetsController received a control for the IME. */
+    int PHASE_CLIENT_ON_CONTROLS_CHANGED =
+            ImeProtoEnums.PHASE_CLIENT_ON_CONTROLS_CHANGED;
 
     /**
      * Called when an IME request is started.
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index a41ab36..b3bd89c 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -2454,6 +2454,7 @@
                                 & WindowInsets.Type.ime()) == 0
                         || viewRootImpl.getInsetsController()
                                 .isPredictiveBackImeHideAnimInProgress())) {
+                    Handler vh = view.getHandler();
                     ImeTracker.forLogging().onProgress(statsToken,
                             ImeTracker.PHASE_CLIENT_NO_ONGOING_USER_ANIMATION);
                     if (resultReceiver != null) {
@@ -2464,8 +2465,17 @@
                                         : InputMethodManager.RESULT_SHOWN, null);
                     }
                     // TODO(b/322992891) handle case of SHOW_IMPLICIT
-                    viewRootImpl.getInsetsController().show(WindowInsets.Type.ime(),
-                            false /* fromIme */, statsToken);
+                    if (vh.getLooper() != Looper.myLooper()) {
+                        // The view is running on a different thread than our own, so
+                        // we need to reschedule our work for over there.
+                        if (DEBUG) Log.v(TAG, "Show soft input: reschedule to view thread");
+                        final var finalStatsToken = statsToken;
+                        vh.post(() -> viewRootImpl.getInsetsController().show(
+                                WindowInsets.Type.ime(), false /* fromIme */, finalStatsToken));
+                    } else {
+                        viewRootImpl.getInsetsController().show(WindowInsets.Type.ime(),
+                                false /* fromIme */, statsToken);
+                    }
                     return true;
                 }
                 ImeTracker.forLogging().onCancelled(statsToken,
diff --git a/core/java/android/view/inputmethod/flags.aconfig b/core/java/android/view/inputmethod/flags.aconfig
index 67e5442..cdca410 100644
--- a/core/java/android/view/inputmethod/flags.aconfig
+++ b/core/java/android/view/inputmethod/flags.aconfig
@@ -224,3 +224,14 @@
     purpose: PURPOSE_BUGFIX
   }
 }
+
+flag {
+    name: "disallow_disabling_ime_navigation_bar"
+    namespace: "input_method"
+    description: "Disallows disabling the IME navigation bar through canImeRenderGesturalNavButtons"
+    bug: "402442590"
+    is_fixed_read_only: true
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index ab7a4f2..ed3f2d1 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1789,17 +1789,4 @@
      * @see #setDisabledActionModeMenuItems
      */
     public static final int MENU_ITEM_PROCESS_TEXT = 1 << 2;
-
-    /**
-     * Enable CHIPS for webview.
-     * This provides a means to check if partitioned cookies are enabled by default.
-     * CHIPS will only be enabled by default for apps targeting Android B or above.
-     *
-     * @hide
-     */
-    @ChangeId
-    @EnabledAfter(targetSdkVersion = android.os.Build.VERSION_CODES.VANILLA_ICE_CREAM)
-    @FlaggedApi(android.webkit.Flags.FLAG_ENABLE_CHIPS)
-    @SystemApi
-    public static final long ENABLE_CHIPS = 380890146L;
 }
diff --git a/core/java/android/webkit/flags.aconfig b/core/java/android/webkit/flags.aconfig
index 16cbb8a..c5176a2 100644
--- a/core/java/android/webkit/flags.aconfig
+++ b/core/java/android/webkit/flags.aconfig
@@ -36,14 +36,6 @@
 }
 
 flag {
-    name: "enable_chips"
-    is_exported: true
-    namespace: "webview"
-    description: "New feature enable CHIPS for webview"
-    bug: "359448044"
-}
-
-flag {
     name: "file_system_access"
     is_exported: true
     namespace: "webview"
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index 222a7b3..3dfbc25 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -9216,7 +9216,13 @@
         public static RemoteResponse fromFillInIntent(@NonNull Intent fillIntent) {
             RemoteResponse response = new RemoteResponse();
             response.mFillIntent = fillIntent;
-            fillIntent.collectExtraIntentKeys();
+            if (fillIntent != null) {
+                // Although the parameter is marked as @NonNull, it is nullable. The method that
+                // calls it (RemoteReviews.setOnClickFillInIntent()) passes its fillInIntent
+                // parameter to this method and it does not guarantee that the fillInIntent is
+                // non-null.
+                fillIntent.collectExtraIntentKeys();
+            }
             return response;
         }
 
diff --git a/core/java/android/window/DesktopExperienceFlags.java b/core/java/android/window/DesktopExperienceFlags.java
index 866c16c..5e8ce5e 100644
--- a/core/java/android/window/DesktopExperienceFlags.java
+++ b/core/java/android/window/DesktopExperienceFlags.java
@@ -56,9 +56,13 @@
     ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT(
             com.android.server.display.feature.flags.Flags::enableDisplayContentModeManagement,
             true),
+    ENABLE_DISPLAY_DISCONNECT_INTERACTION(Flags::enableDisplayDisconnectInteraction, false),
     ENABLE_DISPLAY_FOCUS_IN_SHELL_TRANSITIONS(Flags::enableDisplayFocusInShellTransitions, true),
+    ENABLE_DISPLAY_RECONNECT_INTERACTION(Flags::enableDisplayReconnectInteraction, false),
     ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING(Flags::enableDisplayWindowingModeSwitching, true),
     ENABLE_DRAG_TO_MAXIMIZE(Flags::enableDragToMaximize, true),
+    ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX(Flags::enableDynamicRadiusComputationBugfix, false),
+    ENABLE_KEYBOARD_SHORTCUTS_TO_SWITCH_DESKS(Flags::keyboardShortcutsToSwitchDesks, false),
     ENABLE_MOVE_TO_NEXT_DISPLAY_SHORTCUT(Flags::enableMoveToNextDisplayShortcut, true),
     ENABLE_MULTIPLE_DESKTOPS_BACKEND(Flags::enableMultipleDesktopsBackend, false),
     ENABLE_MULTIPLE_DESKTOPS_FRONTEND(Flags::enableMultipleDesktopsFrontend, false),
diff --git a/core/java/android/window/DesktopModeFlags.java b/core/java/android/window/DesktopModeFlags.java
index aecf6eb..703274d 100644
--- a/core/java/android/window/DesktopModeFlags.java
+++ b/core/java/android/window/DesktopModeFlags.java
@@ -111,7 +111,7 @@
     ENABLE_HOLD_TO_DRAG_APP_HANDLE(Flags::enableHoldToDragAppHandle, true),
     ENABLE_INPUT_LAYER_TRANSITION_FIX(Flags::enableInputLayerTransitionFix, false),
     ENABLE_MINIMIZE_BUTTON(Flags::enableMinimizeButton, true),
-    ENABLE_MODALS_FULLSCREEN_WITH_PERMISSIONS(Flags::enableModalsFullscreenWithPermission, false),
+    ENABLE_MODALS_FULLSCREEN_WITH_PERMISSIONS(Flags::enableModalsFullscreenWithPermission, true),
     ENABLE_OPAQUE_BACKGROUND_FOR_TRANSPARENT_WINDOWS(
             Flags::enableOpaqueBackgroundForTransparentWindows, true),
     ENABLE_QUICKSWITCH_DESKTOP_SPLIT_BUGFIX(Flags::enableQuickswitchDesktopSplitBugfix, true),
@@ -137,7 +137,7 @@
     ENABLE_WINDOWING_SCALED_RESIZING(Flags::enableWindowingScaledResizing, true),
     ENABLE_WINDOWING_TRANSITION_HANDLERS_OBSERVERS(
             Flags::enableWindowingTransitionHandlersObservers, false),
-    EXCLUDE_CAPTION_FROM_APP_BOUNDS(Flags::excludeCaptionFromAppBounds, false),
+    EXCLUDE_CAPTION_FROM_APP_BOUNDS(Flags::excludeCaptionFromAppBounds, true),
     FORCE_CLOSE_TOP_TRANSPARENT_FULLSCREEN_TASK(
             Flags::forceCloseTopTransparentFullscreenTask, false),
     IGNORE_ASPECT_RATIO_RESTRICTIONS_FOR_RESIZEABLE_FREEFORM_ACTIVITIES(
@@ -146,6 +146,8 @@
             Flags::includeTopTransparentFullscreenTaskInDesktopHeuristic, true),
     INHERIT_TASK_BOUNDS_FOR_TRAMPOLINE_TASK_LAUNCHES(
             Flags::inheritTaskBoundsForTrampolineTaskLaunches, false),
+    SKIP_DECOR_VIEW_RELAYOUT_WHEN_CLOSING_BUGFIX(
+            Flags::skipDecorViewRelayoutWhenClosingBugfix, false),
     // go/keep-sorted end
     ;
 
diff --git a/core/java/android/window/IWindowOrganizerController.aidl b/core/java/android/window/IWindowOrganizerController.aidl
index 6f4dd4e..0b84070 100644
--- a/core/java/android/window/IWindowOrganizerController.aidl
+++ b/core/java/android/window/IWindowOrganizerController.aidl
@@ -66,17 +66,6 @@
     void startTransition(IBinder transitionToken, in @nullable WindowContainerTransaction t);
 
     /**
-     * Starts a legacy transition.
-     * @param type The transition type.
-     * @param adapter The animation to use.
-     * @param syncCallback A sync callback for the contents of `t`
-     * @param t Operations that are part of the transition.
-     * @return sync-id or -1 if this no-op'd because a transition is already running.
-     */
-    int startLegacyTransition(int type, in RemoteAnimationAdapter adapter,
-            in IWindowContainerTransactionCallback syncCallback, in WindowContainerTransaction t);
-
-    /**
      * Finishes a transition. This must be called for all created transitions.
      * @param transitionToken Which transition to finish
      * @param t Changes to make before finishing but in the same SF Transaction. Can be null.
diff --git a/core/java/android/window/WindowContainerTransaction.java b/core/java/android/window/WindowContainerTransaction.java
index 2ed9c3a..8f7f941 100644
--- a/core/java/android/window/WindowContainerTransaction.java
+++ b/core/java/android/window/WindowContainerTransaction.java
@@ -16,6 +16,7 @@
 
 package android.window;
 
+import static android.app.Instrumentation.DEBUG_START_ACTIVITY;
 import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
 import static android.window.TaskFragmentOperation.OP_TYPE_CLEAR_ADJACENT_TASK_FRAGMENTS;
 import static android.window.TaskFragmentOperation.OP_TYPE_CREATE_TASK_FRAGMENT;
@@ -32,6 +33,7 @@
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.TestApi;
+import android.app.Instrumentation;
 import android.app.PendingIntent;
 import android.app.WindowConfiguration;
 import android.app.WindowConfiguration.WindowingMode;
@@ -45,6 +47,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.ArrayMap;
+import android.util.Log;
 import android.view.InsetsFrameProvider;
 import android.view.InsetsSource;
 import android.view.SurfaceControl;
@@ -642,6 +645,10 @@
      */
     @NonNull
     public WindowContainerTransaction startTask(int taskId, @Nullable Bundle options) {
+        if (DEBUG_START_ACTIVITY) {
+            Log.d(Instrumentation.TAG, "WCT.startTask: taskId=" + taskId
+                    + " options=" + options, new Throwable());
+        }
         mHierarchyOps.add(HierarchyOp.createForTaskLaunch(taskId, options));
         return this;
     }
@@ -655,11 +662,15 @@
      */
     @NonNull
     public WindowContainerTransaction sendPendingIntent(@Nullable PendingIntent sender,
-            @Nullable Intent intent, @Nullable Bundle options) {
+            @Nullable Intent fillInIntent, @Nullable Bundle options) {
+        if (DEBUG_START_ACTIVITY) {
+            Log.d(Instrumentation.TAG, "WCT.sendPendingIntent: sender=" + sender.getIntent()
+                    + " fillInIntent=" + fillInIntent + " options=" + options, new Throwable());
+        }
         mHierarchyOps.add(new HierarchyOp.Builder(HierarchyOp.HIERARCHY_OP_TYPE_PENDING_INTENT)
                 .setLaunchOptions(options)
                 .setPendingIntent(sender)
-                .setActivityIntent(intent)
+                .setActivityIntent(fillInIntent)
                 .build());
         return this;
     }
@@ -674,6 +685,10 @@
     @NonNull
     public WindowContainerTransaction startShortcut(@NonNull String callingPackage,
             @NonNull ShortcutInfo shortcutInfo, @Nullable Bundle options) {
+        if (DEBUG_START_ACTIVITY) {
+            Log.d(Instrumentation.TAG, "WCT.startShortcut: shortcutInfo=" + shortcutInfo
+                    + " options=" + options, new Throwable());
+        }
         mHierarchyOps.add(HierarchyOp.createForStartShortcut(
                 callingPackage, shortcutInfo, options));
         return this;
diff --git a/core/java/android/window/WindowOrganizer.java b/core/java/android/window/WindowOrganizer.java
index 5c5da49..6e56b63 100644
--- a/core/java/android/window/WindowOrganizer.java
+++ b/core/java/android/window/WindowOrganizer.java
@@ -130,27 +130,6 @@
     }
 
     /**
-     * Start a legacy transition.
-     * @param type The type of the transition. This is ignored if a transitionToken is provided.
-     * @param adapter An existing transition to start. If null, a new transition is created.
-     * @param t The set of window operations that are part of this transition.
-     * @return true on success, false if a transition was already running.
-     * @hide
-     */
-    @RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
-    @NonNull
-    public int startLegacyTransition(int type, @NonNull RemoteAnimationAdapter adapter,
-            @NonNull WindowContainerTransactionCallback syncCallback,
-            @NonNull WindowContainerTransaction t) {
-        try {
-            return getWindowOrganizerController().startLegacyTransition(
-                    type, adapter, syncCallback.mInterface, t);
-        } catch (RemoteException e) {
-            throw e.rethrowFromSystemServer();
-        }
-    }
-
-    /**
      * Register an ITransitionPlayer to handle transition animations.
      * @hide
      */
diff --git a/core/java/android/window/flags/lse_desktop_experience.aconfig b/core/java/android/window/flags/lse_desktop_experience.aconfig
index e706af9..e4142a1 100644
--- a/core/java/android/window/flags/lse_desktop_experience.aconfig
+++ b/core/java/android/window/flags/lse_desktop_experience.aconfig
@@ -595,6 +595,13 @@
 }
 
 flag {
+    name: "nested_tasks_with_independent_bounds"
+    namespace: "lse_desktop_experience"
+    description: "Allows tasks under a root task to be have independent (non-inherited) bounds"
+    bug: "402825303"
+}
+
+flag {
     name: "enable_multiple_desktops_backend"
     namespace: "lse_desktop_experience"
     description: "Enable multiple desktop sessions for desktop windowing (backend)."
@@ -602,6 +609,13 @@
 }
 
 flag {
+    name: "keyboard_shortcuts_to_switch_desks"
+    namespace: "lse_desktop_experience"
+    description: "Enable switching the active desk with keyboard shortcuts"
+    bug: "389957556"
+}
+
+flag {
     name: "enable_connected_displays_dnd"
     namespace: "lse_desktop_experience"
     description: "Enable drag-and-drop between connected displays."
@@ -926,6 +940,16 @@
 }
 
 flag {
+    name: "skip_decor_view_relayout_when_closing_bugfix"
+    namespace: "lse_desktop_experience"
+    description: "Enables bugfix to skip DecorView relayout when the corresponding window is closing."
+    bug: "394502142"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
     name: "enable_size_compat_mode_improvements_for_connected_displays"
     namespace: "lse_desktop_experience"
     description: "Enable some improvements in size compat mode for connected displays."
@@ -945,3 +969,20 @@
     description: "Enable restart menu UI, which is shown when an app moves between displays."
     bug: "397804287"
 }
+
+flag {
+    name: "enable_dynamic_radius_computation_bugfix"
+    namespace: "lse_desktop_experience"
+    description: "Enables bugfix to compute the corner/shadow radius of desktop windows dynamically with the current window context."
+    bug: "399630464"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    name: "show_home_behind_desktop"
+    namespace: "lse_desktop_experience"
+    description: "Enables the home to be shown behind the desktop."
+    bug: "375644149"
+}
diff --git a/core/java/android/window/flags/window_surfaces.aconfig b/core/java/android/window/flags/window_surfaces.aconfig
index d866b0e..756288b 100644
--- a/core/java/android/window/flags/window_surfaces.aconfig
+++ b/core/java/android/window/flags/window_surfaces.aconfig
@@ -118,3 +118,15 @@
         purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "update_host_input_transfer_token"
+    namespace: "window_surfaces"
+    description: "Update host InpuTransferToken on view attach"
+    is_fixed_read_only: true
+    is_exported: true
+    bug: "392965431"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
\ No newline at end of file
diff --git a/core/java/android/window/flags/windowing_frontend.aconfig b/core/java/android/window/flags/windowing_frontend.aconfig
index 8162702..8dd0457 100644
--- a/core/java/android/window/flags/windowing_frontend.aconfig
+++ b/core/java/android/window/flags/windowing_frontend.aconfig
@@ -287,6 +287,17 @@
 }
 
 flag {
+  name: "use_visible_requested_for_process_tracker"
+  namespace: "windowing_frontend"
+  description: "Do not count closing activity as visible process"
+  bug: "396653764"
+  is_fixed_read_only: true
+  metadata {
+    purpose: PURPOSE_BUGFIX
+  }
+}
+
+flag {
   name: "ensure_wallpaper_in_transitions"
   namespace: "windowing_frontend"
   description: "Ensure that wallpaper window tokens are always present/available for collection in transitions"
diff --git a/core/java/com/android/internal/app/ChooserGridLayoutManager.java b/core/java/com/android/internal/app/ChooserGridLayoutManager.java
index 69d2abc..6eb5e74 100644
--- a/core/java/com/android/internal/app/ChooserGridLayoutManager.java
+++ b/core/java/com/android/internal/app/ChooserGridLayoutManager.java
@@ -25,7 +25,7 @@
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityNodeInfo;
 import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
-import android.widget.GridView;
+import android.widget.ListView;
 import android.widget.TextView;
 
 import com.android.internal.R;
@@ -131,7 +131,7 @@
         super.onInitializeAccessibilityNodeInfoForItem(recycler, state, host, info);
         if (announceShortcutsAndSuggestedAppsLegacy() && host instanceof ViewGroup) {
             if (host.getId() == R.id.shortcuts_container) {
-                info.setClassName(GridView.class.getName());
+                info.setClassName(ListView.class.getName());
                 info.setContainerTitle(mShortcutGroupTitle);
                 info.setCollectionInfo(createShortcutsA11yCollectionInfo((ViewGroup) host));
             } else if (host.getId() == R.id.chooser_row) {
@@ -140,7 +140,7 @@
                 ChooserListAdapter gridAdapter = adapter instanceof ChooserGridAdapter
                         ? ((ChooserGridAdapter) adapter).getListAdapter()
                         : null;
-                info.setClassName(GridView.class.getName());
+                info.setClassName(ListView.class.getName());
                 info.setCollectionInfo(createSuggestedAppsA11yCollectionInfo((ViewGroup) host));
                 if (gridAdapter == null || gridAdapter.getAlphaTargetCount() > 0) {
                     info.setContainerTitle(mSuggestedAppsGroupTitle);
diff --git a/core/java/com/android/internal/jank/Cuj.java b/core/java/com/android/internal/jank/Cuj.java
index 41e2ca9..c25f6b1 100644
--- a/core/java/com/android/internal/jank/Cuj.java
+++ b/core/java/com/android/internal/jank/Cuj.java
@@ -313,8 +313,27 @@
      */
     public static final int CUJ_DEFAULT_TASK_TO_TASK_ANIMATION = 128;
 
+    /**
+     * Track moving a window to another display in Desktop Windowing mode.
+     *
+     * <p>Tracking starts when the DesktopModeMoveToDisplayTransitionHandler starts animating the
+     * task to move it to another display. This is triggered when the user presses a keyboard
+     * shortcut or clicks the menu in the overview. Tracking ends when the animation completes.</p>
+     */
+    public static final int CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY = 129;
+
+    /**
+     * Track the animation of an ongoing call app back into its status bar chip (displaying the call
+     * icon and timer) when returning Home.
+     *
+     * <p>Tracking starts when the RemoteTransition registered to handle the transition from the app
+     * to Home is sent the onAnimationStart() signal and start the animation. Tracking ends when
+     * the animation is fully settled and the transition is complete.</p>
+     */
+    public static final int CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP = 130;
+
     // When adding a CUJ, update this and make sure to also update CUJ_TO_STATSD_INTERACTION_TYPE.
-    @VisibleForTesting static final int LAST_CUJ = CUJ_DEFAULT_TASK_TO_TASK_ANIMATION;
+    @VisibleForTesting static final int LAST_CUJ = CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP;
 
     /** @hide */
     @IntDef({
@@ -434,7 +453,9 @@
             CUJ_DESKTOP_MODE_KEYBOARD_QUICK_SWITCH_APP_LAUNCH,
             CUJ_LAUNCHER_WORK_UTILITY_VIEW_EXPAND,
             CUJ_LAUNCHER_WORK_UTILITY_VIEW_SHRINK,
-            CUJ_DEFAULT_TASK_TO_TASK_ANIMATION
+            CUJ_DEFAULT_TASK_TO_TASK_ANIMATION,
+            CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY,
+            CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface CujType {}
@@ -565,6 +586,8 @@
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WORK_UTILITY_VIEW_EXPAND] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WORK_UTILITY_VIEW_EXPAND;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_LAUNCHER_WORK_UTILITY_VIEW_SHRINK] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__LAUNCHER_WORK_UTILITY_VIEW_SHRINK;
         CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DEFAULT_TASK_TO_TASK_ANIMATION] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DEFAULT_TASK_TO_TASK_ANIMATION;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY;
+        CUJ_TO_STATSD_INTERACTION_TYPE[CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP] = FrameworkStatsLog.UIINTERACTION_FRAME_INFO_REPORTED__INTERACTION_TYPE__STATUS_BAR_APP_RETURN_TO_CALL_CHIP;
     }
 
     private Cuj() {
@@ -817,6 +840,10 @@
                 return "LAUNCHER_WORK_UTILITY_VIEW_SHRINK";
             case CUJ_DEFAULT_TASK_TO_TASK_ANIMATION:
                 return "DEFAULT_TASK_TO_TASK_ANIMATION";
+            case CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY:
+                return "DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY";
+            case CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP:
+                return "STATUS_BAR_APP_RETURN_TO_CALL_CHIP";
         }
         return "UNKNOWN";
     }
diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java
index c6207f9..f1c47a7 100644
--- a/core/java/com/android/internal/os/BatteryStatsHistory.java
+++ b/core/java/com/android/internal/os/BatteryStatsHistory.java
@@ -672,6 +672,7 @@
      */
     public void reset() {
         synchronized (this) {
+            mMonotonicHistorySize = 0;
             initHistoryBuffer();
             if (mStore != null) {
                 mStore.reset();
@@ -759,9 +760,20 @@
                     break;
                 }
 
-                if (fragment.monotonicTimeMs >= startTimeMs && fragment != mActiveFragment) {
-                    containers.add(new BatteryHistoryParcelContainer(fragment));
+                if (fragment.monotonicTimeMs >= mHistoryBufferStartTime) {
+                    // Do not include the backup of the current buffer, which is explicitly
+                    // included later
+                    continue;
                 }
+
+                if (i < fragments.size() - 1
+                        && fragments.get(i + 1).monotonicTimeMs < startTimeMs) {
+                    // Since fragments are ordered, an early start of next fragment implies an
+                    // early end for this one.
+                    continue;
+                }
+
+                containers.add(new BatteryHistoryParcelContainer(fragment));
             }
         }
 
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index 33794a5..ac2c51c 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -24,6 +24,7 @@
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_CHECK_CREDENTIAL_UNLOCKED;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU;
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_EXPAND_PANEL;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FACE_WAKE_AND_UNLOCK;
 import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_FINGERPRINT_WAKE_AND_UNLOCK;
@@ -290,6 +291,16 @@
      */
     public static final int ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU = 31;
 
+    /**
+     * Time it takes for the "exit desktop" mode animation to begin after the user provides input.
+     * <p>
+     * Starts when the user provides input to exit desktop mode and enter full screen mode for an
+     * app. This including selecting the full screen button in an app handle's menu, dragging an
+     * app's window handle to the top of the screen, and using the appropriate keyboard shortcut.
+     * Ends when the animation to exit desktop mode begins.
+     */
+    public static final int ACTION_DESKTOP_MODE_EXIT_MODE = 32;
+
     private static final int[] ACTIONS_ALL = {
         ACTION_EXPAND_PANEL,
         ACTION_TOGGLE_RECENTS,
@@ -323,6 +334,7 @@
         ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
         ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
         ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU,
+        ACTION_DESKTOP_MODE_EXIT_MODE,
     };
 
     /** @hide */
@@ -359,6 +371,7 @@
         ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
         ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
         ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU,
+        ACTION_DESKTOP_MODE_EXIT_MODE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface Action {}
@@ -397,6 +410,7 @@
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHADE_WINDOW_DISPLAY_CHANGE,
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG,
             UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU,
+            UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE,
     };
 
     private final Object mLock = new Object();
@@ -601,6 +615,8 @@
                 return "ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_DRAG";
             case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU:
                 return "ACTION_DESKTOP_MODE_ENTER_APP_HANDLE_MENU";
+            case UIACTION_LATENCY_REPORTED__ACTION__ACTION_DESKTOP_MODE_EXIT_MODE:
+                return "ACTION_DESKTOP_MODE_EXIT_MODE";
             default:
                 throw new IllegalArgumentException("Invalid action");
         }
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index 3f96507..d35072f 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -22,7 +22,6 @@
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
 import static android.app.admin.DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
-import static android.security.Flags.reportPrimaryAuthAttempts;
 import static android.security.Flags.shouldTrustManagerListenForPrimaryAuth;
 
 import static com.android.internal.widget.flags.Flags.hideLastCharWithPhysicalInput;
@@ -472,7 +471,7 @@
             return;
         }
         getDevicePolicyManager().reportFailedPasswordAttempt(userId);
-        if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) {
+        if (!shouldTrustManagerListenForPrimaryAuth()) {
             getTrustManager().reportUnlockAttempt(/* authenticated= */ false, userId);
         }
     }
@@ -483,7 +482,7 @@
             return;
         }
         getDevicePolicyManager().reportSuccessfulPasswordAttempt(userId);
-        if (!reportPrimaryAuthAttempts() || !shouldTrustManagerListenForPrimaryAuth()) {
+        if (!shouldTrustManagerListenForPrimaryAuth()) {
             getTrustManager().reportUnlockAttempt(/* authenticated= */ true, userId);
         }
     }
diff --git a/core/java/com/android/internal/widget/NotificationCloseButton.java b/core/java/com/android/internal/widget/NotificationCloseButton.java
index bce266d..0d801b1 100644
--- a/core/java/com/android/internal/widget/NotificationCloseButton.java
+++ b/core/java/com/android/internal/widget/NotificationCloseButton.java
@@ -21,6 +21,8 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
 import android.util.AttributeSet;
 import android.view.RemotableViewMethod;
 import android.view.View;
@@ -40,6 +42,8 @@
     @ColorInt private int mBackgroundColor;
     @ColorInt private int mForegroundColor;
 
+    private Drawable mPillDrawable;
+
     public NotificationCloseButton(Context context) {
         this(context, null, 0, 0);
     }
@@ -62,6 +66,10 @@
     protected void onFinishInflate() {
         super.onFinishInflate();
         setContentDescription(mContext.getText(R.string.close_button_text));
+
+        final LayerDrawable layeredPill = (LayerDrawable) this.getBackground();
+        mPillDrawable = layeredPill.findDrawableByLayerId(R.id.close_button_pill_colorized_layer);
+
         boolean notificationCloseButtonSupported = Resources.getSystem().getBoolean(
                 com.android.internal.R.bool.config_notificationCloseButtonSupported);
         this.setVisibility(notificationCloseButtonSupported ? View.VISIBLE : View.GONE);
@@ -76,8 +84,11 @@
 
     private void updateColors() {
         if (mBackgroundColor != 0) {
-            this.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
+            // TODO(http://b/365585705): Ensure this close button compatible with the ongoing effort
+            // that makes notification rows partially-transparent.
+            this.mPillDrawable.setTintList(ColorStateList.valueOf(mBackgroundColor));
         }
+
         if (mForegroundColor != 0) {
             this.setImageTintList(ColorStateList.valueOf(mForegroundColor));
         }
diff --git a/core/java/com/android/internal/widget/NotificationProgressBar.java b/core/java/com/android/internal/widget/NotificationProgressBar.java
index 3472d68..f6e2a4d 100644
--- a/core/java/com/android/internal/widget/NotificationProgressBar.java
+++ b/core/java/com/android/internal/widget/NotificationProgressBar.java
@@ -78,6 +78,13 @@
     @Nullable
     private List<DrawablePart> mProgressDrawableParts = null;
 
+    /** @see R.styleable#NotificationProgressBar_segMinWidth */
+    private final float mSegMinWidth;
+    /** @see R.styleable#NotificationProgressBar_segSegGap */
+    private final float mSegSegGap;
+    /** @see R.styleable#NotificationProgressBar_segPointGap */
+    private final float mSegPointGap;
+
     @Nullable
     private Drawable mTracker = null;
     private boolean mHasTrackerIcon = false;
@@ -128,6 +135,10 @@
             Log.e(TAG, "Can't get NotificationProgressDrawable", ex);
         }
 
+        mSegMinWidth = a.getDimension(R.styleable.NotificationProgressBar_segMinWidth, 0f);
+        mSegSegGap = a.getDimension(R.styleable.NotificationProgressBar_segSegGap, 0f);
+        mSegPointGap = a.getDimension(R.styleable.NotificationProgressBar_segPointGap, 0f);
+
         // Supports setting the tracker in xml, but ProgressStyle notifications set/override it
         // via {@code #setProgressTrackerIcon}.
         final Drawable tracker = a.getDrawable(R.styleable.NotificationProgressBar_tracker);
@@ -444,30 +455,26 @@
             return;
         }
 
-        final float segSegGap = mNotificationProgressDrawable.getSegSegGap();
-        final float segPointGap = mNotificationProgressDrawable.getSegPointGap();
         final float pointRadius = mNotificationProgressDrawable.getPointRadius();
         mProgressDrawableParts = processPartsAndConvertToDrawableParts(
                 mParts,
                 width,
-                segSegGap,
-                segPointGap,
+                mSegSegGap,
+                mSegPointGap,
                 pointRadius,
                 mHasTrackerIcon,
                 mTrackerDrawWidth
         );
 
-        final float segmentMinWidth = mNotificationProgressDrawable.getSegmentMinWidth();
         final float progressFraction = getProgressFraction();
         final boolean isStyledByProgress = mProgressModel.isStyledByProgress();
-        final float progressGap =
-                mHasTrackerIcon ? 0F : mNotificationProgressDrawable.getSegSegGap();
+        final float progressGap = mHasTrackerIcon ? 0F : mSegSegGap;
         Pair<List<DrawablePart>, Float> p = null;
         try {
             p = maybeStretchAndRescaleSegments(
                     mParts,
                     mProgressDrawableParts,
-                    segmentMinWidth,
+                    mSegMinWidth,
                     pointRadius,
                     progressFraction,
                     isStyledByProgress,
@@ -492,11 +499,11 @@
                         mProgressModel.getProgress(),
                         getMax(),
                         width,
-                        segSegGap,
-                        segPointGap,
+                        mSegSegGap,
+                        mSegPointGap,
                         pointRadius,
                         mHasTrackerIcon,
-                        segmentMinWidth,
+                        mSegMinWidth,
                         isStyledByProgress,
                         mTrackerDrawWidth);
             } catch (NotEnoughWidthToFitAllPartsException ex) {
@@ -521,11 +528,11 @@
                         mProgressModel.getProgress(),
                         getMax(),
                         width,
-                        segSegGap,
-                        segPointGap,
+                        mSegSegGap,
+                        mSegPointGap,
                         pointRadius,
                         mHasTrackerIcon,
-                        segmentMinWidth,
+                        mSegMinWidth,
                         isStyledByProgress,
                         mTrackerDrawWidth);
             } catch (NotEnoughWidthToFitAllPartsException ex) {
diff --git a/core/java/com/android/internal/widget/NotificationProgressDrawable.java b/core/java/com/android/internal/widget/NotificationProgressDrawable.java
index b109610..32b283a 100644
--- a/core/java/com/android/internal/widget/NotificationProgressDrawable.java
+++ b/core/java/com/android/internal/widget/NotificationProgressDrawable.java
@@ -84,27 +84,6 @@
     }
 
     /**
-     * Returns the gap between two segments.
-     */
-    public float getSegSegGap() {
-        return mState.mSegSegGap;
-    }
-
-    /**
-     * Returns the gap between a segment and a point.
-     */
-    public float getSegPointGap() {
-        return mState.mSegPointGap;
-    }
-
-    /**
-     * Returns the gap between a segment and a point.
-     */
-    public float getSegmentMinWidth() {
-        return mState.mSegmentMinWidth;
-    }
-
-    /**
      * Returns the radius for the points.
      */
     public float getPointRadius() {
@@ -241,11 +220,6 @@
 
         mState.setDensity(resolveDensity(r, 0));
 
-        final TypedArray a = obtainAttributes(r, theme, attrs,
-                R.styleable.NotificationProgressDrawable);
-        updateStateFromTypedArray(a);
-        a.recycle();
-
         inflateChildElements(r, parser, attrs, theme);
 
         updateLocalState();
@@ -262,13 +236,6 @@
 
         state.setDensity(resolveDensity(t.getResources(), 0));
 
-        if (state.mThemeAttrs != null) {
-            final TypedArray a = t.resolveAttributes(
-                    state.mThemeAttrs, R.styleable.NotificationProgressDrawable);
-            updateStateFromTypedArray(a);
-            a.recycle();
-        }
-
         applyThemeChildElements(t);
 
         updateLocalState();
@@ -279,21 +246,6 @@
         return (mState.canApplyTheme()) || super.canApplyTheme();
     }
 
-    private void updateStateFromTypedArray(TypedArray a) {
-        final State state = mState;
-
-        // Account for any configuration changes.
-        state.mChangingConfigurations |= a.getChangingConfigurations();
-
-        // Extract the theme attributes, if any.
-        state.mThemeAttrs = a.extractThemeAttrs();
-
-        state.mSegSegGap = a.getDimension(R.styleable.NotificationProgressDrawable_segSegGap,
-                state.mSegSegGap);
-        state.mSegPointGap = a.getDimension(R.styleable.NotificationProgressDrawable_segPointGap,
-                state.mSegPointGap);
-    }
-
     private void inflateChildElements(Resources r, XmlPullParser parser, AttributeSet attrs,
             Theme theme) throws XmlPullParserException, IOException {
         TypedArray a;
@@ -357,8 +309,6 @@
         // Extract the theme attributes, if any.
         state.mThemeAttrsSegments = a.extractThemeAttrs();
 
-        state.mSegmentMinWidth = a.getDimension(
-                R.styleable.NotificationProgressDrawableSegments_minWidth, state.mSegmentMinWidth);
         state.mSegmentHeight = a.getDimension(
                 R.styleable.NotificationProgressDrawableSegments_height, state.mSegmentHeight);
         state.mFadedSegmentHeight = a.getDimension(
@@ -588,9 +538,6 @@
     static final class State extends ConstantState {
         @Config
         int mChangingConfigurations;
-        float mSegSegGap = 0.0f;
-        float mSegPointGap = 0.0f;
-        float mSegmentMinWidth = 0.0f;
         float mSegmentHeight;
         float mFadedSegmentHeight;
         float mSegmentCornerRadius;
@@ -610,9 +557,6 @@
 
         State(@NonNull State orig, @Nullable Resources res) {
             mChangingConfigurations = orig.mChangingConfigurations;
-            mSegSegGap = orig.mSegSegGap;
-            mSegPointGap = orig.mSegPointGap;
-            mSegmentMinWidth = orig.mSegmentMinWidth;
             mSegmentHeight = orig.mSegmentHeight;
             mFadedSegmentHeight = orig.mFadedSegmentHeight;
             mSegmentCornerRadius = orig.mSegmentCornerRadius;
@@ -631,18 +575,6 @@
         }
 
         private void applyDensityScaling(int sourceDensity, int targetDensity) {
-            if (mSegSegGap > 0) {
-                mSegSegGap = scaleFromDensity(
-                        mSegSegGap, sourceDensity, targetDensity);
-            }
-            if (mSegPointGap > 0) {
-                mSegPointGap = scaleFromDensity(
-                        mSegPointGap, sourceDensity, targetDensity);
-            }
-            if (mSegmentMinWidth > 0) {
-                mSegmentMinWidth = scaleFromDensity(
-                        mSegmentMinWidth, sourceDensity, targetDensity);
-            }
             if (mSegmentHeight > 0) {
                 mSegmentHeight = scaleFromDensity(
                         mSegmentHeight, sourceDensity, targetDensity);
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java b/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java
index a53d6b8..3fe6873 100644
--- a/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/AndroidPlatformSemanticNodeApplier.java
@@ -132,8 +132,13 @@
             }
         }
 
-        // TODO correct values
-        nodeInfo.setCollectionInfo(AccessibilityNodeInfo.CollectionInfo.obtain(-1, 1, false));
+        if (scrollDirection == RootContentBehavior.SCROLL_HORIZONTAL) {
+            nodeInfo.setCollectionInfo(AccessibilityNodeInfo.CollectionInfo.obtain(1, -1, false));
+            nodeInfo.setClassName("android.widget.HorizontalScrollView");
+        } else {
+            nodeInfo.setCollectionInfo(AccessibilityNodeInfo.CollectionInfo.obtain(-1, 1, false));
+            nodeInfo.setClassName("android.widget.ScrollView");
+        }
 
         if (scrollDirection == RootContentBehavior.SCROLL_HORIZONTAL) {
             nodeInfo.setClassName("android.widget.HorizontalScrollView");
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java b/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java
index f70f4cb..db2c460 100644
--- a/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/CoreDocumentAccessibility.java
@@ -33,6 +33,7 @@
 import com.android.internal.widget.remotecompose.core.semantics.AccessibleComponent;
 import com.android.internal.widget.remotecompose.core.semantics.CoreSemantics;
 import com.android.internal.widget.remotecompose.core.semantics.ScrollableComponent;
+import com.android.internal.widget.remotecompose.core.semantics.ScrollableComponent.ScrollDirection;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -104,9 +105,9 @@
             if (isClickAction(action)) {
                 return performClick(component);
             } else if (isScrollForwardAction(action)) {
-                return scrollByOffset(mRemoteContext, component, -500) != 0;
+                return scrollDirection(mRemoteContext, component, ScrollDirection.FORWARD);
             } else if (isScrollBackwardAction(action)) {
-                return scrollByOffset(mRemoteContext, component, 500) != 0;
+                return scrollDirection(mRemoteContext, component, ScrollDirection.BACKWARD);
             } else if (isShowOnScreenAction(action)) {
                 return showOnScreen(mRemoteContext, component);
             } else {
@@ -141,19 +142,32 @@
     }
 
     private boolean showOnScreen(RemoteContext context, Component component) {
-        if (component.getParent() instanceof LayoutComponent) {
-            LayoutComponent parent = (LayoutComponent) component.getParent();
-            ScrollableComponent scrollable = parent.selfOrModifier(ScrollableComponent.class);
+        ScrollableComponent scrollable = findScrollable(component);
 
-            if (scrollable != null) {
-                scrollable.showOnScreen(context, component.getComponentId());
-                return true;
-            }
+        if (scrollable != null) {
+            return scrollable.showOnScreen(context, component);
         }
 
         return false;
     }
 
+    @Nullable
+    private static ScrollableComponent findScrollable(Component component) {
+        Component parent = component.getParent();
+
+        while (parent != null) {
+            ScrollableComponent scrollable = parent.selfOrModifier(ScrollableComponent.class);
+
+            if (scrollable != null) {
+                return scrollable;
+            } else {
+                parent = parent.getParent();
+            }
+        }
+
+        return null;
+    }
+
     /**
      * scroll content by the given offset
      *
@@ -173,6 +187,25 @@
     }
 
     /**
+     * scroll content in a given direction
+     *
+     * @param context
+     * @param component
+     * @param direction
+     * @return
+     */
+    public boolean scrollDirection(
+            RemoteContext context, Component component, ScrollDirection direction) {
+        ScrollableComponent scrollable = component.selfOrModifier(ScrollableComponent.class);
+
+        if (scrollable != null) {
+            return scrollable.scrollDirection(context, direction);
+        }
+
+        return false;
+    }
+
+    /**
      * Perform a click on the given component
      *
      * @param component
diff --git a/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java
index c38a44a..da4e8d6 100644
--- a/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java
+++ b/core/java/com/android/internal/widget/remotecompose/accessibility/PlatformRemoteComposeTouchHelper.java
@@ -39,6 +39,7 @@
     private final RemoteComposeDocumentAccessibility mRemoteDocA11y;
 
     private final SemanticNodeApplier<AccessibilityNodeInfo> mApplier;
+    private final View mHost;
 
     public PlatformRemoteComposeTouchHelper(
             View host,
@@ -47,6 +48,7 @@
         super(host);
         this.mRemoteDocA11y = remoteDocA11y;
         this.mApplier = applier;
+        this.mHost = host;
     }
 
     public static PlatformRemoteComposeTouchHelper forRemoteComposePlayer(
@@ -150,6 +152,7 @@
             boolean performed = mRemoteDocA11y.performAction(component, action, arguments);
 
             if (performed) {
+                mHost.invalidate();
                 invalidateRoot();
             }
 
diff --git a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
index caf19e1..8fbd10c 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/CoreDocument.java
@@ -64,16 +64,18 @@
     private static final boolean DEBUG = false;
 
     // Semantic version
-    public static final int MAJOR_VERSION = 0;
-    public static final int MINOR_VERSION = 4;
+    public static final int MAJOR_VERSION = 1;
+    public static final int MINOR_VERSION = 0;
     public static final int PATCH_VERSION = 0;
 
     // Internal version level
-    public static final int DOCUMENT_API_LEVEL = 4;
+    public static final int DOCUMENT_API_LEVEL = 5;
 
     // We also keep a more fine-grained BUILD number, exposed as
     // ID_API_LEVEL = DOCUMENT_API_LEVEL + BUILD
-    static final float BUILD = 0.5f;
+    static final float BUILD = 0.0f;
+
+    private static final boolean UPDATE_VARIABLES_BEFORE_LAYOUT = false;
 
     @NonNull ArrayList<Operation> mOperations = new ArrayList<>();
 
@@ -840,18 +842,25 @@
 
     @NonNull private HashMap<Integer, Component> mComponentMap = new HashMap<Integer, Component>();
 
+    /**
+     * Register all the operations recursively
+     *
+     * @param context
+     * @param list
+     */
     private void registerVariables(
             @NonNull RemoteContext context, @NonNull ArrayList<Operation> list) {
         for (Operation op : list) {
             if (op instanceof VariableSupport) {
-                ((VariableSupport) op).updateVariables(context);
                 ((VariableSupport) op).registerListening(context);
             }
             if (op instanceof Component) {
                 mComponentMap.put(((Component) op).getComponentId(), (Component) op);
-                registerVariables(context, ((Component) op).getList());
                 ((Component) op).registerVariables(context);
             }
+            if (op instanceof Container) {
+                registerVariables(context, ((Container) op).getList());
+            }
             if (op instanceof ComponentValue) {
                 ComponentValue v = (ComponentValue) op;
                 Component component = mComponentMap.get(v.getComponentId());
@@ -864,14 +873,34 @@
             if (op instanceof ComponentModifiers) {
                 for (ModifierOperation modifier : ((ComponentModifiers) op).getList()) {
                     if (modifier instanceof VariableSupport) {
-                        ((VariableSupport) modifier).updateVariables(context);
                         ((VariableSupport) modifier).registerListening(context);
                     }
                 }
             }
+        }
+    }
+
+    /**
+     * Apply the operations recursively, for the original initialization pass with mode == DATA
+     *
+     * @param context
+     * @param list
+     */
+    private void applyOperations(
+            @NonNull RemoteContext context, @NonNull ArrayList<Operation> list) {
+        for (Operation op : list) {
+            if (op instanceof VariableSupport) {
+                ((VariableSupport) op).updateVariables(context);
+            }
+            if (op instanceof Component) { // for componentvalues...
+                ((Component) op).updateVariables(context);
+            }
             op.markNotDirty();
             op.apply(context);
             context.incrementOpCount();
+            if (op instanceof Container) {
+                applyOperations(context, ((Container) op).getList());
+            }
         }
     }
 
@@ -891,8 +920,12 @@
         mTimeVariables.updateTime(context);
 
         registerVariables(context, mOperations);
+        applyOperations(context, mOperations);
         context.mMode = RemoteContext.ContextMode.UNSET;
-        mFirstPaint = true;
+
+        if (UPDATE_VARIABLES_BEFORE_LAYOUT) {
+            mFirstPaint = true;
+        }
     }
 
     ///////////////////////////////////////////////////////////////////////////////////////////////
@@ -1241,11 +1274,13 @@
         context.mRemoteComposeState = mRemoteComposeState;
         context.mRemoteComposeState.setContext(context);
 
-        // Update any dirty variables
-        if (mFirstPaint) {
-            mFirstPaint = false;
-        } else {
-            updateVariables(context, theme, mOperations);
+        if (UPDATE_VARIABLES_BEFORE_LAYOUT) {
+            // Update any dirty variables
+            if (mFirstPaint) {
+                mFirstPaint = false;
+            } else {
+                updateVariables(context, theme, mOperations);
+            }
         }
 
         // If we have a content sizing set, we are going to take the original document
diff --git a/core/java/com/android/internal/widget/remotecompose/core/Operations.java b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
index ac9f98b..2025236 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/Operations.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/Operations.java
@@ -30,6 +30,7 @@
 import com.android.internal.widget.remotecompose.core.operations.DataListIds;
 import com.android.internal.widget.remotecompose.core.operations.DataMapIds;
 import com.android.internal.widget.remotecompose.core.operations.DataMapLookup;
+import com.android.internal.widget.remotecompose.core.operations.DebugMessage;
 import com.android.internal.widget.remotecompose.core.operations.DrawArc;
 import com.android.internal.widget.remotecompose.core.operations.DrawBitmap;
 import com.android.internal.widget.remotecompose.core.operations.DrawBitmapFontText;
@@ -111,6 +112,7 @@
 import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BackgroundModifierOperation;
 import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.BorderModifierOperation;
 import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ClipRectModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.CollapsiblePriorityModifierOperation;
 import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ComponentVisibilityOperation;
 import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.DrawContentOperation;
 import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.GraphicsLayerModifierOperation;
@@ -230,6 +232,7 @@
     public static final int PATH_COMBINE = 175;
     public static final int HAPTIC_FEEDBACK = 177;
     public static final int CONDITIONAL_OPERATIONS = 178;
+    public static final int DEBUG_MESSAGE = 179;
 
     ///////////////////////////////////////// ======================
 
@@ -257,6 +260,7 @@
     public static final int MODIFIER_HEIGHT = 67;
     public static final int MODIFIER_WIDTH_IN = 231;
     public static final int MODIFIER_HEIGHT_IN = 232;
+    public static final int MODIFIER_COLLAPSIBLE_PRIORITY = 235;
     public static final int MODIFIER_BACKGROUND = 55;
     public static final int MODIFIER_BORDER = 107;
     public static final int MODIFIER_PADDING = 58;
@@ -368,6 +372,7 @@
         map.put(MODIFIER_HEIGHT, HeightModifierOperation::read);
         map.put(MODIFIER_WIDTH_IN, WidthInModifierOperation::read);
         map.put(MODIFIER_HEIGHT_IN, HeightInModifierOperation::read);
+        map.put(MODIFIER_COLLAPSIBLE_PRIORITY, CollapsiblePriorityModifierOperation::read);
         map.put(MODIFIER_PADDING, PaddingModifierOperation::read);
         map.put(MODIFIER_BACKGROUND, BackgroundModifierOperation::read);
         map.put(MODIFIER_BORDER, BorderModifierOperation::read);
@@ -440,6 +445,7 @@
         map.put(PATH_COMBINE, PathCombine::read);
         map.put(HAPTIC_FEEDBACK, HapticFeedback::read);
         map.put(CONDITIONAL_OPERATIONS, ConditionalOperations::read);
+        map.put(DEBUG_MESSAGE, DebugMessage::read);
 
         //        map.put(ACCESSIBILITY_CUSTOM_ACTION, CoreSemantics::read);
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
index 1f02668..a86b62e 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteComposeBuffer.java
@@ -33,6 +33,7 @@
 import com.android.internal.widget.remotecompose.core.operations.DataListIds;
 import com.android.internal.widget.remotecompose.core.operations.DataMapIds;
 import com.android.internal.widget.remotecompose.core.operations.DataMapLookup;
+import com.android.internal.widget.remotecompose.core.operations.DebugMessage;
 import com.android.internal.widget.remotecompose.core.operations.DrawArc;
 import com.android.internal.widget.remotecompose.core.operations.DrawBitmap;
 import com.android.internal.widget.remotecompose.core.operations.DrawBitmapFontText;
@@ -1332,7 +1333,7 @@
      * @return the nan id of float
      */
     public float reserveFloatVariable() {
-        int id = mRemoteComposeState.cacheFloat(0f);
+        int id = mRemoteComposeState.nextId();
         return Utils.asNan(id);
     }
 
@@ -1870,6 +1871,46 @@
     }
 
     /**
+     * Add a scroll modifier
+     *
+     * @param direction HORIZONTAL(0) or VERTICAL(1)
+     * @param positionId the position id as a NaN
+     */
+    public void addModifierScroll(int direction, float positionId) {
+        float max = this.reserveFloatVariable();
+        float notchMax = this.reserveFloatVariable();
+        float touchExpressionDirection =
+                direction != 0 ? RemoteContext.FLOAT_TOUCH_POS_X : RemoteContext.FLOAT_TOUCH_POS_Y;
+
+        ScrollModifierOperation.apply(mBuffer, direction, positionId, max, notchMax);
+        this.addTouchExpression(
+                positionId,
+                0f,
+                0f,
+                max,
+                0f,
+                3,
+                new float[] {
+                    touchExpressionDirection, -1, MUL,
+                },
+                TouchExpression.STOP_GENTLY,
+                null,
+                null);
+        ContainerEnd.apply(mBuffer);
+    }
+
+    /**
+     * Add a scroll modifier
+     *
+     * @param direction HORIZONTAL(0) or VERTICAL(1)
+     */
+    public void addModifierScroll(int direction) {
+        float max = this.reserveFloatVariable();
+        ScrollModifierOperation.apply(mBuffer, direction, 0f, max, 0f);
+        ContainerEnd.apply(mBuffer);
+    }
+
+    /**
      * Add a background modifier of provided color
      *
      * @param color the color of the background
@@ -2464,4 +2505,15 @@
     public void addConditionalOperations(byte type, float a, float b) {
         ConditionalOperations.apply(mBuffer, type, a, b);
     }
+
+    /**
+     * Add a debug message
+     *
+     * @param textId text id
+     * @param value
+     * @param flags
+     */
+    public void addDebugMessage(int textId, float value, int flags) {
+        DebugMessage.apply(mBuffer, textId, value, flags);
+    }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
index e37833f..b297a02 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/RemoteContext.java
@@ -46,7 +46,7 @@
             new CoreDocument(); // todo: is this a valid way to initialize? bbade@
     public @NonNull RemoteComposeState mRemoteComposeState =
             new RemoteComposeState(); // todo, is this a valid use of RemoteComposeState -- bbade@
-
+    private long mDocLoadTime = System.currentTimeMillis();
     @Nullable protected PaintContext mPaintContext = null;
     protected float mDensity = Float.NaN;
 
@@ -83,6 +83,20 @@
         }
     }
 
+    /**
+     * Get the time the document was loaded
+     *
+     * @return time in ms since the document was loaded
+     */
+    public long getDocLoadTime() {
+        return mDocLoadTime;
+    }
+
+    /** Set the time the document was loaded */
+    public void setDocLoadTime() {
+        mDocLoadTime = System.currentTimeMillis();
+    }
+
     public boolean isAnimationEnabled() {
         return mAnimate;
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/DebugMessage.java b/core/java/com/android/internal/widget/remotecompose/core/operations/DebugMessage.java
new file mode 100644
index 0000000..c27bd8b
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/DebugMessage.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.VariableSupport;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+
+import java.util.List;
+
+/**
+ * This prints debugging message useful for debugging. It should not be use in production documents
+ */
+public class DebugMessage extends Operation implements VariableSupport {
+    private static final int OP_CODE = Operations.DEBUG_MESSAGE;
+    private static final String CLASS_NAME = "DebugMessage";
+    int mTextID;
+    float mFloatValue;
+    float mOutFloatValue;
+    int mFlags = 0;
+
+    public DebugMessage(int textID, float value, int flags) {
+        mTextID = textID;
+        mFloatValue = value;
+        mFlags = flags;
+    }
+
+    @Override
+    public void updateVariables(@NonNull RemoteContext context) {
+        System.out.println("Debug message : updateVariables ");
+        mOutFloatValue =
+                Float.isNaN(mFloatValue)
+                        ? context.getFloat(Utils.idFromNan(mFloatValue))
+                        : mFloatValue;
+        System.out.println(
+                "Debug message : updateVariables "
+                        + Utils.floatToString(mFloatValue, mOutFloatValue));
+    }
+
+    @Override
+    public void registerListening(@NonNull RemoteContext context) {
+        System.out.println("Debug message : registerListening ");
+
+        if (Float.isNaN(mFloatValue)) {
+            System.out.println("Debug message : registerListening " + mFloatValue);
+            context.listensTo(Utils.idFromNan(mFloatValue), this);
+        }
+    }
+
+    @Override
+    public void write(@NonNull WireBuffer buffer) {
+        apply(buffer, mTextID, mFloatValue, mFlags);
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "DebugMessage "
+                + mTextID
+                + ", "
+                + Utils.floatToString(mFloatValue, mOutFloatValue)
+                + ", "
+                + mFlags;
+    }
+
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
+    public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+        int text = buffer.readInt();
+        float floatValue = buffer.readFloat();
+        int flags = buffer.readInt();
+        DebugMessage op = new DebugMessage(text, floatValue, flags);
+        operations.add(op);
+    }
+
+    /**
+     * The name of the class
+     *
+     * @return the name
+     */
+    @NonNull
+    public static String name() {
+        return CLASS_NAME;
+    }
+
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
+    public static int id() {
+        return OP_CODE;
+    }
+
+    /**
+     * Writes out the operation to the buffer
+     *
+     * @param buffer write the command to the buffer
+     * @param textID id of the text
+     * @param value value to print
+     * @param flags flags to print
+     */
+    public static void apply(@NonNull WireBuffer buffer, int textID, float value, int flags) {
+        buffer.start(OP_CODE);
+        buffer.writeInt(textID);
+        buffer.writeFloat(value);
+        buffer.writeInt(flags);
+    }
+
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
+    public static void documentation(@NonNull DocumentationBuilder doc) {
+        doc.operation("DebugMessage Operations", id(), CLASS_NAME)
+                .description("Print debugging messages")
+                .field(DocumentedOperation.INT, "textId", "test to print")
+                .field(DocumentedOperation.FLOAT, "value", "value of a float to print")
+                .field(DocumentedOperation.INT, "flags", "print additional information");
+    }
+
+    @Override
+    public void apply(@NonNull RemoteContext context) {
+        String str = context.getText(mTextID);
+        System.out.println("Debug message : " + str + " " + mOutFloatValue + " " + mFlags);
+    }
+
+    @NonNull
+    @Override
+    public String deepToString(@NonNull String indent) {
+        return indent + toString();
+    }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
index eba201b..0901ae3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/FloatExpression.java
@@ -149,7 +149,6 @@
 
     @Override
     public void apply(@NonNull RemoteContext context) {
-        updateVariables(context);
         float t = context.getAnimationTime();
         if (Float.isNaN(mLastChange)) {
             mLastChange = t;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java
index ee9e7a4..e86eabf 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/ParticlesCreate.java
@@ -23,6 +23,8 @@
 
 import com.android.internal.widget.remotecompose.core.Operation;
 import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.PaintContext;
+import com.android.internal.widget.remotecompose.core.PaintOperation;
 import com.android.internal.widget.remotecompose.core.RemoteContext;
 import com.android.internal.widget.remotecompose.core.VariableSupport;
 import com.android.internal.widget.remotecompose.core.WireBuffer;
@@ -30,6 +32,7 @@
 import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
 import com.android.internal.widget.remotecompose.core.operations.utilities.AnimatedFloatExpression;
 import com.android.internal.widget.remotecompose.core.operations.utilities.NanMap;
+import com.android.internal.widget.remotecompose.core.serialize.MapSerializer;
 
 import java.util.Arrays;
 import java.util.List;
@@ -38,7 +41,7 @@
  * This creates a particle system. which consist of id, particleCount, array of id's and equations
  * for constructing the particles
  */
-public class ParticlesCreate extends Operation implements VariableSupport {
+public class ParticlesCreate extends PaintOperation implements VariableSupport {
     private static final int OP_CODE = Operations.PARTICLE_DEFINE;
     private static final String CLASS_NAME = "ParticlesCreate";
     private final int mId;
@@ -214,6 +217,13 @@
         return indent + toString();
     }
 
+    @Override
+    public void paint(@NonNull PaintContext context) {
+        for (int i = 0; i < mParticles.length; i++) {
+            initializeParticle(i);
+        }
+    }
+
     void initializeParticle(int pNo) {
         for (int j = 0; j < mParticles[pNo].length; j++) {
             for (int k = 0; k < mIndexeVars.length; k++) {
@@ -226,13 +236,6 @@
         }
     }
 
-    @Override
-    public void apply(@NonNull RemoteContext context) {
-        for (int i = 0; i < mParticles.length; i++) {
-            initializeParticle(i);
-        }
-    }
-
     public float[][] getParticles() {
         return mParticles;
     }
@@ -244,4 +247,7 @@
     public float[][] getEquations() {
         return mOutEquations;
     }
+
+    @Override
+    public void serialize(MapSerializer serializer) {}
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java
index 8a747e1..31d21c4 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathAppend.java
@@ -258,6 +258,6 @@
 
     @Override
     public void serialize(MapSerializer serializer) {
-        serializer.addType(CLASS_NAME).add("id", mInstanceId).add("path", pathString(mFloatPath));
+        serializer.addType(CLASS_NAME).add("id", mInstanceId).addPath("path", mFloatPath);
     }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java
index 78e3b9e..7a28992 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathCreate.java
@@ -242,6 +242,6 @@
 
     @Override
     public void serialize(MapSerializer serializer) {
-        serializer.addType(CLASS_NAME).add("id", mInstanceId).add("path", pathString(mFloatPath));
+        serializer.addType(CLASS_NAME).add("id", mInstanceId).addPath("path", mFloatPath);
     }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
index cedc4f3b..8b01722 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/PathData.java
@@ -243,6 +243,6 @@
 
     @Override
     public void serialize(MapSerializer serializer) {
-        serializer.addType(CLASS_NAME).add("id", mInstanceId).add("path", pathString(mFloatPath));
+        serializer.addType(CLASS_NAME).add("id", mInstanceId).addPath("path", mFloatPath);
     }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java
index e9cc26f..67d3a65 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TimeAttribute.java
@@ -85,6 +85,9 @@
     /** the year */
     public static final short TIME_YEAR = 12;
 
+    /** (value - doc_load_time) * 1E-3 */
+    public static final short TIME_FROM_LOAD_SEC = 14;
+
     /**
      * creates a new operation
      *
@@ -226,6 +229,7 @@
         int val = mType & 255;
         int flags = mType >> 8;
         RemoteContext ctx = context.getContext();
+        long load_time = ctx.getDocLoadTime();
         LongConstant longConstant = (LongConstant) ctx.getObject(mTimeId);
         long value = longConstant.getValue();
         long delta = 0;
@@ -262,10 +266,12 @@
             case TIME_FROM_NOW_SEC:
             case TIME_FROM_ARG_SEC:
                 ctx.loadFloat(mId, (delta) * 1E-3f);
+                ctx.needsRepaint();
                 break;
             case TIME_FROM_ARG_MIN:
             case TIME_FROM_NOW_MIN:
                 ctx.loadFloat(mId, (float) (delta * 1E-3 / 60));
+                ctx.needsRepaint();
                 break;
             case TIME_FROM_ARG_HR:
             case TIME_FROM_NOW_HR:
@@ -292,6 +298,10 @@
             case TIME_YEAR:
                 ctx.loadFloat(mId, time.getYear());
                 break;
+            case TIME_FROM_LOAD_SEC:
+                ctx.loadFloat(mId, (value - load_time) * 1E-3f);
+                ctx.needsRepaint();
+                break;
         }
     }
 
@@ -334,6 +344,8 @@
                 return "TIME_DAY_OF_WEEK";
             case TIME_YEAR:
                 return "TIME_YEAR";
+            case TIME_FROM_LOAD_SEC:
+                return "TIME_FROM_LOAD_SEC";
             default:
                 return "INVALID_TIME_TYPE";
         }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
index f246729..3e5dff8 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/TouchExpression.java
@@ -494,7 +494,7 @@
         mTouchUpTime = context.getAnimationTime();
 
         float dest = getStopPosition(value, slope);
-        float time = mMaxTime * Math.abs(dest - value) / (2 * mMaxVelocity);
+        float time = Math.min(2, mMaxTime * Math.abs(dest - value) / (2 * mMaxVelocity));
         mEasyTouch.config(value, dest, slope, time, mMaxAcceleration, mMaxVelocity, null);
         mEasingToStop = true;
         context.needsRepaint();
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
index f1158d9..425c61b 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/Component.java
@@ -175,20 +175,25 @@
                             + mComponentId);
         }
         for (ComponentValue v : mComponentValues) {
-            switch (v.getType()) {
-                case ComponentValue.WIDTH:
-                    context.loadFloat(v.getValueId(), mWidth);
-                    if (DEBUG) {
-                        System.out.println("Updating WIDTH for " + mComponentId + " to " + mWidth);
-                    }
-                    break;
-                case ComponentValue.HEIGHT:
-                    context.loadFloat(v.getValueId(), mHeight);
-                    if (DEBUG) {
-                        System.out.println(
-                                "Updating HEIGHT for " + mComponentId + " to " + mHeight);
-                    }
-                    break;
+            if (context.getMode() == RemoteContext.ContextMode.DATA) {
+                context.loadFloat(v.getValueId(), 1f);
+            } else {
+                switch (v.getType()) {
+                    case ComponentValue.WIDTH:
+                        context.loadFloat(v.getValueId(), mWidth);
+                        if (DEBUG) {
+                            System.out.println(
+                                    "Updating WIDTH for " + mComponentId + " to " + mWidth);
+                        }
+                        break;
+                    case ComponentValue.HEIGHT:
+                        context.loadFloat(v.getValueId(), mHeight);
+                        if (DEBUG) {
+                            System.out.println(
+                                    "Updating HEIGHT for " + mComponentId + " to " + mHeight);
+                        }
+                        break;
+                }
             }
         }
     }
@@ -824,15 +829,27 @@
      *
      * @param value a 2 dimension float array that will receive the horizontal and vertical position
      *     of the component.
+     * @param forSelf whether the location is for this container or a child, relevant for scrollable
+     *     items.
      */
-    public void getLocationInWindow(@NonNull float[] value) {
+    public void getLocationInWindow(@NonNull float[] value, boolean forSelf) {
         value[0] += mX;
         value[1] += mY;
         if (mParent != null) {
-            mParent.getLocationInWindow(value);
+            mParent.getLocationInWindow(value, false);
         }
     }
 
+    /**
+     * Returns the location of the component relative to the root component
+     *
+     * @param value a 2 dimension float array that will receive the horizontal and vertical position
+     *     of the component.
+     */
+    public void getLocationInWindow(@NonNull float[] value) {
+        getLocationInWindow(value, true);
+    }
+
     @NonNull
     @Override
     public String toString() {
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
index 6163d80..bc099e3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/LayoutComponent.java
@@ -289,11 +289,11 @@
     }
 
     @Override
-    public void getLocationInWindow(@NonNull float[] value) {
+    public void getLocationInWindow(@NonNull float[] value, boolean forSelf) {
         value[0] += mX + mPaddingLeft;
         value[1] += mY + mPaddingTop;
         if (mParent != null) {
-            mParent.getLocationInWindow(value);
+            mParent.getLocationInWindow(value, false);
         }
     }
 
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleColumnLayout.java
index b008952..00ec605 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleColumnLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleColumnLayout.java
@@ -24,10 +24,13 @@
 import com.android.internal.widget.remotecompose.core.RemoteContext;
 import com.android.internal.widget.remotecompose.core.WireBuffer;
 import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.CollapsiblePriorityModifierOperation;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class CollapsibleColumnLayout extends ColumnLayout {
@@ -153,7 +156,7 @@
     }
 
     @Override
-    protected boolean hasVerticalIntrinsicDimension() {
+    public boolean hasVerticalIntrinsicDimension() {
         return true;
     }
 
@@ -166,25 +169,72 @@
             boolean verticalWrap,
             @NonNull MeasurePass measure,
             @NonNull Size size) {
+        computeVisibleChildren(
+                context, maxWidth, maxHeight, horizontalWrap, verticalWrap, measure, size);
+    }
+
+    @Override
+    public void computeSize(
+            @NonNull PaintContext context,
+            float minWidth,
+            float maxWidth,
+            float minHeight,
+            float maxHeight,
+            @NonNull MeasurePass measure) {
+        computeVisibleChildren(context, maxWidth, maxHeight, false, false, measure, null);
+    }
+
+    @Override
+    public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) {
+        // if needed, take care of weight calculations
+        super.internalLayoutMeasure(context, measure);
+        // Check again for visibility
+        ComponentMeasure m = measure.get(this);
+        computeVisibleChildren(context, m.getW(), m.getH(), false, false, measure, null);
+    }
+
+    private void computeVisibleChildren(
+            @NonNull PaintContext context,
+            float maxWidth,
+            float maxHeight,
+            boolean horizontalWrap,
+            boolean verticalWrap,
+            @NonNull MeasurePass measure,
+            @Nullable Size size) {
         int visibleChildren = 0;
         ComponentMeasure self = measure.get(this);
         self.addVisibilityOverride(Visibility.OVERRIDE_VISIBLE);
         float currentMaxHeight = maxHeight;
+        boolean hasPriorities = false;
         for (Component c : mChildrenComponents) {
-            if (c instanceof CollapsibleColumnLayout) {
-                c.measure(context, 0f, maxWidth, 0f, currentMaxHeight, measure);
-            } else {
-                c.measure(context, 0f, maxWidth, 0f, Float.MAX_VALUE, measure);
+            if (!measure.contains(c.getComponentId())) {
+                // No need to remeasure here if already done
+                if (c instanceof CollapsibleColumnLayout) {
+                    c.measure(context, 0f, maxWidth, 0f, currentMaxHeight, measure);
+                } else {
+                    c.measure(context, 0f, maxWidth, 0f, Float.MAX_VALUE, measure);
+                }
             }
+
             ComponentMeasure m = measure.get(c);
             if (!m.isGone()) {
-                size.setWidth(Math.max(size.getWidth(), m.getW()));
-                size.setHeight(size.getHeight() + m.getH());
+                if (size != null) {
+                    size.setWidth(Math.max(size.getWidth(), m.getW()));
+                    size.setHeight(size.getHeight() + m.getH());
+                }
                 visibleChildren++;
                 currentMaxHeight -= m.getH();
             }
+            if (c instanceof LayoutComponent) {
+                LayoutComponent lc = (LayoutComponent) c;
+                CollapsiblePriorityModifierOperation priority =
+                        lc.selfOrModifier(CollapsiblePriorityModifierOperation.class);
+                if (priority != null) {
+                    hasPriorities = true;
+                }
+            }
         }
-        if (!mChildrenComponents.isEmpty()) {
+        if (!mChildrenComponents.isEmpty() && size != null) {
             size.setHeight(size.getHeight() + (mSpacedBy * (visibleChildren - 1)));
         }
 
@@ -192,7 +242,14 @@
         float childrenHeight = 0f;
 
         boolean overflow = false;
-        for (Component child : mChildrenComponents) {
+        ArrayList<Component> children = mChildrenComponents;
+        if (hasPriorities) {
+            // TODO: We need to cache this.
+            children =
+                    CollapsiblePriority.sortWithPriorities(
+                            mChildrenComponents, CollapsiblePriority.VERTICAL);
+        }
+        for (Component child : children) {
             ComponentMeasure childMeasure = measure.get(child);
             if (overflow || childMeasure.isGone()) {
                 childMeasure.addVisibilityOverride(Visibility.OVERRIDE_GONE);
@@ -209,10 +266,10 @@
                 visibleChildren++;
             }
         }
-        if (verticalWrap) {
+        if (verticalWrap && size != null) {
             size.setHeight(Math.min(maxHeight, childrenHeight));
         }
-        if (visibleChildren == 0 || size.getHeight() <= 0f) {
+        if (visibleChildren == 0 || (size != null && size.getHeight() <= 0f)) {
             self.addVisibilityOverride(Visibility.OVERRIDE_GONE);
         }
     }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsiblePriority.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsiblePriority.java
new file mode 100644
index 0000000..46cd45e
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsiblePriority.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.managers;
+
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.CollapsiblePriorityModifierOperation;
+
+import java.util.ArrayList;
+
+/** Utility class to manage collapsible priorities on components */
+public class CollapsiblePriority {
+
+    public static final int HORIZONTAL = 0;
+    public static final int VERTICAL = 1;
+
+    /**
+     * Returns the priority of a child component
+     *
+     * @param c the child component
+     * @return priority value, or 0f if not found
+     */
+    static float getPriority(Component c, int orientation) {
+        if (c instanceof LayoutComponent) {
+            LayoutComponent lc = (LayoutComponent) c;
+            CollapsiblePriorityModifierOperation priority =
+                    lc.selfOrModifier(CollapsiblePriorityModifierOperation.class);
+            if (priority != null && priority.getOrientation() == orientation) {
+                return priority.getPriority();
+            }
+        }
+        return Float.MAX_VALUE;
+    }
+
+    /**
+     * Allocate and return a sorted array of components by their priorities
+     *
+     * @param components the children components
+     * @return list of components sorted by their priority in decreasing order
+     */
+    static ArrayList<Component> sortWithPriorities(
+            ArrayList<Component> components, int orientation) {
+        ArrayList<Component> sorted = new ArrayList<>(components);
+        sorted.sort(
+                (t1, t2) -> {
+                    float p1 = getPriority(t1, orientation);
+                    float p2 = getPriority(t2, orientation);
+                    return (int) (p2 - p1);
+                });
+        return sorted;
+    }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleRowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleRowLayout.java
index 05f3329..e3632f9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleRowLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/CollapsibleRowLayout.java
@@ -24,10 +24,13 @@
 import com.android.internal.widget.remotecompose.core.RemoteContext;
 import com.android.internal.widget.remotecompose.core.WireBuffer;
 import com.android.internal.widget.remotecompose.core.operations.layout.Component;
+import com.android.internal.widget.remotecompose.core.operations.layout.LayoutComponent;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.CollapsiblePriorityModifierOperation;
 
+import java.util.ArrayList;
 import java.util.List;
 
 public class CollapsibleRowLayout extends RowLayout {
@@ -135,8 +138,12 @@
     }
 
     @Override
-    protected boolean hasHorizontalIntrinsicDimension() {
-        return true;
+    public float minIntrinsicHeight(@NonNull RemoteContext context) {
+        float height = computeModifierDefinedHeight(context);
+        if (!mChildrenComponents.isEmpty()) {
+            height += mChildrenComponents.get(0).minIntrinsicHeight(context);
+        }
+        return height;
     }
 
     @Override
@@ -149,12 +156,8 @@
     }
 
     @Override
-    public float minIntrinsicHeight(@NonNull RemoteContext context) {
-        float height = computeModifierDefinedHeight(context);
-        if (!mChildrenComponents.isEmpty()) {
-            height += mChildrenComponents.get(0).minIntrinsicHeight(context);
-        }
-        return height;
+    public boolean hasHorizontalIntrinsicDimension() {
+        return true;
     }
 
     @Override
@@ -166,45 +169,107 @@
             boolean verticalWrap,
             @NonNull MeasurePass measure,
             @NonNull Size size) {
-        super.computeWrapSize(
-                context, Float.MAX_VALUE, maxHeight, horizontalWrap, verticalWrap, measure, size);
+        computeVisibleChildren(
+                context, maxWidth, maxHeight, horizontalWrap, verticalWrap, measure, size);
     }
 
     @Override
-    public boolean applyVisibility(
-            float selfWidth, float selfHeight, @NonNull MeasurePass measure) {
-        float childrenWidth = 0f;
-        float childrenHeight = 0f;
-        boolean changedVisibility = false;
+    public void computeSize(
+            @NonNull PaintContext context,
+            float minWidth,
+            float maxWidth,
+            float minHeight,
+            float maxHeight,
+            @NonNull MeasurePass measure) {
+        computeVisibleChildren(context, maxWidth, maxHeight, false, false, measure, null);
+    }
+
+    @Override
+    public void internalLayoutMeasure(@NonNull PaintContext context, @NonNull MeasurePass measure) {
+        // if needed, take care of weight calculations
+        super.internalLayoutMeasure(context, measure);
+        // Check again for visibility
+        ComponentMeasure m = measure.get(this);
+        computeVisibleChildren(context, m.getW(), m.getH(), false, false, measure, null);
+    }
+
+    private void computeVisibleChildren(
+            @NonNull PaintContext context,
+            float maxWidth,
+            float maxHeight,
+            boolean horizontalWrap,
+            boolean verticalWrap,
+            @NonNull MeasurePass measure,
+            @Nullable Size size) {
         int visibleChildren = 0;
         ComponentMeasure self = measure.get(this);
-        self.clearVisibilityOverride();
-        if (selfWidth <= 0 || selfHeight <= 0) {
-            self.addVisibilityOverride(Visibility.OVERRIDE_GONE);
-            return true;
+        self.addVisibilityOverride(Visibility.OVERRIDE_VISIBLE);
+        float currentMaxWidth = maxWidth;
+        boolean hasPriorities = false;
+        for (Component c : mChildrenComponents) {
+            if (!measure.contains(c.getComponentId())) {
+                // No need to remeasure here if already done
+                if (c instanceof CollapsibleRowLayout) {
+                    c.measure(context, 0f, currentMaxWidth, 0f, maxHeight, measure);
+                } else {
+                    c.measure(context, 0f, Float.MAX_VALUE, 0f, maxHeight, measure);
+                }
+            }
+            ComponentMeasure m = measure.get(c);
+            if (!m.isGone()) {
+                if (size != null) {
+                    size.setHeight(Math.max(size.getHeight(), m.getH()));
+                    size.setWidth(size.getWidth() + m.getW());
+                }
+                visibleChildren++;
+                currentMaxWidth -= m.getW();
+            }
+            if (c instanceof LayoutComponent) {
+                LayoutComponent lc = (LayoutComponent) c;
+                CollapsiblePriorityModifierOperation priority =
+                        lc.selfOrModifier(CollapsiblePriorityModifierOperation.class);
+                if (priority != null) {
+                    hasPriorities = true;
+                }
+            }
         }
-        for (Component child : mChildrenComponents) {
+        if (!mChildrenComponents.isEmpty() && size != null) {
+            size.setWidth(size.getWidth() + (mSpacedBy * (visibleChildren - 1)));
+        }
+
+        float childrenWidth = 0f;
+        float childrenHeight = 0f;
+
+        boolean overflow = false;
+        ArrayList<Component> children = mChildrenComponents;
+        if (hasPriorities) {
+            // TODO: We need to cache this.
+            children =
+                    CollapsiblePriority.sortWithPriorities(
+                            mChildrenComponents, CollapsiblePriority.HORIZONTAL);
+        }
+        for (Component child : children) {
             ComponentMeasure childMeasure = measure.get(child);
-            int visibility = childMeasure.getVisibility();
-            childMeasure.clearVisibilityOverride();
-            if (!childMeasure.isVisible()) {
+            if (overflow || childMeasure.isGone()) {
+                childMeasure.addVisibilityOverride(Visibility.OVERRIDE_GONE);
                 continue;
             }
-            if (childrenWidth + childMeasure.getW() > selfWidth
-                    && childrenHeight + childMeasure.getH() > selfHeight) {
+            float childWidth = childMeasure.getW();
+            boolean childDoesNotFits = childrenWidth + childWidth > maxWidth;
+            if (childDoesNotFits) {
                 childMeasure.addVisibilityOverride(Visibility.OVERRIDE_GONE);
-                if (visibility != childMeasure.getVisibility()) {
-                    changedVisibility = true;
-                }
+                overflow = true;
             } else {
-                childrenWidth += childMeasure.getW();
+                childrenWidth += childWidth;
                 childrenHeight = Math.max(childrenHeight, childMeasure.getH());
                 visibleChildren++;
             }
         }
-        if (visibleChildren == 0) {
+        if (horizontalWrap && size != null) {
+            size.setWidth(Math.min(maxWidth, childrenWidth));
+        }
+        if (visibleChildren == 0 || (size != null && size.getWidth() <= 0f)) {
             self.addVisibilityOverride(Visibility.OVERRIDE_GONE);
         }
-        return changedVisibility;
     }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
index cda90c2..9566242 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/ColumnLayout.java
@@ -33,6 +33,7 @@
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size;
 import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.HeightInModifierOperation;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation;
 import com.android.internal.widget.remotecompose.core.operations.layout.utils.DebugLog;
 import com.android.internal.widget.remotecompose.core.serialize.MapSerializer;
 
@@ -372,6 +373,17 @@
         DebugLog.e();
     }
 
+    @Override
+    public void getLocationInWindow(@NonNull float[] value, boolean forSelf) {
+        super.getLocationInWindow(value, forSelf);
+
+        if (!forSelf && mVerticalScrollDelegate instanceof ScrollModifierOperation) {
+            ScrollModifierOperation smo = (ScrollModifierOperation) mVerticalScrollDelegate;
+
+            value[1] += smo.getScrollY();
+        }
+    }
+
     /**
      * The name of the class
      *
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
index 5b66b95..eb10ead 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/LayoutManager.java
@@ -226,9 +226,17 @@
                         measure,
                         mCachedWrapSize);
                 float w = mCachedWrapSize.getWidth();
-                computeSize(context, 0f, w, 0, measuredHeight, measure);
                 if (hasHorizontalScroll()) {
+                    computeSize(context, 0f, w, 0, measuredHeight, measure);
                     mComponentModifiers.setHorizontalScrollDimension(measuredWidth, w);
+                } else {
+                    computeSize(
+                            context,
+                            0f,
+                            Math.min(measuredWidth, insetMaxWidth),
+                            0,
+                            Math.min(measuredHeight, insetMaxHeight),
+                            measure);
                 }
             } else if (hasVerticalIntrinsicDimension()) {
                 mCachedWrapSize.setWidth(0f);
@@ -236,9 +244,17 @@
                 computeWrapSize(
                         context, maxWidth, Float.MAX_VALUE, false, false, measure, mCachedWrapSize);
                 float h = mCachedWrapSize.getHeight();
-                computeSize(context, 0f, measuredWidth, 0, h, measure);
                 if (hasVerticalScroll()) {
+                    computeSize(context, 0f, measuredWidth, 0, h, measure);
                     mComponentModifiers.setVerticalScrollDimension(measuredHeight, h);
+                } else {
+                    computeSize(
+                            context,
+                            0f,
+                            Math.min(measuredWidth, insetMaxWidth),
+                            0,
+                            Math.min(measuredHeight, insetMaxHeight),
+                            measure);
                 }
             } else {
                 float maxChildWidth = measuredWidth - mPaddingLeft - mPaddingRight;
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
index d5d2e03..15b54a3 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/RowLayout.java
@@ -32,6 +32,7 @@
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.ComponentMeasure;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.MeasurePass;
 import com.android.internal.widget.remotecompose.core.operations.layout.measure.Size;
+import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.ScrollModifierOperation;
 import com.android.internal.widget.remotecompose.core.operations.layout.modifiers.WidthInModifierOperation;
 import com.android.internal.widget.remotecompose.core.operations.layout.utils.DebugLog;
 import com.android.internal.widget.remotecompose.core.serialize.MapSerializer;
@@ -386,6 +387,17 @@
         DebugLog.e();
     }
 
+    @Override
+    public void getLocationInWindow(@NonNull float[] value, boolean forSelf) {
+        super.getLocationInWindow(value, forSelf);
+
+        if (!forSelf && mHorizontalScrollDelegate instanceof ScrollModifierOperation) {
+            ScrollModifierOperation smo = (ScrollModifierOperation) mHorizontalScrollDelegate;
+
+            value[0] += smo.getScrollX();
+        }
+    }
+
     /**
      * The name of the class
      *
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
index d383ee9..120c740 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/managers/TextLayout.java
@@ -77,6 +77,7 @@
     private final Size mCachedSize = new Size(0f, 0f);
 
     @Nullable private String mCachedString = "";
+    @Nullable private String mNewString;
 
     Platform.ComputedTextLayout mComputedTextLayout;
 
@@ -99,7 +100,7 @@
         if (cachedString != null && cachedString.equalsIgnoreCase(mCachedString)) {
             return;
         }
-        mCachedString = cachedString;
+        mNewString = cachedString;
         if (mType == -1) {
             if (mFontFamilyId != -1) {
                 String fontFamily = context.getText(mFontFamilyId);
@@ -119,8 +120,6 @@
                 mType = 0;
             }
         }
-        mTextW = -1;
-        mTextH = -1;
 
         if (mHorizontalScrollDelegate != null) {
             mHorizontalScrollDelegate.reset();
@@ -351,6 +350,9 @@
         mPaint.setColor(mColor);
         context.replacePaint(mPaint);
         float[] bounds = new float[4];
+        if (mNewString != null && !mNewString.equals(mCachedString)) {
+            mCachedString = mNewString;
+        }
         if (mCachedString == null) {
             return;
         }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/CollapsiblePriorityModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/CollapsiblePriorityModifierOperation.java
new file mode 100644
index 0000000..b1f2d2d
--- /dev/null
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/CollapsiblePriorityModifierOperation.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.widget.remotecompose.core.operations.layout.modifiers;
+
+import android.annotation.NonNull;
+
+import com.android.internal.widget.remotecompose.core.Operation;
+import com.android.internal.widget.remotecompose.core.Operations;
+import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.WireBuffer;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentationBuilder;
+import com.android.internal.widget.remotecompose.core.documentation.DocumentedOperation;
+import com.android.internal.widget.remotecompose.core.operations.utilities.StringSerializer;
+import com.android.internal.widget.remotecompose.core.serialize.MapSerializer;
+import com.android.internal.widget.remotecompose.core.serialize.Serializable;
+import com.android.internal.widget.remotecompose.core.serialize.SerializeTags;
+
+import java.util.List;
+
+/** Set an optional priority on a component within a collapsible layout */
+public class CollapsiblePriorityModifierOperation extends Operation
+        implements ModifierOperation, Serializable {
+    private static final int OP_CODE = Operations.MODIFIER_COLLAPSIBLE_PRIORITY;
+    public static final String CLASS_NAME = "CollapsiblePriorityModifierOperation";
+
+    private float mPriority;
+    private int mOrientation;
+
+    public CollapsiblePriorityModifierOperation(int orientation, float priority) {
+        mOrientation = orientation;
+        mPriority = priority;
+    }
+
+    public float getPriority() {
+        return mPriority;
+    }
+
+    public int getOrientation() {
+        return mOrientation;
+    }
+
+    @Override
+    public void write(@NonNull WireBuffer buffer) {
+        apply(buffer, mOrientation, mPriority);
+    }
+
+    @Override
+    public void apply(@NonNull RemoteContext context) {
+        // nothing
+    }
+
+    @NonNull
+    @Override
+    public String deepToString(@NonNull String indent) {
+        return "";
+    }
+
+    /**
+     * Read this operation and add it to the list of operations
+     *
+     * @param buffer the buffer to read
+     * @param operations the list of operations that will be added to
+     */
+    public static void read(@NonNull WireBuffer buffer, @NonNull List<Operation> operations) {
+        int orientation = buffer.readInt();
+        float priority = buffer.readFloat();
+        operations.add(new CollapsiblePriorityModifierOperation(orientation, priority));
+    }
+
+    /**
+     * The OP_CODE for this command
+     *
+     * @return the opcode
+     */
+    public static int id() {
+        return OP_CODE;
+    }
+
+    /**
+     * The name of the class
+     *
+     * @return the name
+     */
+    @NonNull
+    public static String name() {
+        return CLASS_NAME;
+    }
+
+    /**
+     * Populate the documentation with a description of this operation
+     *
+     * @param doc to append the description to.
+     */
+    public static void documentation(@NonNull DocumentationBuilder doc) {
+        doc.operation("Layout Operations", OP_CODE, "CollapsiblePriorityModifier")
+                .description("Add additional priority to children of Collapsible layouts")
+                .field(DocumentedOperation.INT, "orientation", "Horizontal(0) or Vertical (1)")
+                .field(DocumentedOperation.FLOAT, "priority", "The associated priority");
+    }
+
+    /**
+     * Writes out the CollapsiblePriorityModifier to the buffer
+     *
+     * @param buffer buffer to write to
+     * @param priority priority value
+     * @param orientation orientation (HORIZONTAL or VERTICAL)
+     */
+    public static void apply(@NonNull WireBuffer buffer, int orientation, float priority) {
+        buffer.start(OP_CODE);
+        buffer.writeInt(orientation);
+        buffer.writeFloat(priority);
+    }
+
+    @Override
+    public void serialize(MapSerializer serializer) {
+        serializer
+                .addTags(SerializeTags.MODIFIER)
+                .addType(name())
+                .add("orientation", mOrientation)
+                .add("priority", mPriority);
+    }
+
+    @Override
+    public void serializeToString(int indent, @NonNull StringSerializer serializer) {
+        serializer.append(indent, "PRIORITY = [" + getPriority() + "] (" + mOrientation + ")");
+    }
+}
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java
index 3e1f32d..42692f9 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/layout/modifiers/ScrollModifierOperation.java
@@ -430,9 +430,35 @@
     }
 
     @Override
-    public boolean showOnScreen(RemoteContext context, int childId) {
-        // TODO correct this when we trust the bounds in parent
-        return scrollByOffset(context, -1000) != 0;
+    public boolean scrollDirection(RemoteContext context, ScrollDirection direction) {
+        float offset = mHostDimension * 0.7f;
+
+        if (direction == ScrollDirection.FORWARD
+                || direction == ScrollDirection.DOWN
+                || direction == ScrollDirection.RIGHT) {
+            offset *= -1;
+        }
+
+        return scrollByOffset(context, (int) offset) != 0;
+    }
+
+    @Override
+    public boolean showOnScreen(RemoteContext context, Component child) {
+        float[] locationInWindow = new float[2];
+        child.getLocationInWindow(locationInWindow);
+
+        int offset = 0;
+        if (handlesVerticalScroll()) {
+            offset = (int) -locationInWindow[1];
+        } else {
+            offset = (int) -locationInWindow[0];
+        }
+
+        if (offset == 0) {
+            return true;
+        } else {
+            return scrollByOffset(context, offset) != 0;
+        }
     }
 
     @Nullable
diff --git a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java
index a95a175..120c7ac 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/operations/utilities/StringUtils.java
@@ -35,7 +35,10 @@
     @NonNull
     public static String floatToString(
             float value, int beforeDecimalPoint, int afterDecimalPoint, char pre, char post) {
-
+        boolean isNeg = value < 0;
+        if (isNeg) {
+            value = -value;
+        }
         int integerPart = (int) value;
         float fractionalPart = value % 1;
 
@@ -54,14 +57,13 @@
             integerPartString = integerPartString.substring(iLen - beforeDecimalPoint);
         }
         if (afterDecimalPoint == 0) {
-            return integerPartString;
+            return ((isNeg) ? "-" : "") + integerPartString;
         }
         // Convert fractional part to string and pad with zeros
 
         for (int i = 0; i < afterDecimalPoint; i++) {
             fractionalPart *= 10;
         }
-
         fractionalPart = Math.round(fractionalPart);
 
         for (int i = 0; i < afterDecimalPoint; i++) {
@@ -87,6 +89,6 @@
             fact = fact + new String(c);
         }
 
-        return integerPartString + "." + fact;
+        return ((isNeg) ? "-" : "") + integerPartString + "." + fact;
     }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/semantics/ScrollableComponent.java b/core/java/com/android/internal/widget/remotecompose/core/semantics/ScrollableComponent.java
index 3d1bd12..1610e63 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/semantics/ScrollableComponent.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/semantics/ScrollableComponent.java
@@ -18,6 +18,7 @@
 import android.annotation.Nullable;
 
 import com.android.internal.widget.remotecompose.core.RemoteContext;
+import com.android.internal.widget.remotecompose.core.operations.layout.Component;
 
 /**
  * Interface for components that support scrolling.
@@ -48,13 +49,23 @@
     }
 
     /**
+     * Scrolls the content in the specified direction.
+     *
+     * @param direction the direction to scroll
+     * @return whether a scroll was possible
+     */
+    default boolean scrollDirection(RemoteContext context, ScrollDirection direction) {
+        return false;
+    }
+
+    /**
      * Show a child with the given ID on the screen, typically scrolling so it's fully on screen.
      *
-     * @param childId The ID of the child to check for visibility.
+     * @param child The child (including nested) to check for visibility.
      * @return {@code true} if the child with the given ID could be shown on screen; {@code false}
      *     otherwise.
      */
-    default boolean showOnScreen(RemoteContext context, int childId) {
+    default boolean showOnScreen(RemoteContext context, Component child) {
         return false;
     }
 
@@ -108,4 +119,13 @@
             return mCanScrollBackwards;
         }
     }
+
+    enum ScrollDirection {
+        FORWARD,
+        BACKWARD,
+        UP,
+        DOWN,
+        LEFT,
+        RIGHT,
+    }
 }
diff --git a/core/java/com/android/internal/widget/remotecompose/core/serialize/MapSerializer.java b/core/java/com/android/internal/widget/remotecompose/core/serialize/MapSerializer.java
index 20e94ab..32a0ccc 100644
--- a/core/java/com/android/internal/widget/remotecompose/core/serialize/MapSerializer.java
+++ b/core/java/com/android/internal/widget/remotecompose/core/serialize/MapSerializer.java
@@ -49,6 +49,14 @@
     MapSerializer addIntExpressionSrc(String key, int[] value, int mask);
 
     /**
+     * Add a path
+     *
+     * @param key The key
+     * @param path The path
+     */
+    MapSerializer addPath(String key, float[] path);
+
+    /**
      * Add metadata to this map for filtering by the data format generator.
      *
      * @param value A set of tags to add
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
index e1f2924..575a6b2 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/AndroidRemoteContext.java
@@ -22,7 +22,6 @@
 import android.graphics.Canvas;
 import android.graphics.Paint;
 
-import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.widget.remotecompose.core.RemoteContext;
 import com.android.internal.widget.remotecompose.core.TouchListener;
 import com.android.internal.widget.remotecompose.core.VariableSupport;
@@ -43,7 +42,6 @@
  *
  * <p>This is used to play the RemoteCompose operations on Android.
  */
-@VisibleForTesting
 public class AndroidRemoteContext extends RemoteContext {
 
     public void useCanvas(Canvas canvas) {
diff --git a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
index 0bc99ab..e76fb06 100644
--- a/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
+++ b/core/java/com/android/internal/widget/remotecompose/player/platform/RemoteComposeCanvas.java
@@ -42,6 +42,9 @@
 public class RemoteComposeCanvas extends FrameLayout implements View.OnAttachStateChangeListener {
 
     static final boolean USE_VIEW_AREA_CLICK = true; // Use views to represent click areas
+    static final float DEFAULT_FRAME_RATE = 60f;
+    static final float POST_TO_NEXT_FRAME_THRESHOLD = 60f;
+
     RemoteComposeDocument mDocument = null;
     int mTheme = Theme.LIGHT;
     boolean mInActionDown = false;
@@ -53,9 +56,11 @@
     long mStart = System.nanoTime();
 
     long mLastFrameDelay = 1;
-    float mMaxFrameRate = 60f; // frames per seconds
+    float mMaxFrameRate = DEFAULT_FRAME_RATE; // frames per seconds
     long mMaxFrameDelay = (long) (1000 / mMaxFrameRate);
 
+    long mLastFrameCall = System.currentTimeMillis();
+
     private Choreographer mChoreographer;
     private Choreographer.FrameCallback mFrameCallback =
             new Choreographer.FrameCallback() {
@@ -100,8 +105,10 @@
 
     public void setDocument(RemoteComposeDocument value) {
         mDocument = value;
+        mMaxFrameRate = DEFAULT_FRAME_RATE;
         mDocument.initializeContext(mARContext);
         mDisable = false;
+        mARContext.setDocLoadTime();
         mARContext.setAnimationEnabled(true);
         mARContext.setDensity(mDensity);
         mARContext.setUseChoreographer(true);
@@ -545,8 +552,25 @@
             }
             int nextFrame = mDocument.needsRepaint();
             if (nextFrame > 0) {
-                mLastFrameDelay = Math.max(mMaxFrameDelay, nextFrame);
+                if (mMaxFrameRate >= POST_TO_NEXT_FRAME_THRESHOLD) {
+                    mLastFrameDelay = nextFrame;
+                } else {
+                    mLastFrameDelay = Math.max(mMaxFrameDelay, nextFrame);
+                }
                 if (mChoreographer != null) {
+                    if (mDebug == 1) {
+                        System.err.println(
+                                "RC : POST CHOREOGRAPHER WITH "
+                                        + mLastFrameDelay
+                                        + " (nextFrame was "
+                                        + nextFrame
+                                        + ", max delay "
+                                        + mMaxFrameDelay
+                                        + ", "
+                                        + " max framerate is "
+                                        + mMaxFrameRate
+                                        + ")");
+                    }
                     mChoreographer.postFrameCallbackDelayed(mFrameCallback, mLastFrameDelay);
                 }
                 if (!mARContext.useChoreographer()) {
@@ -566,6 +590,16 @@
             mDisable = true;
             invalidate();
         }
+        if (mDebug == 1) {
+            long frameDelay = System.currentTimeMillis() - mLastFrameCall;
+            System.err.println(
+                    "RC : Delay since last frame "
+                            + frameDelay
+                            + " ms ("
+                            + (1000f / (float) frameDelay)
+                            + " fps)");
+            mLastFrameCall = System.currentTimeMillis();
+        }
     }
 
     private void drawDisable(Canvas canvas) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 748c5b4..bfa0aa9 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -31,6 +31,7 @@
     name: "libandroid_runtime",
     host_supported: true,
     cflags: [
+        "-Wno-cast-function-type-mismatch",
         "-Wno-unused-parameter",
         "-Wno-non-virtual-dtor",
         "-Wno-maybe-uninitialized",
diff --git a/core/jni/android_os_Parcel.cpp b/core/jni/android_os_Parcel.cpp
index dec724b..e1b3479 100644
--- a/core/jni/android_os_Parcel.cpp
+++ b/core/jni/android_os_Parcel.cpp
@@ -558,8 +558,7 @@
     delete parcel;
 }
 
-static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr)
-{
+static Parcel* parcel_for_marshall(JNIEnv* env, jlong nativePtr) {
     Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
     if (parcel == NULL) {
        return NULL;
@@ -577,6 +576,16 @@
         return NULL;
     }
 
+    return parcel;
+}
+
+static jbyteArray android_os_Parcel_marshall(JNIEnv* env, jclass clazz, jlong nativePtr)
+{
+    Parcel* parcel = parcel_for_marshall(env, nativePtr);
+    if (parcel == NULL) {
+       return NULL;
+    }
+
     jbyteArray ret = env->NewByteArray(parcel->dataSize());
 
     if (ret != NULL)
@@ -592,6 +601,56 @@
     return ret;
 }
 
+static long ensure_capacity(JNIEnv* env, Parcel* parcel, jint remaining) {
+    long dataSize = parcel->dataSize();
+    if (remaining < dataSize) {
+        jnihelp::ThrowException(env, "java/nio/BufferOverflowException", "()V");
+        return -1;
+    }
+    return dataSize;
+}
+
+static int android_os_Parcel_marshall_array(JNIEnv* env, jclass clazz, jlong nativePtr,
+                                            jbyteArray data, jint offset, jint remaining)
+{
+    Parcel* parcel = parcel_for_marshall(env, nativePtr);
+    if (parcel == NULL) {
+       return 0;
+    }
+
+    long data_size = ensure_capacity(env, parcel, remaining);
+    if (data_size < 0) {
+        return 0;
+    }
+
+    jbyte* array = (jbyte*)env->GetPrimitiveArrayCritical(data, 0);
+    if (array != NULL)
+    {
+        memcpy(array + offset, parcel->data(), data_size);
+        env->ReleasePrimitiveArrayCritical(data, array, 0);
+    }
+    return data_size;
+}
+
+static int android_os_Parcel_marshall_buffer(JNIEnv* env, jclass clazz, jlong nativePtr,
+                                             jobject javaBuffer, jint offset, jint remaining) {
+    Parcel* parcel = parcel_for_marshall(env, nativePtr);
+    if (parcel == NULL) {
+       return 0;
+    }
+
+    long data_size = ensure_capacity(env, parcel, remaining);
+    if (data_size < 0) {
+        return 0;
+    }
+
+    jbyte* buffer = (jbyte*)env->GetDirectBufferAddress(javaBuffer);
+    if (buffer != NULL) {
+        memcpy(buffer + offset, parcel->data(), data_size);
+    }
+    return data_size;
+}
+
 static void android_os_Parcel_unmarshall(JNIEnv* env, jclass clazz, jlong nativePtr,
                                           jbyteArray data, jint offset, jint length)
 {
@@ -613,6 +672,25 @@
     }
 }
 
+static void android_os_Parcel_unmarshall_buffer(JNIEnv* env, jclass clazz, jlong nativePtr,
+                                                jobject javaBuffer, jint offset, jint length)
+{
+    Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
+    if (parcel == NULL || length < 0) {
+       return;
+    }
+
+    jbyte* buffer = (jbyte*)env->GetDirectBufferAddress(javaBuffer);
+    if (buffer)
+    {
+        parcel->setDataSize(length);
+        parcel->setDataPosition(0);
+
+        void* raw = parcel->writeInplace(length);
+        memcpy(raw, (buffer + offset), length);
+    }
+}
+
 static jint android_os_Parcel_compareData(JNIEnv* env, jclass clazz, jlong thisNativePtr,
                                           jlong otherNativePtr)
 {
@@ -911,7 +989,10 @@
     {"nativeDestroy",             "(J)V", (void*)android_os_Parcel_destroy},
 
     {"nativeMarshall",            "(J)[B", (void*)android_os_Parcel_marshall},
+    {"nativeMarshallArray",       "(J[BII)I", (void*)android_os_Parcel_marshall_array},
+    {"nativeMarshallBuffer",      "(JLjava/nio/ByteBuffer;II)I", (void*)android_os_Parcel_marshall_buffer},
     {"nativeUnmarshall",          "(J[BII)V", (void*)android_os_Parcel_unmarshall},
+    {"nativeUnmarshallBuffer",    "(JLjava/nio/ByteBuffer;II)V", (void*)android_os_Parcel_unmarshall_buffer},
     {"nativeCompareData",         "(JJ)I", (void*)android_os_Parcel_compareData},
     {"nativeCompareDataInRange",  "(JIJII)Z", (void*)android_os_Parcel_compareDataInRange},
     {"nativeAppendFrom",          "(JJII)V", (void*)android_os_Parcel_appendFrom},
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index a0c8f30..36bda61 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -73,6 +73,7 @@
     jmethodID mExecTransact;
     jmethodID mGetInterfaceDescriptor;
     jmethodID mTransactionCallback;
+    jmethodID mGetExtension;
 
     // Object state.
     jfieldID mObject;
@@ -488,8 +489,12 @@
             if (mVintf) {
                 ::android::internal::Stability::markVintf(b.get());
             }
-            if (mExtension != nullptr) {
-                b.get()->setExtension(mExtension);
+            if (mSetExtensionCalled) {
+                jobject javaIBinderObject = env->CallObjectMethod(obj, gBinderOffsets.mGetExtension);
+                sp<IBinder> extensionFromJava = ibinderForJavaObject(env, javaIBinderObject);
+                if (extensionFromJava != nullptr) {
+                    b.get()->setExtension(extensionFromJava);
+                }
             }
             mBinder = b;
             ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
@@ -515,21 +520,12 @@
         mVintf = false;
     }
 
-    sp<IBinder> getExtension() {
-        AutoMutex _l(mLock);
-        sp<JavaBBinder> b = mBinder.promote();
-        if (b != nullptr) {
-            return b.get()->getExtension();
-        }
-        return mExtension;
-    }
-
     void setExtension(const sp<IBinder>& extension) {
         AutoMutex _l(mLock);
-        mExtension = extension;
+        mSetExtensionCalled = true;
         sp<JavaBBinder> b = mBinder.promote();
         if (b != nullptr) {
-            b.get()->setExtension(mExtension);
+            b.get()->setExtension(extension);
         }
     }
 
@@ -541,8 +537,7 @@
     // is too much binder state here, we can think about making JavaBBinder an
     // sp here (avoid recreating it)
     bool            mVintf = false;
-
-    sp<IBinder>     mExtension;
+    bool            mSetExtensionCalled = false;
 };
 
 // ----------------------------------------------------------------------------
@@ -1254,10 +1249,6 @@
     return IPCThreadState::self()->blockUntilThreadAvailable();
 }
 
-static jobject android_os_Binder_getExtension(JNIEnv* env, jobject obj) {
-    JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
-    return javaObjectForIBinder(env, jbh->getExtension());
-}
 
 static void android_os_Binder_setExtension(JNIEnv* env, jobject obj, jobject extensionObject) {
     JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
@@ -1300,8 +1291,7 @@
     { "getNativeBBinderHolder", "()J", (void*)android_os_Binder_getNativeBBinderHolder },
     { "getNativeFinalizer", "()J", (void*)android_os_Binder_getNativeFinalizer },
     { "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable },
-    { "getExtension", "()Landroid/os/IBinder;", (void*)android_os_Binder_getExtension },
-    { "setExtension", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
+    { "setExtensionNative", "(Landroid/os/IBinder;)V", (void*)android_os_Binder_setExtension },
 };
 // clang-format on
 
@@ -1318,6 +1308,8 @@
     gBinderOffsets.mTransactionCallback =
             GetStaticMethodIDOrDie(env, clazz, "transactionCallback", "(IIII)V");
     gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
+    gBinderOffsets.mGetExtension = GetMethodIDOrDie(env, clazz, "getExtension",
+                                                        "()Landroid/os/IBinder;");
 
     return RegisterMethodsOrDie(
         env, kBinderPathName,
diff --git a/core/jni/android_window_InputTransferToken.cpp b/core/jni/android_window_InputTransferToken.cpp
index f92d128..b4efacb 100644
--- a/core/jni/android_window_InputTransferToken.cpp
+++ b/core/jni/android_window_InputTransferToken.cpp
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-#undef ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION // TODO:remove this and fix code
 
 #define LOG_TAG "InputTransferToken"
 
@@ -53,7 +52,7 @@
 }
 
 static void nativeWriteToParcel(JNIEnv* env, jclass clazz, jlong nativeObj, jobject parcelObj) {
-    InputTransferToken* inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
+    auto inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
     Parcel* parcel = parcelForJavaObject(env, parcelObj);
     inputTransferToken->writeToParcel(parcel);
 }
@@ -67,12 +66,12 @@
 }
 
 static jobject nativeGetBinderToken(JNIEnv* env, jclass clazz, jlong nativeObj) {
-    sp<InputTransferToken> inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
+    auto inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
     return javaObjectForIBinder(env, inputTransferToken->mToken);
 }
 
 static jlong nativeGetBinderTokenRef(JNIEnv*, jclass, jlong nativeObj) {
-    sp<InputTransferToken> inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
+    auto inputTransferToken = reinterpret_cast<InputTransferToken*>(nativeObj);
     return reinterpret_cast<jlong>(inputTransferToken->mToken.get());
 }
 
@@ -105,12 +104,9 @@
 
 static bool nativeEquals(JNIEnv* env, jclass clazz, jlong inputTransferTokenObj1,
                          jlong inputTransferTokenObj2) {
-    sp<InputTransferToken> inputTransferToken1(
-            reinterpret_cast<InputTransferToken*>(inputTransferTokenObj1));
-    sp<InputTransferToken> inputTransferToken2(
-            reinterpret_cast<InputTransferToken*>(inputTransferTokenObj2));
-
-    return inputTransferToken1 == inputTransferToken2;
+    auto token1 = reinterpret_cast<InputTransferToken*>(inputTransferTokenObj1);
+    auto token2 = reinterpret_cast<InputTransferToken*>(inputTransferTokenObj2);
+    return (token1 != nullptr) && (token2 != nullptr) && (*token1 == *token2);
 }
 
 static const JNINativeMethod sInputTransferTokenMethods[] = {
diff --git a/core/jni/android_window_ScreenCapture.cpp b/core/jni/android_window_ScreenCapture.cpp
index 7b085b1..ba74b0e 100644
--- a/core/jni/android_window_ScreenCapture.cpp
+++ b/core/jni/android_window_ScreenCapture.cpp
@@ -109,27 +109,29 @@
             return binder::Status::ok();
         }
         captureResults.fenceResult.value()->waitForever(LOG_TAG);
-        jobject jhardwareBuffer = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
-                env, captureResults.buffer->toAHardwareBuffer());
-        jobject jGainmap = nullptr;
+        auto jhardwareBuffer = ScopedLocalRef<jobject>(
+                env, android_hardware_HardwareBuffer_createFromAHardwareBuffer(
+                        env, captureResults.buffer->toAHardwareBuffer()));
+        auto jGainmap = ScopedLocalRef<jobject>(env);
         if (captureResults.optionalGainMap) {
-            jGainmap = android_hardware_HardwareBuffer_createFromAHardwareBuffer(
-                    env, captureResults.optionalGainMap->toAHardwareBuffer());
+            jGainmap = ScopedLocalRef<jobject>(
+                    env, android_hardware_HardwareBuffer_createFromAHardwareBuffer(
+                            env, captureResults.optionalGainMap->toAHardwareBuffer()));
         }
-        jobject screenshotHardwareBuffer =
-                env->CallStaticObjectMethod(gScreenshotHardwareBufferClassInfo.clazz,
+        auto screenshotHardwareBuffer =
+                ScopedLocalRef<jobject>(env, env->CallStaticObjectMethod(
+                                            gScreenshotHardwareBufferClassInfo.clazz,
                                             gScreenshotHardwareBufferClassInfo.builder,
-                                            jhardwareBuffer,
+                                            jhardwareBuffer.get(),
                                             static_cast<jint>(captureResults.capturedDataspace),
                                             captureResults.capturedSecureLayers,
-                                            captureResults.capturedHdrLayers, jGainmap,
-                                            captureResults.hdrSdrRatio);
+                                            captureResults.capturedHdrLayers, jGainmap.get(),
+                                            captureResults.hdrSdrRatio));
         checkAndClearException(env, "builder");
-        env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept, screenshotHardwareBuffer,
+        env->CallVoidMethod(consumer.get(), gConsumerClassInfo.accept,
+                            screenshotHardwareBuffer.get(),
                             fenceStatus(captureResults.fenceResult));
         checkAndClearException(env, "accept");
-        env->DeleteLocalRef(jhardwareBuffer);
-        env->DeleteLocalRef(screenshotHardwareBuffer);
         return binder::Status::ok();
     }
 
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 59e01bf..9df351f 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -35,7 +35,6 @@
 import "frameworks/base/core/proto/android/providers/settings.proto";
 import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
 import "frameworks/base/core/proto/android/server/alarm/alarmmanagerservice.proto";
-import "frameworks/base/core/proto/android/server/bluetooth_manager_service.proto";
 import "frameworks/base/core/proto/android/server/fingerprint.proto";
 import "frameworks/base/core/proto/android/server/jobscheduler.proto";
 import "frameworks/base/core/proto/android/server/location/context_hub.proto";
@@ -483,10 +482,8 @@
         (section).args = "connmetrics --proto"
     ];
 
-    optional com.android.server.BluetoothManagerServiceDumpProto bluetooth_manager = 3050 [
-        (section).type = SECTION_DUMPSYS,
-        (section).args = "bluetooth_manager --proto"
-    ];
+    // Deprecated BluetoothManagerServiceDumpProto
+    reserved 3050;
 
     optional com.android.server.location.ContextHubServiceProto context_hub = 3051 [
         (section).type = SECTION_DUMPSYS,
diff --git a/core/proto/android/providers/settings/system.proto b/core/proto/android/providers/settings/system.proto
index 325790c..8393f8b 100644
--- a/core/proto/android/providers/settings/system.proto
+++ b/core/proto/android/providers/settings/system.proto
@@ -290,7 +290,16 @@
 
     optional SettingProto apply_ramping_ringer = 35 [ (android.privacy).dest = DEST_AUTOMATIC ];
 
+    message Display {
+        option (android.msg_privacy).dest = DEST_EXPLICIT;
+
+        optional SettingProto cv_enabled = 1 [ (android.privacy).dest = DEST_AUTOMATIC ];
+    }
+    optional Display display = 39;
+
+
+
     // Please insert fields in alphabetical order and group them into messages
     // if possible (to avoid reaching the method limit).
-    // Next tag = 39;
+    // Next tag = 40;
 }
diff --git a/core/proto/android/server/Android.bp b/core/proto/android/server/Android.bp
deleted file mode 100644
index 362daa7..0000000
--- a/core/proto/android/server/Android.bp
+++ /dev/null
@@ -1,28 +0,0 @@
-//
-// Copyright (C) 2021 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-//      http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-
-package {
-    default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
-filegroup {
-  name: "srcs_bluetooth_manager_service_proto",
-  srcs: [
-      "bluetooth_manager_service.proto",
-  ],
-  visibility: ["//packages/modules/Bluetooth:__subpackages__"],
-}
-
diff --git a/core/proto/android/server/bluetooth_manager_service.proto b/core/proto/android/server/bluetooth_manager_service.proto
deleted file mode 100644
index c33f66a..0000000
--- a/core/proto/android/server/bluetooth_manager_service.proto
+++ /dev/null
@@ -1,49 +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.
- */
-
-syntax = "proto2";
-package com.android.server;
-
-import "frameworks/base/core/proto/android/privacy.proto";
-import "frameworks/proto_logging/stats/enums/bluetooth/enums.proto";
-
-option java_multiple_files = true;
-
-message BluetoothManagerServiceDumpProto {
-   option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-
-   message ActiveLog {
-      option (.android.msg_privacy).dest = DEST_AUTOMATIC;
-      optional int64 timestamp_ms = 1;
-      optional bool enable = 2;
-      optional string package_name = 3;
-      optional .android.bluetooth.EnableDisableReasonEnum reason = 4;
-   }
-
-   optional bool enabled = 1;
-   optional int32 state = 2;
-   optional string state_name = 3;
-   optional string address = 4 [(.android.privacy).dest = DEST_EXPLICIT];
-   optional string name = 5 [(.android.privacy).dest = DEST_EXPLICIT];
-   optional int64 last_enabled_time_ms = 6;
-   optional int64 curr_timestamp_ms = 7;
-   repeated ActiveLog active_logs = 8;
-   optional int32 num_crashes = 9;
-   optional bool crash_log_maxed = 10;
-   repeated int64 crash_timestamps_ms = 11;
-   optional int32 num_ble_apps = 12;
-   repeated string ble_app_package_names = 13;
-}
\ No newline at end of file
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e16ce98..9e02004 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5394,13 +5394,13 @@
          corresponding permission such as {@link #HEAD_TRACKING} or
          {@link #FACE_TRACKING} for the data being accessed.
 
-         <p>Protection level: normal|appop
+         <p>Protection level: signature|privileged
 
          @SystemApi
          @FlaggedApi(android.xr.Flags.FLAG_XR_MANIFEST_ENTRIES)
          @hide -->
     <permission android:name="android.permission.XR_TRACKING_IN_BACKGROUND"
-                android:protectionLevel="normal|appop"
+                android:protectionLevel="signature|privileged"
                 android:description="@string/permdesc_xr_tracking_in_background"
                 android:label="@string/permlab_xr_tracking_in_background"
                 android:featureFlag="android.xr.xr_manifest_entries" />
diff --git a/core/res/res/color/notification_close_button_state_tint.xml b/core/res/res/color/notification_close_button_state_tint.xml
new file mode 100644
index 0000000..bc42ceb
--- /dev/null
+++ b/core/res/res/color/notification_close_button_state_tint.xml
@@ -0,0 +1,19 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, softwarere
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT 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="@color/notification_expand_button_state_tint" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/drawable-w192dp/loader_horizontal_watch.xml b/core/res/res/drawable-w192dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..18cea6e
--- /dev/null
+++ b/core/res/res/drawable-w192dp/loader_horizontal_watch.xml
@@ -0,0 +1,97 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="15dp" android:width="67dp" android:viewportHeight="15" android:viewportWidth="67">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_1_G" android:translateX="33.5" android:translateY="7.5">
+                    <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M33.5 -7.5 C33.5,-7.5 33.5,7.5 33.5,7.5 C33.5,7.5 -33.5,7.5 -33.5,7.5 C-33.5,7.5 -33.5,-7.5 -33.5,-7.5 C-33.5,-7.5 33.5,-7.5 33.5,-7.5c "/>
+                </group>
+                <group android:name="_R_G_L_0_G" android:translateX="-296.5" android:translateY="-62.5" android:pivotX="330" android:pivotY="70" android:scaleX="0.1" android:scaleY="0.1">
+                    <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-224.84700000000004" android:translateY="-321.948" android:pivotX="555.09" android:pivotY="-329" android:rotation="28.9" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M194.88 359 C190,359 185.05,357.81 180.48,355.3 C59.86,289.14 -41.55,191.9 -112.79,74.11 C-186.14,-47.16 -224.91,-186.55 -224.91,-329 C-224.91,-345.57 -211.48,-359 -194.91,-359 C-178.34,-359 -164.91,-345.57 -164.91,-329 C-164.91,-197.5 -129.13,-68.84 -61.45,43.06 C4.33,151.82 97.97,241.6 209.33,302.69 C223.86,310.66 229.18,328.9 221.21,343.42 C215.75,353.37 205.48,359 194.88,359c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_5_G" android:translateX="744.323" android:translateY="-277.96299999999997" android:pivotX="-414.08" android:pivotY="-372.985" android:rotation="28.9">
+                        <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-335.95 402.99 C-351.13,402.99 -364.16,391.5 -365.76,376.07 C-367.46,359.59 -355.49,344.85 -339.01,343.14 C-162.93,324.91 -0.15,242.33 119.34,110.62 C239.66,-22.01 305.92,-193.76 305.92,-372.98 C305.92,-389.55 319.35,-402.98 335.92,-402.98 C352.49,-402.98 365.92,-389.55 365.92,-372.98 C365.92,-178.82 294.13,7.24 163.78,150.93 C34.34,293.61 -142.03,383.07 -332.83,402.82 C-333.88,402.93 -334.92,402.99 -335.95,402.99c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_2_G" android:translateX="185.385" android:translateY="70.09100000000001" android:pivotX="144.858" android:pivotY="-721.039" android:rotation="28.9" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M144.62 58.96 C144.61,58.96 144.61,58.96 144.6,58.96 C40.39,58.93 -60.82,38.66 -156.19,-1.28 C-171.48,-7.68 -178.68,-25.26 -172.28,-40.54 C-165.88,-55.82 -148.3,-63.02 -133.02,-56.62 C-45.02,-19.77 48.4,-1.07 144.63,-1.04 C161.19,-1.03 174.62,12.4 174.62,28.97 C174.61,45.53 161.18,58.96 144.62,58.96c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_0_G" android:translateX="330" android:translateY="70">
+                        <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-660 -313 C-660,-313 -660,313 -660,313 C-660,313 660,313 660,313 C660,313 660,-313 660,-313 C660,-313 -660,-313 -660,-313c  M300.74 -1.16 C205.46,38.62 103.22,59.09 -0.03,59.05 C-103.28,59.01 -205.51,38.48 -300.76,-1.37 C-316.05,-7.76 -323.26,-25.34 -316.86,-40.62 C-310.47,-55.91 -292.9,-63.12 -277.61,-56.72 C-189.68,-19.94 -95.32,-0.98 -0.01,-0.95 C95.3,-0.92 189.67,-19.81 277.63,-56.53 C292.92,-62.91 310.49,-55.69 316.87,-40.4 C323.25,-25.11 316.03,-7.54 300.74,-1.16c "/>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.9" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.135 0.202,0.848 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
+
diff --git a/core/res/res/drawable-w204dp/loader_horizontal_watch.xml b/core/res/res/drawable-w204dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..fbc6eab
--- /dev/null
+++ b/core/res/res/drawable-w204dp/loader_horizontal_watch.xml
@@ -0,0 +1,104 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="15dp" android:width="70dp" android:viewportHeight="15" android:viewportWidth="70">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_1_G" android:translateX="35" android:translateY="7.5">
+                    <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M35 -7.5 C35,-7.5 35,7.5 35,7.5 C35,7.5 -35,7.5 -35,7.5 C-35,7.5 -35,-7.5 -35,-7.5 C-35,-7.5 35,-7.5 35,-7.5c "/>
+                </group>
+                <group android:name="_R_G_L_0_G" android:translateX="-310" android:translateY="-64" android:pivotX="345" android:pivotY="71.5" android:scaleX="0.1" android:scaleY="0.1">
+                    <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-239.44799999999998" android:translateY="-341.45" android:pivotX="584.448" android:pivotY="-346.55" android:rotation="28.8" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M205.28 376.55 C200.4,376.55 195.46,375.36 190.88,372.85 C64.08,303.29 -42.54,201.07 -117.44,77.24 C-194.55,-50.25 -235.31,-196.79 -235.31,-346.55 C-235.31,-363.12 -221.88,-376.55 -205.31,-376.55 C-188.74,-376.55 -175.31,-363.12 -175.31,-346.55 C-175.31,-207.74 -137.54,-71.93 -66.1,46.19 C3.34,160.99 102.18,255.76 219.73,320.24 C234.26,328.21 239.58,346.45 231.61,360.97 C226.15,370.92 215.88,376.55 205.28,376.55c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_5_G" android:translateX="781.413" android:translateY="-295.124" android:pivotX="-436.413" android:pivotY="-392.876" android:rotation="28.8">
+                        <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-353.86 422.88 C-369.04,422.88 -382.07,411.4 -383.67,395.97 C-385.37,379.49 -373.4,364.74 -356.92,363.03 C-171.06,343.79 0.76,256.62 126.89,117.59 C253.89,-22.41 323.83,-203.7 323.83,-392.88 C323.83,-409.44 337.26,-422.88 353.83,-422.88 C370.4,-422.88 383.83,-409.44 383.83,-392.88 C383.83,-188.76 308.36,6.84 171.32,157.9 C35.25,307.89 -150.15,401.94 -350.74,422.72 C-351.79,422.82 -352.83,422.88 -353.86,422.88c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_2_G" android:translateX="192.671" android:translateY="71.49599999999998" android:pivotX="152.329" android:pivotY="-759.496" android:rotation="28.8" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M152.33 60.5 C152.33,60.5 152.32,60.5 152.32,60.5 C42.76,60.47 -63.64,39.16 -163.91,-2.82 C-179.19,-9.22 -186.39,-26.8 -179.99,-42.08 C-173.59,-57.36 -156.02,-64.57 -140.73,-58.16 C-47.84,-19.27 50.77,0.47 152.34,0.5 C168.91,0.51 182.33,13.94 182.33,30.51 C182.32,47.08 168.89,60.5 152.33,60.5c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_0_G" android:translateX="345" android:translateY="71.5">
+                        <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-579 -259.5 C-579,-259.5 -579,259.5 -579,259.5 C-579,259.5 579,259.5 579,259.5 C579,259.5 579,-259.5 579,-259.5 C579,-259.5 -579,-259.5 -579,-259.5c  M316.17 -2.8 C216,39.02 108.52,60.54 -0.03,60.5 C-108.58,60.46 -216.04,38.87 -316.18,-3.02 C-331.47,-9.41 -338.68,-26.99 -332.28,-42.27 C-325.89,-57.56 -308.32,-64.76 -293.03,-58.37 C-200.22,-19.55 -100.61,0.46 -0.01,0.5 C100.6,0.54 200.22,-19.41 293.06,-58.17 C308.35,-64.55 325.92,-57.33 332.3,-42.04 C338.68,-26.75 331.46,-9.18 316.17,-2.8c "/>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
+
diff --git a/core/res/res/drawable-w216dp/loader_horizontal_watch.xml b/core/res/res/drawable-w216dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..ed4b7ea
--- /dev/null
+++ b/core/res/res/drawable-w216dp/loader_horizontal_watch.xml
@@ -0,0 +1,105 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="16dp" android:width="74dp" android:viewportHeight="16" android:viewportWidth="74">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_1_G" android:translateX="37" android:translateY="8">
+                    <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M37 -8 C37,-8 37,8 37,8 C37,8 -37,8 -37,8 C-37,8 -37,-8 -37,-8 C-37,-8 37,-8 37,-8c "/>
+                </group>
+                <group android:name="_R_G_L_0_G" android:translateX="-328" android:translateY="-65.5" android:pivotX="365" android:pivotY="73.5" android:scaleX="0.1" android:scaleY="0.1">
+                    <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-256.447" android:translateY="-365.014" android:pivotX="621.447" android:pivotY="-368.486" android:rotation="28.8" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M218.28 398.49 C213.4,398.49 208.46,397.3 203.88,394.78 C69.34,320.99 -43.78,212.53 -123.25,81.15 C-205.06,-54.11 -248.31,-209.59 -248.31,-368.49 C-248.31,-385.05 -234.88,-398.49 -218.31,-398.49 C-201.74,-398.49 -188.31,-385.05 -188.31,-368.49 C-188.31,-220.54 -148.06,-75.8 -71.91,50.09 C2.1,172.45 107.45,273.45 232.73,342.18 C247.26,350.15 252.58,368.38 244.61,382.91 C239.15,392.86 228.88,398.49 218.28,398.49c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_5_G" android:translateX="829.0260000000001" android:translateY="-315.759" android:pivotX="-464.026" android:pivotY="-417.741" android:rotation="28.8">
+                        <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-376.25 447.74 C-391.43,447.74 -404.46,436.26 -406.05,420.83 C-407.76,404.35 -395.78,389.61 -379.3,387.9 C-181.22,367.38 1.9,274.48 136.32,126.3 C271.67,-22.9 346.22,-216.12 346.22,-417.74 C346.22,-434.31 359.65,-447.74 376.22,-447.74 C392.79,-447.74 406.22,-434.31 406.22,-417.74 C406.22,-201.18 326.15,6.35 180.76,166.61 C36.39,325.75 -160.31,425.54 -373.12,447.58 C-374.17,447.69 -375.22,447.74 -376.25,447.74c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_2_G" android:translateX="203.029" android:translateY="74.06899999999996" android:pivotX="161.971" android:pivotY="-807.569" android:rotation="28.8" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M161.97 62.43 C161.97,62.43 161.96,62.43 161.96,62.43 C45.71,62.4 -67.17,39.79 -173.55,-4.75 C-188.83,-11.15 -196.03,-28.72 -189.63,-44.01 C-183.24,-59.29 -165.66,-66.49 -150.38,-60.09 C-51.37,-18.64 53.72,2.4 161.98,2.43 C178.55,2.44 191.98,15.87 191.97,32.44 C191.97,49 178.54,62.43 161.97,62.43c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_0_G" android:translateX="365" android:translateY="73.5">
+                        <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-609 -244.5 C-609,-244.5 -609,244.5 -609,244.5 C-609,244.5 609,244.5 609,244.5 C609,244.5 609,-244.5 609,-244.5 C609,-244.5 -609,-244.5 -609,-244.5c  M335.44 -4.16 C229.17,40.21 115.13,63.04 -0.04,63 C-115.21,62.96 -229.22,40.05 -335.47,-4.39 C-350.76,-10.79 -357.95,-28.36 -351.56,-43.65 C-345.17,-58.93 -327.59,-66.14 -312.31,-59.74 C-213.39,-18.36 -107.24,2.96 -0.02,3 C107.21,3.04 213.38,-18.22 312.33,-59.53 C327.62,-65.91 345.19,-58.69 351.57,-43.4 C357.95,-28.11 350.73,-10.54 335.44,-4.16c "/>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.8" android:valueTo="-51.3" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
+
+
diff --git a/core/res/res/drawable-w228dp/loader_horizontal_watch.xml b/core/res/res/drawable-w228dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..c4574d8
--- /dev/null
+++ b/core/res/res/drawable-w228dp/loader_horizontal_watch.xml
@@ -0,0 +1,103 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="16dp" android:width="78dp" android:viewportHeight="16" android:viewportWidth="78">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_1_G" android:translateX="39" android:translateY="8">
+                    <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M39 -8 C39,-8 39,8 39,8 C39,8 -39,8 -39,8 C-39,8 -39,-8 -39,-8 C-39,-8 39,-8 39,-8c "/>
+                </group>
+                <group android:name="_R_G_L_0_G" android:translateX="-345" android:translateY="-67" android:pivotX="384" android:pivotY="75" android:scaleX="0.1" android:scaleY="0.1">
+                    <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-274.19" android:translateY="-390.077" android:pivotX="658.448" android:pivotY="-390.423" android:rotation="28.7" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M231.28 420.42 C226.4,420.42 221.45,419.23 216.88,416.72 C74.61,338.68 -45.02,224 -129.06,85.06 C-171.54,14.82 -204.38,-60.73 -226.66,-139.5 C-249.65,-220.76 -261.31,-305.18 -261.31,-390.42 C-261.31,-406.99 -247.88,-420.42 -231.31,-420.42 C-214.74,-420.42 -201.31,-406.99 -201.31,-390.42 C-201.31,-310.71 -190.42,-231.78 -168.93,-155.83 C-148.11,-82.23 -117.42,-11.63 -77.72,54 C0.86,183.92 112.71,291.15 245.73,364.12 C260.26,372.08 265.58,390.32 257.61,404.85 C252.15,414.79 241.88,420.42 231.28,420.42c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_5_G" android:translateX="875.8979999999999" android:translateY="-337.894" android:pivotX="-491.64" android:pivotY="-442.606" android:rotation="28.7">
+                        <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-398.64 472.61 C-413.82,472.61 -426.84,461.13 -428.44,445.7 C-430.15,429.22 -418.17,414.47 -401.69,412.77 C-191.38,390.98 3.04,292.33 145.75,135.01 C289.46,-23.4 368.6,-228.54 368.6,-442.61 C368.6,-459.17 382.04,-472.61 398.6,-472.61 C415.17,-472.61 428.6,-459.17 428.6,-442.61 C428.6,-213.6 343.93,5.85 190.19,175.33 C37.53,343.61 -170.48,449.13 -395.51,472.44 C-396.56,472.55 -397.6,472.61 -398.64,472.61c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_2_G" android:translateX="212.64499999999998" android:translateY="75.14200000000005" android:pivotX="171.613" android:pivotY="-855.642" android:rotation="28.7" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M171.61 64.36 C171.61,64.36 171.61,64.36 171.61,64.36 C48.68,64.32 -70.7,40.42 -183.19,-6.68 C-198.47,-13.07 -205.68,-30.65 -199.28,-45.93 C-192.88,-61.22 -175.3,-68.42 -160.02,-62.02 C-54.9,-18.01 56.68,4.33 171.62,4.36 C188.19,4.36 201.62,17.8 201.61,34.36 C201.61,50.93 188.18,64.36 171.61,64.36c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_0_G" android:translateX="384" android:translateY="75">
+                        <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-611 -259 C-611,-259 -611,259 -611,259 C-611,259 611,259 611,259 C611,259 611,-259 611,-259 C611,-259 -611,-259 -611,-259c  M354.66 -6.52 C242.36,40.4 121.76,64.54 -0.04,64.5 C-121.84,64.46 -242.44,40.23 -354.74,-6.76 C-370.04,-13.16 -377.24,-30.73 -370.84,-46.02 C-364.44,-61.3 -346.94,-68.51 -331.64,-62.12 C-226.54,-18.18 -113.84,4.46 -0.04,4.5 C113.76,4.54 226.56,-18.02 331.56,-61.89 C346.86,-68.27 364.46,-61.05 370.86,-45.76 C377.26,-30.47 369.96,-12.9 354.66,-6.52c "/>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
diff --git a/core/res/res/drawable-w240dp/loader_horizontal_watch.xml b/core/res/res/drawable-w240dp/loader_horizontal_watch.xml
new file mode 100644
index 0000000..ad60bbd
--- /dev/null
+++ b/core/res/res/drawable-w240dp/loader_horizontal_watch.xml
@@ -0,0 +1,104 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="17dp" android:width="82dp" android:viewportHeight="17" android:viewportWidth="82">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_1_G" android:translateX="41" android:translateY="8.5">
+                    <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M41 -8.5 C41,-8.5 41,8.5 41,8.5 C41,8.5 -41,8.5 -41,8.5 C-41,8.5 -41,-8.5 -41,-8.5 C-41,-8.5 41,-8.5 41,-8.5c "/>
+                </group>
+                <group android:name="_R_G_L_0_G" android:translateX="-362.5" android:translateY="-69" android:pivotX="403.5" android:pivotY="77.5" android:scaleX="0.1" android:scaleY="0.1">
+                    <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-291.64799999999997" android:translateY="-414.141" android:pivotX="695.448" android:pivotY="-412.359" android:rotation="28.7" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M244.28 442.36 C239.4,442.36 234.45,441.17 229.88,438.66 C79.87,356.38 -46.26,235.46 -134.87,88.96 C-179.66,14.91 -214.28,-64.74 -237.78,-147.79 C-262.02,-233.47 -274.31,-322.49 -274.31,-412.36 C-274.31,-428.93 -260.88,-442.36 -244.31,-442.36 C-227.74,-442.36 -214.31,-428.93 -214.31,-412.36 C-214.31,-328.01 -202.78,-244.49 -180.05,-164.12 C-158.01,-86.24 -125.54,-11.54 -83.53,57.91 C-0.38,195.38 117.97,308.85 258.73,386.05 C273.26,394.02 278.58,412.26 270.61,426.78 C265.15,436.73 254.88,442.36 244.28,442.36c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_5_G" android:translateX="923.0530000000001" android:translateY="-359.029" android:pivotX="-519.253" android:pivotY="-467.471" android:rotation="28.7">
+                        <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-421.02 497.47 C-436.2,497.47 -449.23,485.99 -450.83,470.56 C-452.53,454.08 -440.56,439.34 -424.08,437.63 C-201.54,414.57 4.18,310.19 155.19,143.73 C229.54,61.77 287.7,-31.75 328.04,-134.22 C369.81,-240.3 390.99,-352.42 390.99,-467.47 C390.99,-484.04 404.42,-497.47 420.99,-497.47 C437.56,-497.47 450.99,-484.04 450.99,-467.47 C450.99,-226.02 361.72,5.35 199.63,184.04 C38.67,361.47 -180.63,472.73 -417.89,497.31 C-418.94,497.42 -419.99,497.47 -421.02,497.47c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_2_G" android:translateX="222.54600000000002" android:translateY="77.21400000000006" android:pivotX="181.254" android:pivotY="-903.714" android:rotation="28.7" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M181.26 66.28 C181.25,66.28 181.25,66.28 181.25,66.28 C51.64,66.25 -74.22,41.06 -192.83,-8.6 C-208.12,-15 -215.32,-32.58 -208.92,-47.86 C-202.52,-63.15 -184.94,-70.35 -169.66,-63.95 C-58.42,-17.38 59.64,6.25 181.26,6.28 C197.83,6.29 211.26,19.72 211.26,36.29 C211.25,52.86 197.82,66.28 181.26,66.28c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_0_G" android:translateX="403.5" android:translateY="77.5">
+                        <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-630.5 -255.5 C-630.5,-255.5 -630.5,255.5 -630.5,255.5 C-630.5,255.5 630.5,255.5 630.5,255.5 C630.5,255.5 630.5,-255.5 630.5,-255.5 C630.5,-255.5 -630.5,-255.5 -630.5,-255.5c  M374 -8.88 C255.5,40.59 128.4,66.04 0,66 C-128.4,65.95 -255.6,40.42 -374,-9.14 C-389.3,-15.53 -396.5,-33.11 -390.1,-48.39 C-383.7,-63.68 -366.2,-70.88 -350.9,-64.49 C-239.7,-18 -120.5,5.96 0,6 C120.4,6.04 239.7,-17.84 350.9,-64.25 C366.2,-70.63 383.7,-63.41 390.1,-48.12 C396.5,-32.83 389.3,-15.26 374,-8.88c "/>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
+
diff --git a/core/res/res/drawable/close_button_bg.xml b/core/res/res/drawable/close_button_bg.xml
new file mode 100644
index 0000000..59ac7d4
--- /dev/null
+++ b/core/res/res/drawable/close_button_bg.xml
@@ -0,0 +1,30 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/close_button_pill_colorized_layer">
+        <shape xmlns:android="http://schemas.android.com/apk/res/android">
+            <corners android:radius="@dimen/notification_close_button_size" />
+            <solid android:color="@android:color/white" />
+        </shape>
+    </item>
+    <item>
+        <shape xmlns:android="http://schemas.android.com/apk/res/android">
+            <corners android:radius="@dimen/notification_close_button_size" />
+            <solid android:color="@color/notification_close_button_state_tint" />
+        </shape>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/core/res/res/drawable/loader_horizontal_watch.xml b/core/res/res/drawable/loader_horizontal_watch.xml
new file mode 100644
index 0000000..6b86c63
--- /dev/null
+++ b/core/res/res/drawable/loader_horizontal_watch.xml
@@ -0,0 +1,103 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt">
+    <aapt:attr name="android:drawable">
+        <vector android:height="14dp" android:width="76dp" android:viewportHeight="14" android:viewportWidth="76">
+            <group android:name="_R_G">
+                <group android:name="_R_G_L_1_G" android:translateX="39" android:translateY="8">
+                    <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M39 -8 C39,-8 39,8 39,8 C39,8 -39,8 -39,8 C-39,8 -39,-8 -39,-8 C-39,-8 39,-8 39,-8c "/>
+                </group>
+                <group android:name="_R_G_L_0_G" android:translateX="-345" android:translateY="-67" android:pivotX="384" android:pivotY="75" android:scaleX="0.1" android:scaleY="0.1">
+                    <group android:name="_R_G_L_0_G_L_6_G" android:translateX="-274.19" android:translateY="-390.077" android:pivotX="658.448" android:pivotY="-390.423" android:rotation="28.7" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_6_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M231.28 420.42 C226.4,420.42 221.45,419.23 216.88,416.72 C74.61,338.68 -45.02,224 -129.06,85.06 C-171.54,14.82 -204.38,-60.73 -226.66,-139.5 C-249.65,-220.76 -261.31,-305.18 -261.31,-390.42 C-261.31,-406.99 -247.88,-420.42 -231.31,-420.42 C-214.74,-420.42 -201.31,-406.99 -201.31,-390.42 C-201.31,-310.71 -190.42,-231.78 -168.93,-155.83 C-148.11,-82.23 -117.42,-11.63 -77.72,54 C0.86,183.92 112.71,291.15 245.73,364.12 C260.26,372.08 265.58,390.32 257.61,404.85 C252.15,414.79 241.88,420.42 231.28,420.42c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_5_G" android:translateX="875.8979999999999" android:translateY="-337.894" android:pivotX="-491.64" android:pivotY="-442.606" android:rotation="28.7">
+                        <path android:name="_R_G_L_0_G_L_5_G_D_0_P_0" android:fillColor="#303030" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-398.64 472.61 C-413.82,472.61 -426.84,461.13 -428.44,445.7 C-430.15,429.22 -418.17,414.47 -401.69,412.77 C-191.38,390.98 3.04,292.33 145.75,135.01 C289.46,-23.4 368.6,-228.54 368.6,-442.61 C368.6,-459.17 382.04,-472.61 398.6,-472.61 C415.17,-472.61 428.6,-459.17 428.6,-442.61 C428.6,-213.6 343.93,5.85 190.19,175.33 C37.53,343.61 -170.48,449.13 -395.51,472.44 C-396.56,472.55 -397.6,472.61 -398.64,472.61c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_2_G" android:translateX="212.64499999999998" android:translateY="75.14200000000005" android:pivotX="171.613" android:pivotY="-855.642" android:rotation="28.7" android:scaleY="0">
+                        <path android:name="_R_G_L_0_G_L_2_G_D_0_P_0" android:fillColor="#ffffff" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M171.61 64.36 C171.61,64.36 171.61,64.36 171.61,64.36 C48.68,64.32 -70.7,40.42 -183.19,-6.68 C-198.47,-13.07 -205.68,-30.65 -199.28,-45.93 C-192.88,-61.22 -175.3,-68.42 -160.02,-62.02 C-54.9,-18.01 56.68,4.33 171.62,4.36 C188.19,4.36 201.62,17.8 201.61,34.36 C201.61,50.93 188.18,64.36 171.61,64.36c "/>
+                    </group>
+                    <group android:name="_R_G_L_0_G_L_0_G" android:translateX="384" android:translateY="75">
+                        <path android:name="_R_G_L_0_G_L_0_G_D_0_P_0" android:fillColor="#000000" android:fillAlpha="1" android:fillType="nonZero" android:pathData=" M-611 -259 C-611,-259 -611,259 -611,259 C-611,259 611,259 611,259 C611,259 611,-259 611,-259 C611,-259 -611,-259 -611,-259c  M354.66 -6.52 C242.36,40.4 121.76,64.54 -0.04,64.5 C-121.84,64.46 -242.44,40.23 -354.74,-6.76 C-370.04,-13.16 -377.24,-30.73 -370.84,-46.02 C-364.44,-61.3 -346.94,-68.51 -331.64,-62.12 C-226.54,-18.18 -113.84,4.46 -0.04,4.5 C113.76,4.54 226.56,-18.02 331.56,-61.89 C346.86,-68.27 364.46,-61.05 370.86,-45.76 C377.26,-30.47 369.96,-12.9 354.66,-6.52c "/>
+                    </group>
+                </group>
+            </group>
+            <group android:name="time_group"/>
+        </vector>
+    </aapt:attr>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_6_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="333" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_5_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="rotation" android:duration="983" android:startOffset="0" android:valueFrom="28.7" android:valueTo="-51.4" android:valueType="floatType">
+                    <aapt:attr name="android:interpolator">
+                        <pathInterpolator android:pathData="M 0.0,0.0 c0.402,0.136 0.202,0.847 1.0,1.0"/>
+                    </aapt:attr>
+                </objectAnimator>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="_R_G_L_0_G_L_2_G">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="scaleY" android:duration="0" android:startOffset="133" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+    <target android:name="time_group">
+        <aapt:attr name="android:animation">
+            <set android:ordering="together">
+                <objectAnimator android:repeatCount="infinite" android:propertyName="translateX" android:duration="1000" android:startOffset="0" android:valueFrom="0" android:valueTo="1" android:valueType="floatType"/>
+            </set>
+        </aapt:attr>
+    </target>
+</animated-vector>
diff --git a/core/res/res/drawable/notification_progress.xml b/core/res/res/drawable/notification_progress.xml
index ff5450e..92a0a6a 100644
--- a/core/res/res/drawable/notification_progress.xml
+++ b/core/res/res/drawable/notification_progress.xml
@@ -19,12 +19,9 @@
           android:gravity="center_vertical|fill_horizontal">
         <com.android.internal.widget.NotificationProgressDrawable
             android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:segSegGap="@dimen/notification_progress_segSeg_gap"
-            android:segPointGap="@dimen/notification_progress_segPoint_gap">
+            android:layout_height="wrap_content">
             <segments
                 android:color="?attr/colorProgressBackgroundNormal"
-                android:minWidth="@dimen/notification_progress_segments_min_width"
                 android:height="@dimen/notification_progress_segments_height"
                 android:fadedHeight="@dimen/notification_progress_segments_faded_height"
                 android:cornerRadius="@dimen/notification_progress_segments_corner_radius"/>
diff --git a/core/res/res/layout/accessibility_autoclick_type_panel.xml b/core/res/res/layout/accessibility_autoclick_type_panel.xml
index 902ef7f..615af6f 100644
--- a/core/res/res/layout/accessibility_autoclick_type_panel.xml
+++ b/core/res/res/layout/accessibility_autoclick_type_panel.xml
@@ -49,7 +49,8 @@
                     android:id="@+id/accessibility_autoclick_drag_button"
                     style="@style/AccessibilityAutoclickPanelImageButtonStyle"
                     android:contentDescription="@string/accessibility_autoclick_drag"
-                    android:src="@drawable/accessibility_autoclick_drag" />
+                    android:src="@drawable/accessibility_autoclick_drag"
+                    android:clickable="false" />
             </LinearLayout>
 
             <LinearLayout
@@ -60,7 +61,8 @@
                     android:id="@+id/accessibility_autoclick_double_click_button"
                     style="@style/AccessibilityAutoclickPanelImageButtonStyle"
                     android:contentDescription="@string/accessibility_autoclick_double_click"
-                    android:src="@drawable/accessibility_autoclick_double_click" />
+                    android:src="@drawable/accessibility_autoclick_double_click"
+                    android:clickable="false" />
             </LinearLayout>
 
             <LinearLayout
@@ -71,7 +73,8 @@
                     android:id="@+id/accessibility_autoclick_right_click_button"
                     style="@style/AccessibilityAutoclickPanelImageButtonStyle"
                     android:contentDescription="@string/accessibility_autoclick_right_click"
-                    android:src="@drawable/accessibility_autoclick_right_click" />
+                    android:src="@drawable/accessibility_autoclick_right_click"
+                    android:clickable="false" />
             </LinearLayout>
 
             <LinearLayout
@@ -82,7 +85,8 @@
                     android:id="@+id/accessibility_autoclick_scroll_button"
                     style="@style/AccessibilityAutoclickPanelImageButtonStyle"
                     android:contentDescription="@string/accessibility_autoclick_scroll"
-                    android:src="@drawable/accessibility_autoclick_scroll" />
+                    android:src="@drawable/accessibility_autoclick_scroll"
+                    android:clickable="false" />
             </LinearLayout>
 
             <LinearLayout
@@ -93,7 +97,8 @@
                     android:id="@+id/accessibility_autoclick_left_click_button"
                     style="@style/AccessibilityAutoclickPanelImageButtonStyle"
                     android:contentDescription="@string/accessibility_autoclick_left_click"
-                    android:src="@drawable/accessibility_autoclick_left_click" />
+                    android:src="@drawable/accessibility_autoclick_left_click"
+                    android:clickable="false" />
             </LinearLayout>
 
         </LinearLayout>
@@ -114,7 +119,8 @@
                 android:id="@+id/accessibility_autoclick_pause_button"
                 style="@style/AccessibilityAutoclickPanelImageButtonStyle"
                 android:contentDescription="@string/accessibility_autoclick_pause"
-                android:src="@drawable/accessibility_autoclick_pause" />
+                android:src="@drawable/accessibility_autoclick_pause"
+                android:clickable="false" />
         </LinearLayout>
 
         <LinearLayout
@@ -125,7 +131,8 @@
                 android:id="@+id/accessibility_autoclick_position_button"
                 style="@style/AccessibilityAutoclickPanelImageButtonStyle"
                 android:contentDescription="@string/accessibility_autoclick_position"
-                android:src="@drawable/accessibility_autoclick_position" />
+                android:src="@drawable/accessibility_autoclick_position"
+                android:clickable="false" />
         </LinearLayout>
 
     </LinearLayout>
diff --git a/core/res/res/layout/chooser_az_label_row.xml b/core/res/res/layout/chooser_az_label_row.xml
index baf07ce..0e907c1 100644
--- a/core/res/res/layout/chooser_az_label_row.xml
+++ b/core/res/res/layout/chooser_az_label_row.xml
@@ -16,7 +16,7 @@
   -->
 
 <ImageView xmlns:android="http://schemas.android.com/apk/res/android"
-          android:contentDescription="@string/chooser_all_apps_button_label"
+          android:importantForAccessibility="no"
           android:src="@drawable/chooser_row_layer_list"
           android:paddingTop="16dp"
           android:layout_width="match_parent"
diff --git a/core/res/res/layout/notification_2025_action_list.xml b/core/res/res/layout/notification_2025_action_list.xml
index 053aca0..6c07ec1 100644
--- a/core/res/res/layout/notification_2025_action_list.xml
+++ b/core/res/res/layout/notification_2025_action_list.xml
@@ -22,6 +22,7 @@
     android:layout_height="wrap_content"
     android:layout_gravity="bottom"
     android:layout_marginBottom="@dimen/notification_2025_action_list_margin_bottom"
+    android:minHeight="@dimen/notification_2025_action_list_min_height"
     >
 
     <LinearLayout
diff --git a/core/res/res/layout/notification_2025_conversation_icon_container.xml b/core/res/res/layout/notification_2025_conversation_icon_container.xml
index 7ec2450..16c9500 100644
--- a/core/res/res/layout/notification_2025_conversation_icon_container.xml
+++ b/core/res/res/layout/notification_2025_conversation_icon_container.xml
@@ -29,7 +29,8 @@
     <FrameLayout
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
-        android:layout_margin="@dimen/notification_2025_margin"
+        android:layout_marginHorizontal="@dimen/notification_2025_margin"
+        android:layout_marginTop="@dimen/notification_2025_margin"
         android:clipChildren="false"
         android:clipToPadding="false"
         android:layout_gravity="top|center_horizontal"
diff --git a/core/res/res/layout/notification_2025_messaging_group.xml b/core/res/res/layout/notification_2025_messaging_group.xml
index ecaf0b9..ba0ce7b 100644
--- a/core/res/res/layout/notification_2025_messaging_group.xml
+++ b/core/res/res/layout/notification_2025_messaging_group.xml
@@ -53,7 +53,6 @@
             android:id="@+id/group_message_container"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginTop="@dimen/notification_text_margin_top"
             android:spacing="2dp" />
     </com.android.internal.widget.RemeasuringLinearLayout>
     <FrameLayout
diff --git a/core/res/res/layout/notification_2025_reply_history_container.xml b/core/res/res/layout/notification_2025_reply_history_container.xml
index 6923b59..256f7b8 100644
--- a/core/res/res/layout/notification_2025_reply_history_container.xml
+++ b/core/res/res/layout/notification_2025_reply_history_container.xml
@@ -28,16 +28,16 @@
             android:layout_width="match_parent"
             android:layout_height="1dip"
             android:id="@+id/action_divider"
-            android:layout_marginTop="@dimen/notification_content_margin"
-            android:layout_marginBottom="@dimen/notification_content_margin"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginTop="@dimen/notification_2025_margin"
+            android:layout_marginBottom="@dimen/notification_2025_margin"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:background="@drawable/notification_template_divider" />
 
     <TextView
             android:id="@+id/notification_material_reply_text_3"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:visibility="gone"
             android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
             android:singleLine="true" />
@@ -46,7 +46,7 @@
             android:id="@+id/notification_material_reply_text_2"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:visibility="gone"
             android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
             android:singleLine="true" />
@@ -56,13 +56,13 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="horizontal"
-            android:layout_marginEnd="@dimen/notification_content_margin_end">
+            android:layout_marginEnd="@dimen/notification_2025_margin">
         <TextView
                 android:id="@+id/notification_material_reply_text_1"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_weight="1"
-                android:layout_marginEnd="@dimen/notification_content_margin_end"
+                android:layout_marginEnd="@dimen/notification_2025_margin"
                 android:layout_gravity="center"
                 android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Reply"
                 android:singleLine="true" />
diff --git a/core/res/res/layout/notification_2025_template_collapsed_base.xml b/core/res/res/layout/notification_2025_template_collapsed_base.xml
index 63f32e3..57c89b9 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_base.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_base.xml
@@ -74,7 +74,6 @@
             android:id="@+id/notification_headerless_view_column"
             android:layout_width="0px"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
             android:layout_weight="1"
             android:layout_marginVertical="@dimen/notification_2025_reduced_margin"
             android:orientation="vertical"
@@ -157,7 +156,7 @@
             android:id="@+id/expand_button_touch_container"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:minWidth="@dimen/notification_content_margin_end"
+            android:minWidth="@dimen/notification_2025_margin"
             >
 
             <include layout="@layout/notification_2025_expand_button"
diff --git a/core/res/res/layout/notification_2025_template_collapsed_call.xml b/core/res/res/layout/notification_2025_template_collapsed_call.xml
index 732021c6..c57196e 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_call.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_call.xml
@@ -35,7 +35,6 @@
         <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:minHeight="@dimen/notification_2025_min_height"
             android:clipChildren="false"
             android:layout_weight="1"
             >
@@ -78,9 +77,7 @@
                     android:id="@+id/notification_headerless_view_column"
                     android:layout_width="0px"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center_vertical"
                     android:layout_weight="1"
-                    android:layout_marginBottom="@dimen/notification_2025_margin"
                     android:layout_marginTop="@dimen/notification_2025_margin"
                     android:clipChildren="false"
                     android:orientation="vertical"
@@ -152,7 +149,7 @@
                     android:id="@+id/expand_button_touch_container"
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
-                    android:minWidth="@dimen/notification_content_margin_end"
+                    android:minWidth="@dimen/notification_2025_margin"
                     >
 
                     <include layout="@layout/notification_2025_expand_button"
@@ -173,21 +170,13 @@
 
         </FrameLayout>
 
-        <LinearLayout
-            android:id="@+id/notification_action_list_margin_target"
+        <include layout="@layout/notification_template_smart_reply_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="-20dp"
-            android:clipChildren="false"
-            android:orientation="vertical">
-            <include layout="@layout/notification_template_smart_reply_container"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
-                android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-                android:layout_marginEnd="@dimen/notification_content_margin_end" />
-            <include layout="@layout/notification_2025_action_list" />
-        </LinearLayout>
+            android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
+            android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+            android:layout_marginEnd="@dimen/notification_2025_margin" />
+        <include layout="@layout/notification_2025_action_list" />
     </LinearLayout>
 
 </com.android.internal.widget.CallLayout>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_conversation.xml b/core/res/res/layout/notification_2025_template_collapsed_conversation.xml
index 1ee7ddc..1c6fcb5 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_conversation.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_conversation.xml
@@ -35,7 +35,6 @@
         <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:minHeight="@dimen/notification_2025_min_height"
             android:clipChildren="false"
             android:layout_weight="1"
             >
@@ -78,17 +77,11 @@
                 android:clipChildren="false"
                 >
 
-                <!--
-                  NOTE: because messaging will always have 2 lines, this LinearLayout should NOT
-                  have the id/notification_headerless_view_column, as that is used for modifying
-                   vertical margins to accommodate the single-line state that base supports
-                  -->
                 <LinearLayout
+                    android:id="@+id/notification_headerless_view_column"
                     android:layout_width="0px"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center_vertical"
                     android:layout_weight="1"
-                    android:layout_marginBottom="@dimen/notification_2025_margin"
                     android:layout_marginTop="@dimen/notification_2025_margin"
                     android:layout_marginStart="@dimen/notification_2025_content_margin_start"
                     android:clipChildren="false"
@@ -150,7 +143,6 @@
                     android:layout_height="@dimen/notification_right_icon_size"
                     android:layout_gravity="center_vertical|end"
                     android:layout_marginTop="@dimen/notification_2025_margin"
-                    android:layout_marginBottom="@dimen/notification_2025_margin"
                     android:layout_marginStart="@dimen/notification_2025_right_icon_content_margin"
                     android:forceHasOverlappingRendering="false"
                     android:spacing="0dp"
@@ -175,7 +167,7 @@
                     android:id="@+id/expand_button_touch_container"
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
-                    android:minWidth="@dimen/notification_content_margin_end"
+                    android:minWidth="@dimen/notification_2025_margin"
                     >
 
                     <include layout="@layout/notification_2025_expand_button"
@@ -196,20 +188,13 @@
 
         </FrameLayout>
 
-    <LinearLayout
-            android:id="@+id/notification_action_list_margin_target"
+        <include layout="@layout/notification_template_smart_reply_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="-20dp"
-            android:clipChildren="false"
-            android:orientation="vertical">
-        <include layout="@layout/notification_template_smart_reply_container"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
-                android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-                android:layout_marginEnd="@dimen/notification_content_margin_end" />
+            android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
+            android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+            android:layout_marginEnd="@dimen/notification_2025_margin" />
         <include layout="@layout/notification_2025_action_list" />
+
     </LinearLayout>
-</LinearLayout>
 </com.android.internal.widget.ConversationLayout>
diff --git a/core/res/res/layout/notification_2025_template_collapsed_media.xml b/core/res/res/layout/notification_2025_template_collapsed_media.xml
index 629af77..de82f9f 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_media.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_media.xml
@@ -76,7 +76,6 @@
             android:id="@+id/notification_headerless_view_column"
             android:layout_width="0px"
             android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
             android:layout_weight="1"
             android:layout_marginVertical="@dimen/notification_2025_reduced_margin"
             android:orientation="vertical"
@@ -178,7 +177,7 @@
             android:id="@+id/expand_button_touch_container"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:minWidth="@dimen/notification_content_margin_end"
+            android:minWidth="@dimen/notification_2025_margin"
             >
 
             <include layout="@layout/notification_2025_expand_button"
diff --git a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
index af66025..8e2cb23 100644
--- a/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_collapsed_messaging.xml
@@ -38,7 +38,6 @@
         <FrameLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:minHeight="@dimen/notification_2025_min_height"
             android:clipChildren="false"
             android:layout_weight="1"
             >
@@ -61,7 +60,8 @@
                 android:layout_width="@dimen/notification_2025_icon_circle_size"
                 android:layout_height="@dimen/notification_2025_icon_circle_size"
                 android:layout_alignParentStart="true"
-                android:layout_margin="@dimen/notification_2025_margin"
+                android:layout_marginHorizontal="@dimen/notification_2025_margin"
+                android:layout_marginTop="@dimen/notification_2025_margin"
                 android:background="@drawable/notification_icon_circle"
                 android:padding="@dimen/notification_2025_icon_circle_padding"
                 />
@@ -89,17 +89,11 @@
                 android:clipChildren="false"
                 >
 
-                <!--
-                  NOTE: because messaging will always have 2 lines, this LinearLayout should NOT
-                  have the id/notification_headerless_view_column, as that is used for modifying
-                   vertical margins to accommodate the single-line state that base supports
-                  -->
                 <LinearLayout
+                    android:id="@+id/notification_headerless_view_column"
                     android:layout_width="0px"
                     android:layout_height="wrap_content"
-                    android:layout_gravity="center_vertical"
                     android:layout_weight="1"
-                    android:layout_marginBottom="@dimen/notification_2025_margin"
                     android:layout_marginTop="@dimen/notification_2025_margin"
                     android:layout_marginStart="@dimen/notification_2025_content_margin_start"
                     android:clipChildren="false"
@@ -161,7 +155,6 @@
                     android:layout_height="@dimen/notification_right_icon_size"
                     android:layout_gravity="center_vertical|end"
                     android:layout_marginTop="@dimen/notification_2025_margin"
-                    android:layout_marginBottom="@dimen/notification_2025_margin"
                     android:layout_marginStart="@dimen/notification_2025_right_icon_content_margin"
                     android:forceHasOverlappingRendering="false"
                     android:spacing="0dp"
@@ -186,7 +179,7 @@
                     android:id="@+id/expand_button_touch_container"
                     android:layout_width="wrap_content"
                     android:layout_height="match_parent"
-                    android:minWidth="@dimen/notification_content_margin_end"
+                    android:minWidth="@dimen/notification_2025_margin"
                     >
 
                     <include layout="@layout/notification_2025_expand_button"
@@ -207,20 +200,13 @@
 
         </FrameLayout>
 
-    <LinearLayout
-            android:id="@+id/notification_action_list_margin_target"
+        <include layout="@layout/notification_template_smart_reply_container"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginTop="-20dp"
-            android:clipChildren="false"
-            android:orientation="vertical">
-        <include layout="@layout/notification_template_smart_reply_container"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
-                android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-                android:layout_marginEnd="@dimen/notification_content_margin_end" />
+            android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
+            android:layout_marginStart="@dimen/notification_2025_content_margin_start"
+            android:layout_marginEnd="@dimen/notification_2025_margin" />
         <include layout="@layout/notification_2025_action_list" />
+
     </LinearLayout>
-</LinearLayout>
 </com.android.internal.widget.MessagingLayout>
diff --git a/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml b/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml
index 52bc7b8..b32a778 100644
--- a/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml
+++ b/core/res/res/layout/notification_2025_template_compact_heads_up_base.xml
@@ -76,7 +76,7 @@
             android:id="@+id/expand_button_touch_container"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:minWidth="@dimen/notification_content_margin_end"
+            android:minWidth="@dimen/notification_2025_margin"
             >
             <include layout="@layout/notification_2025_expand_button"
                 android:layout_width="wrap_content"
diff --git a/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml b/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml
index be640460..268396f 100644
--- a/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_compact_heads_up_messaging.xml
@@ -103,7 +103,7 @@
             android:id="@+id/expand_button_touch_container"
             android:layout_width="wrap_content"
             android:layout_height="match_parent"
-            android:minWidth="@dimen/notification_content_margin_end"
+            android:minWidth="@dimen/notification_2025_margin"
             >
             <include layout="@layout/notification_2025_expand_button"
                 android:layout_width="wrap_content"
diff --git a/core/res/res/layout/notification_2025_template_expanded_base.xml b/core/res/res/layout/notification_2025_template_expanded_base.xml
index 76a8581..58b26c9 100644
--- a/core/res/res/layout/notification_2025_template_expanded_base.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_base.xml
@@ -24,10 +24,8 @@
     >
 
     <LinearLayout
-        android:id="@+id/notification_action_list_margin_target"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/notification_content_margin"
         android:orientation="vertical"
         >
 
@@ -47,11 +45,11 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-                android:layout_marginEnd="@dimen/notification_content_margin_end"
+                android:layout_marginEnd="@dimen/notification_2025_margin"
                 android:orientation="vertical"
                 >
 
-                <include layout="@layout/notification_template_part_line1" />
+                <include layout="@layout/notification_2025_title" />
 
                 <include layout="@layout/notification_template_text_multiline" />
 
@@ -78,7 +76,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
             />
 
diff --git a/core/res/res/layout/notification_2025_template_expanded_big_picture.xml b/core/res/res/layout/notification_2025_template_expanded_big_picture.xml
index 999afa6..f6a17ef 100644
--- a/core/res/res/layout/notification_2025_template_expanded_big_picture.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_big_picture.xml
@@ -28,7 +28,6 @@
     <include layout="@layout/notification_2025_right_icon" />
 
     <LinearLayout
-        android:id="@+id/notification_action_list_margin_target"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
         android:layout_gravity="top"
@@ -43,11 +42,11 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:orientation="vertical"
             >
 
-            <include layout="@layout/notification_template_part_line1" />
+            <include layout="@layout/notification_2025_title" />
 
             <include
                 layout="@layout/notification_template_progress"
@@ -67,7 +66,7 @@
             android:layout_weight="1"
             android:layout_marginTop="13dp"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:background="@drawable/notification_big_picture_outline"
             android:clipToOutline="true"
             android:scaleType="centerCrop"
@@ -85,7 +84,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
             />
 
diff --git a/core/res/res/layout/notification_2025_template_expanded_big_text.xml b/core/res/res/layout/notification_2025_template_expanded_big_text.xml
index c9206ed..540444e 100644
--- a/core/res/res/layout/notification_2025_template_expanded_big_text.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_big_text.xml
@@ -26,11 +26,9 @@
     <include layout="@layout/notification_2025_template_header" />
 
     <com.android.internal.widget.RemeasuringLinearLayout
-        android:id="@+id/notification_action_list_margin_target"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="top"
-        android:layout_marginBottom="@dimen/notification_content_margin"
         android:clipToPadding="false"
         android:orientation="vertical"
         >
@@ -43,13 +41,13 @@
             android:layout_height="wrap_content"
             android:layout_gravity="top"
             android:paddingStart="@dimen/notification_2025_content_margin_start"
-            android:paddingEnd="@dimen/notification_content_margin_end"
+            android:paddingEnd="@dimen/notification_2025_margin"
             android:clipToPadding="false"
             android:orientation="vertical"
             android:layout_weight="1"
             >
 
-            <include layout="@layout/notification_template_part_line1" />
+            <include layout="@layout/notification_2025_title" />
 
             <include
                 layout="@layout/notification_template_progress"
@@ -84,7 +82,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
             />
 
diff --git a/core/res/res/layout/notification_2025_template_expanded_call.xml b/core/res/res/layout/notification_2025_template_expanded_call.xml
index ec21455..60b3200 100644
--- a/core/res/res/layout/notification_2025_template_expanded_call.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_call.xml
@@ -30,7 +30,6 @@
     <include layout="@layout/notification_2025_conversation_header"/>
 
     <com.android.internal.widget.RemeasuringLinearLayout
-        android:id="@+id/notification_action_list_margin_target"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_gravity="top"
@@ -46,12 +45,12 @@
             android:layout_gravity="top"
             android:layout_weight="1"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:orientation="vertical"
             android:clipChildren="false"
             >
 
-            <include layout="@layout/notification_template_part_line1"/>
+            <include layout="@layout/notification_2025_title"/>
 
             <include layout="@layout/notification_template_text_multiline" />
 
@@ -62,7 +61,7 @@
             android:layout_height="wrap_content"
             android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end" />
+            android:layout_marginEnd="@dimen/notification_2025_margin" />
 
         <include layout="@layout/notification_2025_action_list" />
 
diff --git a/core/res/res/layout/notification_2025_template_expanded_conversation.xml b/core/res/res/layout/notification_2025_template_expanded_conversation.xml
index 6ee82fa..e085d47 100644
--- a/core/res/res/layout/notification_2025_template_expanded_conversation.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_conversation.xml
@@ -29,7 +29,6 @@
     <include layout="@layout/notification_2025_conversation_header"/>
 
     <com.android.internal.widget.RemeasuringLinearLayout
-            android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
@@ -44,19 +43,20 @@
             android:layout_height="wrap_content"
             android:layout_gravity="top"
             android:layout_weight="1"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:orientation="vertical"
             android:clipChildren="false"
             >
 
-            <include layout="@layout/notification_template_part_line1"/>
+            <include layout="@layout/notification_2025_title"/>
 
             <com.android.internal.widget.MessagingLinearLayout
                 android:id="@+id/notification_messaging"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/notification_2025_margin"
                 android:clipChildren="false"
-                android:spacing="@dimen/notification_messaging_spacing" />
+                android:spacing="@dimen/notification_2025_messaging_spacing" />
         </com.android.internal.widget.RemeasuringLinearLayout>
 
         <include layout="@layout/notification_template_smart_reply_container"
@@ -64,7 +64,7 @@
                 android:layout_height="wrap_content"
                 android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
                 android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-                android:layout_marginEnd="@dimen/notification_content_margin_end" />
+                android:layout_marginEnd="@dimen/notification_2025_margin" />
 
         <include layout="@layout/notification_2025_action_list" />
 
diff --git a/core/res/res/layout/notification_2025_template_expanded_inbox.xml b/core/res/res/layout/notification_2025_template_expanded_inbox.xml
index 1eaef22..55253d0 100644
--- a/core/res/res/layout/notification_2025_template_expanded_inbox.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_inbox.xml
@@ -24,7 +24,6 @@
     >
     <include layout="@layout/notification_2025_template_header" />
     <LinearLayout
-            android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             android:layout_gravity="top"
@@ -39,12 +38,12 @@
             android:layout_height="wrap_content"
             android:layout_gravity="top"
             android:paddingStart="@dimen/notification_2025_content_margin_start"
-            android:paddingEnd="@dimen/notification_content_margin_end"
+            android:paddingEnd="@dimen/notification_2025_margin"
             android:layout_weight="1"
             android:clipToPadding="false"
             android:orientation="vertical"
             >
-            <include layout="@layout/notification_template_part_line1"
+            <include layout="@layout/notification_2025_title"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content" />
             <include layout="@layout/notification_template_progress"
@@ -126,7 +125,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin" />
         <include layout="@layout/notification_2025_action_list" />
     </LinearLayout>
diff --git a/core/res/res/layout/notification_2025_template_expanded_media.xml b/core/res/res/layout/notification_2025_template_expanded_media.xml
index 801e339..5e97607 100644
--- a/core/res/res/layout/notification_2025_template_expanded_media.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_media.xml
@@ -41,10 +41,10 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:orientation="vertical"
             >
-            <include layout="@layout/notification_template_part_line1"/>
+            <include layout="@layout/notification_2025_title"/>
             <include layout="@layout/notification_template_text"/>
         </LinearLayout>
 
@@ -53,7 +53,7 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_2025_media_actions_margin_start"
-            android:minHeight="@dimen/notification_content_margin"
+            android:minHeight="@dimen/notification_2025_margin"
             >
 
             <!-- Nesting in FrameLayout is required to ensure that the marginStart actually applies
diff --git a/core/res/res/layout/notification_2025_template_expanded_messaging.xml b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
index 62059af..14ed536 100644
--- a/core/res/res/layout/notification_2025_template_expanded_messaging.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_messaging.xml
@@ -29,7 +29,6 @@
     <include layout="@layout/notification_2025_template_header"/>
 
     <com.android.internal.widget.RemeasuringLinearLayout
-            android:id="@+id/notification_action_list_margin_target"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_gravity="top"
@@ -44,19 +43,20 @@
             android:layout_height="wrap_content"
             android:layout_gravity="top"
             android:layout_weight="1"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:orientation="vertical"
             android:clipChildren="false"
             >
 
-            <include layout="@layout/notification_template_part_line1"/>
+            <include layout="@layout/notification_2025_title"/>
 
             <com.android.internal.widget.MessagingLinearLayout
                 android:id="@+id/notification_messaging"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/notification_2025_margin"
                 android:clipChildren="false"
-                android:spacing="@dimen/notification_messaging_spacing" />
+                android:spacing="@dimen/notification_2025_messaging_spacing" />
         </com.android.internal.widget.RemeasuringLinearLayout>
 
         <include layout="@layout/notification_template_smart_reply_container"
@@ -64,7 +64,7 @@
                 android:layout_height="wrap_content"
                 android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
                 android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-                android:layout_marginEnd="@dimen/notification_content_margin_end" />
+                android:layout_marginEnd="@dimen/notification_2025_margin" />
 
         <include layout="@layout/notification_2025_action_list" />
 
diff --git a/core/res/res/layout/notification_2025_template_expanded_progress.xml b/core/res/res/layout/notification_2025_template_expanded_progress.xml
index cf39d8b..1315481 100644
--- a/core/res/res/layout/notification_2025_template_expanded_progress.xml
+++ b/core/res/res/layout/notification_2025_template_expanded_progress.xml
@@ -25,10 +25,8 @@
     >
 
     <LinearLayout
-        android:id="@+id/notification_action_list_margin_target"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_marginBottom="@dimen/notification_content_margin"
         android:orientation="vertical"
         >
 
@@ -48,11 +46,11 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-                android:layout_marginEnd="@dimen/notification_content_margin_end"
+                android:layout_marginEnd="@dimen/notification_2025_margin"
                 android:orientation="vertical"
                 >
 
-                <include layout="@layout/notification_template_part_line1" />
+                <include layout="@layout/notification_2025_title" />
 
                 <include layout="@layout/notification_template_text_multiline" />
 
@@ -114,7 +112,7 @@
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-            android:layout_marginEnd="@dimen/notification_content_margin_end"
+            android:layout_marginEnd="@dimen/notification_2025_margin"
             android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
             />
 
diff --git a/core/res/res/layout/notification_2025_template_heads_up_base.xml b/core/res/res/layout/notification_2025_template_heads_up_base.xml
index 4d3b245..e416c50 100644
--- a/core/res/res/layout/notification_2025_template_heads_up_base.xml
+++ b/core/res/res/layout/notification_2025_template_heads_up_base.xml
@@ -56,7 +56,7 @@
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
                 android:layout_marginStart="@dimen/notification_2025_content_margin_start"
-                android:layout_marginEnd="@dimen/notification_content_margin_end"
+                android:layout_marginEnd="@dimen/notification_2025_margin"
                 android:layout_marginTop="@dimen/notification_2025_smart_reply_container_margin"
                 />
 
diff --git a/core/res/res/layout/notification_2025_title.xml b/core/res/res/layout/notification_2025_title.xml
new file mode 100644
index 0000000..7cea5ea
--- /dev/null
+++ b/core/res/res/layout/notification_2025_title.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License
+  -->
+<TextView
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/title"
+    android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Title"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:maxLines="2"
+    android:ellipsize="end"
+    android:textAlignment="viewStart"
+    />
diff --git a/core/res/res/layout/notification_close_button.xml b/core/res/res/layout/notification_close_button.xml
index 5eff84e..9656d39 100644
--- a/core/res/res/layout/notification_close_button.xml
+++ b/core/res/res/layout/notification_close_button.xml
@@ -17,13 +17,14 @@
 <com.android.internal.widget.NotificationCloseButton
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@+id/close_button"
+    android:background="@drawable/close_button_bg"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:layout_gravity="top|end"
     android:contentDescription="@string/close_button_text"
     android:visibility="gone"
     android:src="@drawable/notification_close_button_icon"
-    android:padding="2dp"
+    android:padding="@dimen/notification_close_button_padding"
     android:scaleType="fitCenter"
     android:importantForAccessibility="no"
     >
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 59ac5c6..1cab0dc 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vra ontsluitpatroon voordat jy ontspeld"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vra wagwoord voordat jy ontspeld"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Deur jou admin geïnstalleer.\nGaan na instellings om toegestaande toestemmings te sien"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Deur jou admin opgedateer.\nGaan na instellings om toegestaande toestemmings te sien"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Uitgevee deur jou administrateur"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterybespaarder skakel Donkertema aan en beperk of skakel agtergrondaktiwiteit, sommige visuele effekte, sekere kenmerke en sommige netwerkverbindings af"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rollees"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Onderbreek"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisie"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rollees op"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rollees af"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rollees na links"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rollees na regs"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Gaan uit Rolleesmodus"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Rolleespaneel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in die BEPERK-groep geplaas"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"het \'n prent gestuur"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Werk 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Toets"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Gemeenskaplik"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Toesighoudend"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Werkprofiel"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privaat ruimte"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Kloon"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 169e020..bda4da0 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ከመንቀል በፊት የማስከፈቻ ሥርዓተ-ጥለት ጠይቅ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ከመንቀል በፊት የይለፍ ቃል ጠይቅ"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"በአስተዳዳሪዎ ተጭኗል።\nየተፈቀዱ ፍቃዶችን ለማየት ወደ ቅንብሮች ይሂዱ"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"በአስተዳዳሪዎ ተዘምኗል።\nየተፈቀዱ ፍቃዶችን ለማየት ወደ ቅንብሮች ይሂዱ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"በእርስዎ አስተዳዳሪ ተሰርዟል"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"እሺ"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ባትሪ ቆጣቢ ጠቆር ያለ ገጽታን ያበራል እና የጀርባ እንቅስቃሴን፣ አንዳንድ ዕይታዊ ውጤቶችን፣ አንዳንድ ባህሪዎችን፣ እና አንዳንድ የአውታረ መረብ ግንኙነቶችን ይገድባል ወይም ያጠፋል።"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ሸብልል"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ባለበት አቁም"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"አቀማመጥ"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ወደ ላይ ሸብልል"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ወደ ታች ሸብልል"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ወደ ግራ ሸብልል"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ወደ ቀኝ ሸብልል"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ከሸብልል ሁነታ ውጣ"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"የመሸብለል ፓነል"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ወደ የRESTRICTED ባልዲ ተከትቷል"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>፦"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"አንድ ምስል ልከዋል"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ሥራ 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ሙከራ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"የጋራ"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"ክትትል በማድረግ ላይ"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"የሥራ መገለጫ"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"የግል ቦታ"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"አባዛ"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 1d2bd77..7daa4b4 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -1969,8 +1969,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"طلب إدخال نقش فتح القفل قبل إزالة التثبيت"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"طلب إدخال كلمة المرور قبل إزالة التثبيت"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"تم التثبيت من قِبل المشرف.\nانتقِل إلى الإعدادات للاطّلاع على الأذونات الممنوحة"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"تم التحديث من قِبل المشرف.\nيُرجى الانتقال إلى الإعدادات للاطّلاع على الأذونات الممنوحة"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"تم الحذف بواسطة المشرف"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"حسنًا"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"يؤدي استخدام ميزة \"توفير شحن البطارية\" إلى تفعيل وضع \"المظهر الداكن\" وتقييد أو إيقاف الأنشطة في الخلفية وبعض التأثيرات المرئية وميزات معيّنة وبعض اتصالات الشبكات."</string>
@@ -2278,18 +2277,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"الانتقال للأسفل أو للأعلى"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"إيقاف مؤقت"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"تعديل الموضع"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"الانتقال للأعلى"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"الانتقال للأسفل"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"الانتقال لليمين"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"الانتقال لليسار"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"الخروج من وضع الانتقال"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"لوحة الانتقال"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"تم وضع <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> في الحزمة \"محظورة\"."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"هذا المستخدم أرسل صورة"</string>
@@ -2497,8 +2490,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ملف العمل 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ملف شخصي تجريبي"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ملف شخصي مشترك"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"المُشرف"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ملف العمل"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"المساحة الخاصة"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"نسخة طبق الأصل"</string>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 606161c..5f7ef00 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন কৰাৰ পূৰ্বে আনলক আৰ্হি দিবলৈ কওক"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন কৰাৰ পূৰ্বে পাছৱৰ্ড দিবলৈ কওক"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"আপোনাৰ প্ৰশাসকে ইনষ্টল কৰিছে।\nপ্ৰদান কৰা অনুমতিসমূহ চাবলৈ ছেটিঙলৈ যাওক"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"আপোনাৰ প্ৰশাসকে আপডে’ট কৰিছে।\nপ্ৰদান কৰা অনুমতিসমূহ চাবলৈ ছেটিঙলৈ যাওক"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"আপোনাৰ প্ৰশাসকে মচিছে"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"বেটাৰী সঞ্চয়কাৰীয়ে গাঢ় ৰঙৰ থীম অন কৰে আৰু নেপথ্যৰ কাৰ্যকলাপ, কিছুমান ভিজুৱেল ইফেক্ট, নিৰ্দিষ্ট কিছুমান সুবিধা আৰু নেটৱৰ্কৰ সংযোগ সীমিত অথবা অফ কৰে।"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"স্ক্ৰ’ল কৰক"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"পজ কৰক"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"স্থান"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ওপৰলৈ স্ক্ৰ’ল কৰক"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"তললৈ স্ক্ৰ’ল কৰক"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"বাওঁফাললৈ স্ক্ৰ’ল কৰক"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"সোঁফাললৈ স্ক্ৰ’ল কৰক"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"স্ক্ৰ’ল ম’ডৰ পৰা বাহিৰ হওক"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"স্ক্ৰ’ল পেনেল"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ক সীমাবদ্ধ বাকেটটোত ৰখা হৈছে"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"এখন প্ৰতিচ্ছবি পঠিয়াইছে"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"কৰ্মস্থান ৩"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"পৰীক্ষা"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"শ্বেয়াৰ কৰা"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"তদাৰক কৰি থকা হৈছে"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"কৰ্মস্থানৰ প্ৰ’ফাইল"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"প্ৰাইভেট স্পে’চ"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ক্ল’ন"</string>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index 904194f1..bc8a3f3 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Qrafik açar istənilsin"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Ayırmadan öncə parol istənilsin"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Admin quraşdırıb.\nVerilən icazələrə baxmaq üçün ayarlara keçin"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Admin güncəlləyib.\nTəmin edilən icazələrə baxmaq üçün ayarlara keçin"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Admin tərəfindən silindi"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Enerjiyə Qənaət rejimi Tünd temanı aktivləşdirir, habelə arxa fon fəaliyyətini, bəzi vizual effektləri, müəyyən xüsusiyyətləri və bəzi şəbəkə bağlantılarını məhdudlaşdırır, yaxud söndürür."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Sürüşdürün"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Durdurun"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Mövqe"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Yuxarı sürüşdürün"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Aşağı sürüşdürün"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Sola sürüşdürün"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Sağa sürüşdürün"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sürüşdürmə rejimindən çıxın"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Sürüşdürmə paneli"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> MƏHDUDLAŞDIRILMIŞ səbətinə yerləşdirilib"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"şəkil göndərdi"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"İş 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Kommunal"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Nəzarət edilir"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"İş profili"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Məxfi sahə"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index e7fff52..8b74200 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži šablon za otključavanje pre otkačinjanja"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku pre otkačinjanja"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao je administrator.\nIdite u podešavanja da biste videli odobrene dozvole"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Ažurirao je administrator.\nIdite u podešavanja da biste videli odobrene dozvole"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je administrator"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Potvrdi"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizuelne efekte, određene funkcije i neke mrežne veze."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Skrolujte"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauziraj"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozicija"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Skroluj nagore"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Skroluj nadole"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Skroluj ulevo"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Skroluj udesno"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izađi iz režima skrolovanja"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Okno za skrolovanje"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je dodat u segment OGRANIČENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"je poslao/la sliku"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Posao 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Zajedničko"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzire se"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Poslovni profil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privatan prostor"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klonirano"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 94739b3..cbdbc23 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -1967,8 +1967,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запытваць узор разблакіроўкі перад адмацаваннем"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запытваць пароль перад адмацаваннем"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Усталявана адміністратарам.\nКаб паглядзець дадзеныя дазволы, перайдзіце ў налады"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Абноўлена адміністратарам.\nКаб праглядзець дадзеныя дазволы, перайдзіце ў налады"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Выдалены вашым адміністратарам"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"У рэжыме энергазберажэння ўключаецца цёмная тэма і выключаюцца ці абмяжоўваюцца дзеянні ў фонавым рэжыме, некаторыя візуальныя эфекты, пэўныя функцыі і падключэнні да сетак."</string>
@@ -2276,18 +2275,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Гартанне"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Прыпыніць"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Пазіцыя"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Прагартаць уверх"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Прагартаць уніз"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Прагартаць улева"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Прагартаць управа"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Выйсці з рэжыму гартання"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Панэль прагортвання"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" дададзены ў АБМЕЖАВАНУЮ групу"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"адпраўлены відарыс"</string>
@@ -2495,8 +2488,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Працоўны 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Тэставы"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Супольны"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Бацькоўскі кантроль"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Працоўны профіль"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Прыватная прастора"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клон"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 2bd7d1d..a1140b9 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Превъртане"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Пауза"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Позиция"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Превъртане нагоре"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Превъртане надолу"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Превъртане наляво"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Превъртане надясно"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Изход от режима за превъртане"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Панел за превъртане"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакетът <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е поставен в ОГРАНИЧЕНИЯ контейнер"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"изпратено изображение"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Служебни 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Тестване"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Общи"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Контролиране"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Служебен потребителски профил"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Частно пространство"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клониране"</string>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index 16a7e9a..426c711 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"আনপিন করার আগে আনলক প্যাটার্ন চান"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"আনপিন করার আগে পাসওয়ার্ড চান"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"আপনার অ্যাডমিন ইনস্টল করেছেন।\nঅনুমোদন করা অনুমতি দেখতে সেটিংসে যান"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"আপনার অ্যাডমিন আপডেট করেছেন।\nঅনুমোদন করা অনুমতি দেখতে সেটিংসে যান"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"আপনার প্রশাসক মুছে দিয়েছেন"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ঠিক আছে"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ব্যাটারি সেভার ডার্ক থিম চালু করে এবং ব্যাকগ্রাউন্ড অ্যাক্টিভিটি, কিছু ভিজ্যুয়াল এফেক্ট, নির্দিষ্ট ফিচার ও কয়েকটি নেটওয়ার্ক কানেকশনের ব্যবহার সীমিত করে বা বন্ধ করে দেয়।"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"স্ক্রল করুন"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"পজ করুন"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"পজিশন"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"উপর দিকে স্ক্রল করুন"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"নিচে স্ক্রল করুন"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"বাঁদিকে স্ক্রল করুন"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ডানদিকে স্ক্রল করুন"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"স্ক্রল মোড থেকে বেরিয়ে আসুন"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"স্ক্রল প্যানেল"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> সীমাবদ্ধ গ্রুপে অন্তর্ভুক্ত করা হয়েছে"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"একটি ছবি পাঠানো হয়েছে"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"৩য় অফিস"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"পরীক্ষা"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"কমিউনাল"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"তত্ত্বাবধান করা"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"অফিস প্রোফাইল"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"প্রাইভেট স্পেস"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ক্লোন"</string>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index e5a78a3..947f6ba 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje prije poništavanja kačenja"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži lozinku prije nego se otkači"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao je vaš administrator.\nIdite u postavke da pregledate data odobrenja"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Ažurirao je vaš administrator.\nIdite u postavke da pregledate data odobrenja"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao je vaš administrator"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Uredu"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ušteda baterije uključuje tamnu temu i ograničava ili isključuje aktivnost u pozadini, određene vizuelne efekte i funkcije te neke mrežne veze."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Klizanje"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauziraj"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Položaj"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Klizanje nagore"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Klizanje nadolje"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Klizanje ulijevo"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Klizanje udesno"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izlaz iz načina rada za klizanje"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Ploča za klizanje"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je stavljen u odjeljak OGRANIČENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"je poslao/la sliku"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"3. poslovno"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Testno"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Opće"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzor"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Radni profil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privatni prostor"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index b70bb33..8dcf671 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sol·licita el patró de desbloqueig per deixar de fixar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demana la contrasenya per deixar de fixar"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instal·lat per l\'administrador.\nVes a la configuració per veure els permisos concedits."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Actualitzat per l\'administrador.\nVes a la configuració per veure els permisos concedits."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Suprimit per l\'administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"D\'acord"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Estalvi de bateria activa el tema fosc i limita o desactiva l\'activitat en segon pla, alguns efectes visuals, determinades funcions i algunes connexions de xarxa."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplaça"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Posa en pausa"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posició"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Desplaça\'t cap amunt"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Desplaça\'t cap avall"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Desplaça\'t cap a l\'esquerra"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Desplaça\'t cap a la dreta"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Surt del mode de desplaçament"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Tauler de desplaçament"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> s\'ha transferit al segment RESTRINGIT"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ha enviat una imatge"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Treball 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Prova"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Compartit"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"En supervisió"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de treball"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espai privat"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clon"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c4e69ab..61d9249 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -1967,8 +1967,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Před uvolněním požádat o bezpečnostní gesto"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Před odepnutím požádat o heslo"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Nainstalováno administrátorem.\nUdělená oprávnění si můžete prohlédnout v nastavení."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Aktualizováno administrátorem.\nUdělená oprávnění si můžete prohlédnout v nastavení."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Smazáno administrátorem"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Spořič baterie zapíná tmavý motiv a omezuje či vypíná aktivitu na pozadí, některé vizuální efekty, některé funkce a připojení k některým sítím."</string>
@@ -2276,18 +2275,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Posunutí"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pozastavit"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozice"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Posunout nahoru"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Posunout dolů"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Posunout doleva"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Posunout doprava"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Ukončit režim posouvání"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel posouvání"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balíček <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> byl vložen do sekce OMEZENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"posílá obrázek"</string>
@@ -2495,8 +2488,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Práce 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Komunální"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Dohled"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Pracovní profil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Soukromý prostor"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index c044723..8d8918f 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Bed om oplåsningsmønster ved deaktivering"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bed om adgangskode inden frigørelse"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Installeret af din administrator.\nGå til Indstillinger for at se de tilladelser, der er blevet givet"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Opdateret af din administrator.\nGå til Indstillinger for at se de tilladelser, der er blevet givet"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet af din administrator"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterisparefunktionen aktiverer Mørkt tema og begrænser eller deaktiverer aktivitet i baggrunden og visse visuelle effekter, funktioner og netværksforbindelser."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rul"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sæt på pause"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Placering"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rul op"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rul ned"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rul til venstre"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rul til højre"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Afslut rulletilstand"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Rullepanel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blevet placeret i samlingen BEGRÆNSET"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sendte et billede"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Arbejde 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Fælles"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Forældrestyring"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Arbejdsprofil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privat område"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 0d371cc..15eddde 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Vor dem Beenden nach Entsperrungsmuster fragen"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vor dem Beenden nach Passwort fragen"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Von deinem Administrator installiert.\nRufe die Einstellungen auf, um gewährte Berechtigungen anzusehen."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Von deinem Administrator aktualisiert.\nRufe die Einstellungen auf, um gewährte Berechtigungen anzusehen."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Von deinem Administrator gelöscht"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Der Energiesparmodus aktiviert das dunkle Design. Hintergrundaktivitäten, einige Funktionen und optische Effekte und manche Netzwerkverbindungen werden eingeschränkt oder deaktiviert."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scrollen"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausieren"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Nach oben scrollen"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Nach unten scrollen"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Nach links scrollen"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Nach rechts scrollen"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Scrollmodus beenden"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Bildlaufleiste"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> wurde in den BESCHRÄNKT-Bucket gelegt"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"hat ein Bild gesendet"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Geschäftlich 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Gemeinsam genutzt"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Elternaufsicht"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Arbeitsprofil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Vertrauliches Profil"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 55d28c5..5d83f78 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Να γίνεται ερώτηση για το μοτίβο ξεκλειδώματος, πριν από το ξεκαρφίτσωμα"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Να γίνεται ερώτηση για τον κωδικό πρόσβασης, πριν από το ξεκαρφίτσωμα"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Εγκαταστάθηκε από τον διαχειριστή σας.\nΜεταβείτε στις ρυθμίσεις για να δείτε τις άδειες που έχουν εκχωρηθεί"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Ενημερώθηκε από τον διαχειριστή σας.\nΜεταβείτε στις ρυθμίσεις για να δείτε τις άδειες που έχουν εκχωρηθεί"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Διαγράφηκε από τον διαχειριστή σας"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Η Εξοικονόμηση μπαταρίας ενεργοποιεί το Σκούρο θέμα και περιορίζει ή απενεργοποιεί τη δραστηριότητα στο παρασκήνιο, ορισμένα οπτικά εφέ, συγκεκριμένες λειτουργίες και κάποιες συνδέσεις δικτύου."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Κύλιση"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Παύση"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Θέση"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Κύλιση προς τα επάνω"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Κύλιση προς τα κάτω"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Κύλιση προς τα αριστερά"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Κύλιση προς τα δεξιά"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Έξοδος από τη λειτουργία κύλισης"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Πλαίσιο κύλισης"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Το πακέτο <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> τοποθετήθηκε στον κάδο ΠΕΡΙΟΡΙΣΜΕΝΗΣ ΠΡΟΣΒΑΣΗΣ."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"έστειλε μια εικόνα"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Εργασία 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Δοκιμή"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Κοινόχρηστο"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Επίβλεψη"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Προφίλ εργασίας"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Ιδιωτικός χώρος"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Κλώνος"</string>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index b948404..532fee6 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing-aid battery is low. This only switches your mic during the call."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing-aid microphone for hands-free calling. This only switches your mic during the call."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scroll up"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scroll down"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scroll left"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scroll right"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Exit scroll mode"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scroll panel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sent an image"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervising"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Work profile"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Private space"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index 30843ad..eb6f281 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -2486,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervising"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Work profile"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Private space"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index bcfc861..c079a48 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing-aid battery is low. This only switches your mic during the call."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing-aid microphone for hands-free calling. This only switches your mic during the call."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scroll up"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scroll down"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scroll left"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scroll right"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Exit scroll mode"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scroll panel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sent an image"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervising"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Work profile"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Private space"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 15ea9bf..62daeff 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Magnification"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Switch to phone mic?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Switch to hearing aid mic?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing aid battery is low. This only switches your mic during the call."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing aid microphone for hands-free calling. This only switches your mic during the call."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"For better sound or if your hearing-aid battery is low. This only switches your mic during the call."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"You can use your hearing-aid microphone for hands-free calling. This only switches your mic during the call."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Switch"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Settings"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Switching to <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scroll up"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scroll down"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scroll left"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scroll right"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Exit scroll mode"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scroll panel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> has been put into the RESTRICTED bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sent an image"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Work 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervising"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Work profile"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Private space"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 1e10140..3870869 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -2274,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplazamiento"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Desplazarse hacia arriba"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Desplazarse hacia abajo"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Desplazarse hacia la izquierda"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Desplazarse hacia la derecha"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Salir del modo de desplazamiento"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel de desplazamiento"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Se colocó <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> en el bucket RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"envió una imagen"</string>
@@ -2493,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Trabajo 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Probar"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisando"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabajo"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espacio privado"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clon"</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 189a027..b5a5e8f 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir patrón de desbloqueo para dejar de fijar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicitar contraseña para desactivar"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado por tu administrador.\nVe a Ajustes para ver los permisos concedidos."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Actualizado por tu administrador.\nVe a Ajustes para ver los permisos concedidos."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado por el administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Ahorro de batería activa el tema oscuro y limita o desactiva la actividad en segundo plano, algunos efectos visuales, ciertas funciones y algunas conexiones de red."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desplazarse"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Desplazarse hacia arriba"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Desplazarse hacia abajo"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Desplazarse a la izquierda"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Desplazarse a la derecha"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Salir del modo de desplazamiento"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel de desplazamiento"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> se ha incluido en el grupo de restringidos"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ha enviado una imagen"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Trabajo 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Prueba"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Común"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisando"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabajo"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espacio privado"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clon"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index 893bc4e..99f9791 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Suurendus"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Kas vahetada telefoni mikrofonile?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Kas vahetada kuuldeaparaadi mikrofonile?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Parema heli tagamiseks või siis, kui tele kuuldeaparaadi aku on tühi. See vahetab teie mikrofoni ainult kõne ajal."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Saate kasutada oma kuuldeaparaadi mikrofon vabakäerežiimis helistamiseks. See vahetab teie mikrofoni ainult kõne ajal."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Parema heli tagamiseks või siis, kui teie kuuldeaparaadi aku on tühi. See vahetab teie mikrofoni ainult kõne ajal."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Saate kasutada oma kuuldeaparaadi mikrofoni vabakäerežiimis helistamiseks. See vahetab teie mikrofoni ainult kõne ajal."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Vaheta"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Seaded"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Üleminek kasutajale <xliff:g id="NAME">%1$s</xliff:g> ..."</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Enne vabastamist küsi avamismustrit"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Enne vabastamist küsi parooli"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Installis teie administraator.\nAntud õiguste vaatamiseks avage seaded"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Värskendas teie administraator.\nAntud õiguste vaatamiseks avage seaded"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administraator on selle kustutanud"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Akusäästja lülitab sisse tumeda teema ja lülitab välja taustategevused, mõned visuaalsed efektid, teatud funktsioonid ja võrguühendused või piirab neid."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Keri"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Peata"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Asukoht"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Keri üles"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Keri alla"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Keri vasakule"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Keri paremale"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Välju kerimisrežiimist"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Keri paneelil"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on lisatud salve PIIRANGUTEGA"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"saatis kujutise"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Töö 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Jagatud"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Järelevalve"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Tööprofiil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privaatne ruum"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Kloon"</string>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index fb60c8d..7a49905 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Eskatu desblokeatzeko eredua aingura kendu aurretik"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Eskatu pasahitza aingura kendu aurretik"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Administratzaileak instalatu du.\nEmandako baimenak ikusteko, joan ezarpenetara."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Administratzaileak eguneratu du.\nEmandako baimenak ikusteko, joan ezarpenetara."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administratzaileak ezabatu du"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Ados"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Bateria-aurreztaileak gai iluna aktibatzen du, eta atzeko planoko jarduerak, zenbait efektu bisual, eta eginbide jakin eta sareko konexio batzuk mugatzen edo desaktibatzen ditu."</string>
@@ -2493,8 +2492,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Lanekoa 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Probakoa"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Partekatua"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Gainbegiratzea"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Laneko profila"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Eremu pribatua"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klona"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 24db15a..820a80c 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"پیمایش"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"توقف موقت"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"موقعیت"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"پیمایش به بالا"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"پیمایش به پایین"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"پیمایش به چپ"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"پیمایش به راست"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"خارج شدن از حالت پیمایش"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"پانل پیمایش"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> در سطل «محدودشده» قرار گرفت"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"تصویری ارسال کرد"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"کار ۳"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"آزمایش"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"عمومی"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"نظارت"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"نمایه کاری"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"فضای خصوصی"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"همسانه‌سازی"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index cb16427..dce063d 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pyydä lukituksenpoistokuvio ennen irrotusta"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pyydä salasana ennen irrotusta"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Järjestelmänvalvojan asentama.\nTarkista myönnetyt luvat asetuksista."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Järjestelmänvalvojan päivittämä.\nTarkista myönnetyt luvat asetuksista"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Järjestelmänvalvoja poisti tämän."</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Virransäästö laittaa tumman teeman päälle ja rajoittaa tai laittaa pois päältä taustatoimintoja, tiettyjä ominaisuuksia sekä joitakin visuaalisia tehosteita ja verkkoyhteyksiä."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Vieritä"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Keskeytä"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Sijainti"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Vieritys ylös"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Vieritä alas"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Vieritä vasemmalle"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Vieritä oikealle"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Poistu vieritystilasta"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Vierityspaneeli"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> on nyt rajoitettujen ryhmässä"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"lähetti kuvan"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Työ 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Testi"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Jaettu"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Valvotaan"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Työprofiili"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Yksityinen tila"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klooni"</string>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index c2b368e..127e6fc 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -1820,9 +1820,9 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"La fonctionnalité s\'ouvrira la prochaine fois que vous utiliserez ce raccourci. Balayez l\'écran du bas vers le haut avec trois doigts et relâchez rapidement."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passer au micro du téléphone?"</string>
-    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passer au micro pour la prothèse auditive?"</string>
+    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passer au micro de la prothèse auditive?"</string>
     <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pour profiter d\'un meilleur son ou si la pile de votre prothèse auditive est faible. Cette option ne change votre micro que pendant l\'appel."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser votre microphone pour prothèse auditive pour faire des appels en mode mains libres. Cette option ne change votre micro que pendant l\'appel."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser le microphone de votre prothèse auditive pour faire des appels en mode mains libres. Cette option ne change votre micro que pendant l\'appel."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Changer"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Paramètres"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Passage au profil : <xliff:g id="NAME">%1$s</xliff:g> en cours…"</string>
@@ -2274,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Faire défiler"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Faire défiler vers le haut"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Faire défiler vers le bas"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Faire défiler vers la gauche"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Faire défiler vers la droite"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sortir du mode de défilement"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panneau de défilement"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le compartiment RESTREINT"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g> :"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"a envoyé une image"</string>
@@ -2493,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Professionnel 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervision"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil professionnel"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espace privé"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 1cf5409..a30c414 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -1821,8 +1821,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Agrandissement"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passer au micro du téléphone ?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passer au micro de l\'appareil auditif ?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pour améliorer le son ou si la batterie de votre appareil auditif est faible. Cette option change uniquement le micro pendant l\'appel."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser le micro de votre appareil auditif pour passer des appels en mode mains-libres. Cette option change uniquement le micro pendant l\'appel."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pour un meilleur son ou si la batterie de votre appareil auditif est faible. Cette option ne change le micro que pendant l\'appel."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Vous pouvez utiliser le micro de votre appareil auditif pour passer des appels en mode mains-libres. Cette option ne change le micro que pendant l\'appel."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Changer"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Paramètres"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Passage à <xliff:g id="NAME">%1$s</xliff:g>..."</string>
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Demander le schéma de déverrouillage avant de retirer l\'épingle"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Demander le mot de passe avant de retirer l\'épingle"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Installé par votre administrateur.\nAllez dans les paramètres pour consulter les autorisations accordées."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Mis à jour par votre administrateur.\nAllez dans les paramètres pour consulter les autorisations accordées."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Supprimé par votre administrateur"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"L\'économiseur de batterie active le thème sombre et limite ou désactive l\'activité en arrière-plan ainsi que certains effets visuels, fonctionnalités et connexions réseau."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Faire défiler"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pause"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Faire défiler vers le haut"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Faire défiler vers le bas"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Faire défiler vers la gauche"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Faire défiler vers la droite"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Quitter le mode défilement"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panneau de défilement"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a été placé dans le bucket RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g> :"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"a envoyé une image"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Professionnel 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Commun"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervision"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil professionnel"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espace privé"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index ecd2d4b..d79e3c6 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrón de desbloqueo antes de soltar a fixación"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir contrasinal antes de soltar a fixación"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pola persoa administradora.\nVai á configuración para ver os permisos concedidos"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Actualizado pola persoa administradora.\nVai á configuración para ver os permisos concedidos"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Eliminado polo teu administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Aceptar"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Coa función Aforro de batería, actívase o tema escuro e restrínxense ou desactívanse a actividade en segundo plano, algúns efectos visuais e determinadas funcións e conexións de rede."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Desprazar"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausa"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posición"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Desprazarse cara arriba"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Desprazarse cara abaixo"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Desprazar cara á esquerda"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Desprazar cara á dereita"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Saír do modo de desprazamento"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel de desprazamento"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> incluíuse no grupo RESTRINXIDO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"enviouse unha imaxe"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Traballo 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Proba"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Compartido"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisión"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de traballo"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espazo privado"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clonado"</string>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index b4095ef..6b1e284 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -1803,8 +1803,7 @@
     <string name="one_handed_mode_feature_name" msgid="2334330034828094891">"એક-હાથે વાપરો મોડ"</string>
     <string name="reduce_bright_colors_feature_name" msgid="3222994553174604132">"એક્સ્ટ્રા ડિમ"</string>
     <string name="hearing_aids_feature_name" msgid="1125892105105852542">"સાંભળવામાં સહાય કરતા ડિવાઇસ"</string>
-    <!-- no translation found for autoclick_feature_name (8149248738736949630) -->
-    <skip />
+    <string name="autoclick_feature_name" msgid="8149248738736949630">"ઑટોક્લિક"</string>
     <string name="hearing_device_status_disconnected" msgid="497547752953543832">"ડિસ્કનેક્ટેડ છે"</string>
     <string name="hearing_device_status_connected" msgid="2149385149669918764">"કનેક્ટેડ છે"</string>
     <string name="hearing_device_status_active" msgid="4770378695482566032">"સક્રિય"</string>
@@ -1966,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"અનપિન કરતા પહેલાં અનલૉક પૅટર્ન માટે પૂછો"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"અનપિન કરતાં પહેલાં પાસવર્ડ માટે પૂછો"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"તમારા ઍડમિન દ્વારા ઇન્સ્ટૉલ કરવામાં આવ્યું છે.\nઆપેલી પરવાનગીઓ જોવા માટે સેટિંગ પર જાઓ"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"તમારા ઍડમિન દ્વારા અપડેટ કરવામાં આવ્યું છે.\nઆપેલી પરવાનગીઓ જોવા માટે સેટિંગ પર જાઓ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"તમારા વ્યવસ્થાપક દ્વારા કાઢી નાખવામાં આવેલ છે"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ઓકે"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"બૅટરી સેવર ઘેરી થીમની સુવિધા ચાલુ કરે છે અને બૅકગ્રાઉન્ડ પ્રવૃત્તિ, અમુક વિઝ્યુઅલ ઇફેક્ટ, અમુક સુવિધાઓ અને કેટલાક નેટવર્ક કનેક્શન મર્યાદિત કે બંધ કરે છે."</string>
@@ -2275,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"સ્ક્રોલ કરો"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"થોભાવો"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"સ્થિતિ"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ઉપર સ્ક્રોલ કરો"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"નીચે સ્ક્રોલ કરો"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ડાબે સ્ક્રોલ કરો"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"જમણે સ્ક્રોલ કરો"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"સ્ક્રોલ મોડમાંથી બહાર નીકળો"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"સ્ક્રોલ પૅનલ"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>ને પ્રતિબંધિત સમૂહમાં મૂકવામાં આવ્યું છે"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"છબી મોકલી"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index f93b8a2..b8be405 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ज़ूम करने की सुविधा"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"क्या आपको फ़ोन के माइक्रोफ़ोन पर स्विच करना है?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"क्या आपको कान की मशीन के माइक पर स्विच करना है?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"बेहतर आवाज़ के लिए या कान की मशीन की बैटरी कम होने पर. यह सिर्फ़ कॉल के दौरान आपका माइक चालू करता है."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"बोलकर कॉल का जवाब देने के लिए, \'कान की मशीन का माइक्रोफ़ोन\' इस्तेमाल किया जा सकता है. इससे, कॉल के दौरान सिर्फ़ आपका माइक चालू या बंद होता है."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"बेहतर आवाज़ के लिए या कान की मशीन की बैटरी कम होने पर, इसका इस्तेमाल करें. इससे सिर्फ़ कॉल के दौरान आपका माइक चालू होता है."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"बोलकर कॉल का जवाब देने के लिए, \'कान की मशीन का माइक्रोफ़ोन\' इस्तेमाल किया जा सकता है. इससे सिर्फ़ कॉल के दौरान आपका माइक चालू होता है."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"स्विच करें"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिंग"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> पर स्विच किया जा रहा है…"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करने से पहले लॉक खोलने के पैटर्न के लिए पूछें"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करने से पहले पासवर्ड के लिए पूछें"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"इसे आपके एडमिन ने इंस्टॉल किया है.\nजिन अनुमतियों को मंज़ूरी मिली है उन्हें देखने के लिए, सेटिंग में जाएं"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"इसे आपके एडमिन ने अपडेट किया है.\nजिन अनुमतियों को मंज़ूरी मिली है उन्हें देखने के लिए, सेटिंग में जाएं"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"आपके व्यवस्थापक ने हटा दिया है"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ठीक है"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"बैटरी सेवर, गहरे रंग वाली थीम को चालू करता है. साथ ही, इस मोड में बैकग्राउंड की गतिविधि, कुछ विज़ुअल इफ़ेक्ट, और कुछ खास सुविधाएं कम या बंद हो जाती हैं. कुछ इंटरनेट कनेक्शन भी पूरी तरह काम नहीं करते."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"स्क्रोल करें"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"रोकें"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"पोज़िशन"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ऊपर की ओर स्क्रोल करें"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"नीचे की ओर स्क्रोल करें"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"बाईं ओर स्क्रोल करें"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"दाईं ओर स्क्रोल करें"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"स्क्रोल मोड को बंद करें"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"पैनल को स्क्रोल करें"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> को प्रतिबंधित बकेट में रखा गया है"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"एक इमेज भेजी गई"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ऑफ़िस 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"टेस्ट"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"कम्यूनिटी"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"निगरानी की जा रही है"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"वर्क प्रोफ़ाइल"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"प्राइवेट स्पेस"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"क्लोन"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 336e379..77c9a60 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -1821,8 +1821,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povećavanje"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Želite li se prebaciti na mikrofon telefona?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite li se prebaciti na mikrofon slušnog pomagala?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Za bolji zvuk ili ako je razina baterije slušnog pomagala niska. Time se mikrofon prebacuje samo tijekom poziva."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon slušnog pomagala možete koristiti za pozivanje bez upotrebe ruku. Time se mikrofon prebacuje samo tijekom poziva."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Da biste se bolje čuli ili ako je razina baterije slušnog pomagala niska. Mikrofon se koristi samo tijekom poziva."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon slušnog pomagala možete koristiti za pozivanje bez upotrebe ruku. Mikrofon se koristi samo tijekom poziva."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Prebaci"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Postavke"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Prebacivanje na korisnika <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Traži uzorak za otključavanje radi otkvačivanja"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Traži zaporku radi otkvačivanja"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalirao vaš administrator.\nOtvorite postavke da biste pregledali dodijeljena dopuštenja"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Ažurirao je vaš administrator.\nOtvorite postavke da biste pregledali dodijeljena dopuštenja"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Izbrisao administrator"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"U redu"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Štednja baterije uključuje tamnu temu i ograničava ili isključuje aktivnosti u pozadini, neke vizualne efekte, određene značajke i neke mrežne veze."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Pomakni se"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauziraj"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozicija"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Pomakni prema gore"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Pomakni prema dolje"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Pomakni ulijevo"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Pomakni udesno"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izađi iz načina pomicanja"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Ploča za pomicanje"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> premješten je u spremnik OGRANIČENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"šalje sliku"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Posao 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Zajedničko"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzire se"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Radni profil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privatni prostor"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 1519326..24babe3 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Görgetés"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Szüneteltetés"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozíció"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Görgetés felfelé"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Görgetés lefelé"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Görgetés balra"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Görgetés jobbra"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Kilépés a görgetési módból"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Görgetési panel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"A következő csomag a KORLÁTOZOTT csoportba került: <xliff:g id="PACKAGE_NAME">%1$s</xliff:g>"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"képet küldött"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"3. munkahelyi"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Teszt"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Közös"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Aktív felügyelet"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Munkaprofil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privát terület"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klón"</string>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index af9ee62..7f78454 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Ոլորել"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Դադարեցնել"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Դիրքը"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Թերթել վերև"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Թերթել ներքև"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Թերթել ձախ"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Թերթել աջ"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Դուրս գալ թերթելու ռեժիմից"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Թերթելու վահանակ"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> փաթեթը գցվեց ՍԱՀՄԱՆԱՓԱԿՎԱԾ զամբյուղի մեջ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>՝"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"օգտատերը պատկեր է ուղարկել"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Աշխատանքային 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Փորձնական"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Ընդհանուր"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Վերահսկում"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Աշխատանքային պրոֆիլ"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Մասնավոր տարածք"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Կլոն"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 90b1ddf..fbbf285 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Meminta pola pembukaan kunci sebelum melepas sematan"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Meminta sandi sebelum melepas sematan"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Diinstal oleh admin Anda.\nBuka setelan untuk melihat izin yang diberikan"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Diperbarui oleh admin Anda.\nBuka setelan untuk melihat izin yang diberikan"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dihapus oleh admin Anda"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Oke"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Penghemat Baterai akan mengaktifkan Tema gelap dan membatasi atau menonaktifkan aktivitas latar belakang, beberapa efek visual, fitur tertentu, dan beberapa koneksi jaringan."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scroll"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Jeda"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisi"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scroll ke Atas"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scroll ke Bawah"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scroll ke Kiri"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scroll ke Kanan"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Keluar dari Mode Scroll"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panel Scroll"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah dimasukkan ke dalam bucket DIBATASI"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"mengirim gambar"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Kerja 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Pengujian"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Umum"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Mengawasi"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil kerja"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Ruang privasi"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index 772be76..d148f5d6 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Stækkun"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Skipta yfir í hljóðnema símans?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Skipta yfir í hljóðnema heyrnartækis?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Fyrir betri hljómgæði eða ef lítil hleðsla er á heyrnartækinu. Aðeins verður skipt um hljóðnema á meðan á símtali stendur."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Þú getur notað hljóðnema heyrnartækisins þíns til að hringja eða svara símtölum handfrjálst. Aðeins verður skipt um hljóðnema á meðan á símtali stendur."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Til að auka hljómgæði eða ef hleðsla heyrnartækisins er lág. Aðeins verður skipt um hljóðnema meðan á símtali stendur."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Þú getur notað hljóðnema heyrnartækisins þíns til að hringja eða svara símtölum handfrjálst. Aðeins verður skipt um hljóðnema meðan á símtali stendur."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Skipta"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Stillingar"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Skiptir yfir á <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Fletta"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Hlé"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Staðsetning"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Fletta upp"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Fletta niður"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Fletta til vinstri"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Fletta til hægri"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Loka flettistillingu"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Flettisvæði"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> var sett í flokkinn TAKMARKAÐ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"sendi mynd"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Vinna 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Prófun"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Sameiginlegt"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Eftirlit virkt"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Vinnusnið"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Leynirými"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Afrit"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index dd10d1d..7fe1bdc 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -1821,8 +1821,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ingrandimento"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Passare al microfono dello smartphone?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Passare al microfono dell\'apparecchio acustico?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Per una migliore resa audio o se la batteria dell\'apparecchio acustico è scarica. In questo modo, il microfono viene attivato solo durante la chiamata."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puoi usare il microfono dell\'apparecchio acustico per le chiamate in vivavoce. In questo modo, il microfono viene attivato solo durante la chiamata."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Per una migliore resa audio o se la batteria dell\'apparecchio acustico è scarica. Il cambio del microfono avviene solo durante la chiamata."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Puoi usare il microfono dell\'apparecchio acustico per le chiamate in vivavoce. Il cambio del microfono avviene solo durante la chiamata."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Cambia"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Impostazioni"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Passaggio a <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2274,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scorri"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Metti in pausa"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posizione"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scorri verso l\'alto"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scorri verso il basso"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scorri verso sinistra"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scorri verso destra"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Disattiva la modalità di scorrimento"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Riquadro di scorrimento"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> è stato inserito nel bucket RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ha inviato un\'immagine"</string>
@@ -2493,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Lavoro 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Condiviso"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisione"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profilo di lavoro"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Spazio privato"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 1055612..c32bcdd 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"צריך לבקש קו ביטול נעילה לפני ביטול הצמדה"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"יש לבקש סיסמה לפני ביטול הצמדה"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"החבילה הותקנה על ידי האדמין.\nצריך לעבור להגדרות כדי לראות את ההרשאות שניתנו"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"החבילה עודכנה על ידי האדמין.\nצריך לעבור להגדרות כדי לראות את ההרשאות שניתנו"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"נמחקה על ידי מנהל המערכת"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"אישור"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"התכונה \'חיסכון בסוללה\' מפעילה עיצוב כהה ומגבילה או מכבה פעילות ברקע, חלק מהאפקטים החזותיים, תכונות מסוימות וחלק מהחיבורים לרשתות."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"גלילה"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"השהיה"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"מיקום"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"גלילה למעלה"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"גלילה למטה"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"גלילה שמאלה"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"גלילה ימינה"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"יציאה ממצב גלילה"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"גלילה בחלונית"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> התווספה לקטגוריה \'מוגבל\'"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"נשלחה תמונה"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"פרופיל עבודה 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"בדיקה"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"שיתופי"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"פרופיל מפקח"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"פרופיל העבודה"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"המרחב הפרטי"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"שכפול"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index ea101ec..207e030 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"スクロール"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"一時停止"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"上にスクロール"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"下にスクロール"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"左にスクロール"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"右にスクロール"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"スクロール モードを終了"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"スクロール パネル"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> は RESTRICTED バケットに移動しました。"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"画像を送信しました"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"仕事用 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"テスト"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"共用"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"管理者"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"仕事用プロファイル"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"プライベート スペース"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"複製"</string>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index 055c412..a1a4f72 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"გადაადგილება"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"პაუზა"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"პოზიცია"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ზემოთ გადაადგილება"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ქვემოთ გადაადგილება"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"მარცხნივ გადაადგილება"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"მარჯვნივ გადაადგილება"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"გადაადგილების რეჟიმიდან გასვლა"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"გადაადგილების არე"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> მოთავსდა კალათაში „შეზღუდული“"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"გაიგზავნა სურათი"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"სამსახური 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"სატესტო"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"საერთო"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"ზედამხედველობა"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"სამსახურის პროფილი"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"კერძო სივრცე"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"კლონის შექმნა"</string>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 176645f..97e550d 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Ұлғайту"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Телефонның микрофонына ауысу керек пе?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Есту аппаратының микрофонына ауысу керек пе?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дауыс жақсы шығу үшін немесе есту аппаратының батарея заряды аз болған жағдайда пайдалануға болады. Микрофонға тек қоңырау кезінде ауысады."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Дауыспен басқару арқылы қоңырау шалу үшін есту аппаратының микрофонын пайдалана аласыз. Микрофонға тек қоңырау кезінде ауысады."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дыбыс дұрыс естілмей тұрғанда немесе есту аппаратының батарея заряды аз болған жағдайда пайдалануға болады. Басқа микрофонға тек қоңырау кезінде ауысады."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Дауыспен басқару арқылы қоңырау шалу үшін есту аппаратының микрофонын пайдалана аласыз. Басқа микрофонға тек қоңырау кезінде ауысады."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Ауысу"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Параметрлер"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> профиліне ауысу…"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Босату алдында бекітпесін ашу өрнегін сұрау"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Босату алдында құпия сөзді сұрау"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Әкімшіңіз орнатты.\nБерілген рұқсаттарды көру үшін параметрлерге өтіңіз."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Әкімшіңіз жаңартты.\nБерілген рұқсаттарды көру үшін параметрлерге өтіңіз."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Әкімші жойған"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Жарайды"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батареяны үнемдеу режимі қараңғы режимді іске қосады және фондық әрекеттерге, кейбір визуалдық әсерлерге, белгілі бір функциялар мен кейбір желі байланыстарына шектеу қояды немесе оларды өшіреді."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Айналдыру"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Кідірту"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Орналастыру"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Жоғары айналдыру"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Төменге айналдыру"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Солға айналдыру"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Оңға айналдыру"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Айналдыру режимінен шығу"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Айналдыру панелі"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ШЕКТЕЛГЕН себетке салынды."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"сурет жіберілді"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Жұмыс 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Сынақ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Жалпы"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Қадағалау"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Жұмыс профилі"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Құпия кеңістік"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клон"</string>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index 63b05e6..e9ee62a 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"សួរ​រក​លំនាំ​ដោះ​សោ​មុន​ពេលដោះខ្ទាស់"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"សួរ​រក​ពាក្យ​សម្ងាត់​មុន​ពេល​ផ្ដាច់"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"បានដំឡើងដោយអ្នកគ្រប់គ្រងរបស់អ្នក។\nចូលទៅកាន់ការកំណត់ ដើម្បីមើលការ​អនុញ្ញាតដែលផ្ដល់ឱ្យ"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"បានធ្វើបច្ចុប្បន្នភាពដោយអ្នកគ្រប់គ្រងរបស់អ្នក។\nចូលទៅកាន់ការកំណត់ ដើម្បីមើលការ​អនុញ្ញាតដែលផ្ដល់ឱ្យ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"លុប​ដោយ​អ្នកគ្រប់គ្រង​របស់​អ្នក"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"យល់ព្រម"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"មុខងារ​សន្សំថ្មបើកទម្រង់រចនាងងឹត និងដាក់កំហិត ឬបិទសកម្មភាពផ្ទៃខាងក្រោយ បែបផែនរូបភាពមួយចំនួន មុខងារជាក់លាក់ និងការតភ្ជាប់បណ្ដាញមួយចំនួន។"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"រំកិល"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ផ្អាក"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ទីតាំង"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"រំកិលឡើងលើ"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"រំកិលចុះក្រោម"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"រំកិល​ទៅ​ឆ្វេង"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"រំកិល​ទៅ​ស្ដាំ"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ចាកចេញពី​មុខងារ​រំកិល"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ផ្ទាំងរំកិល"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ត្រូវបានដាក់​ទៅក្នុងធុង​ដែលបានដាក់កំហិត"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>៖"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"បាន​ផ្ញើរូបភាព"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ការងារទី 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ការធ្វើ​តេស្ត"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ទូទៅ"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"កំពុងគ្រប់គ្រង"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"កម្រងព័ត៌មានការងារ"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"លំហ​ឯកជន"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ក្លូន"</string>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index f56f2c8..316955f 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ವಿರಾಮಗೊಳಿಸಿ"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ಸ್ಥಾನ"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ಮೇಲಕ್ಕೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ಕೆಳಕ್ಕೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ಎಡಕ್ಕೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ಬಲಕ್ಕೆ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ಸ್ಕ್ರಾಲ್ ಮೋಡ್‌ನಿಂದ ನಿರ್ಗಮಿಸಿ"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ಪ್ಯಾನೆಲ್ ಸ್ಕ್ರಾಲ್ ಮಾಡಿ"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ಬಂಧಿತ ಬಕೆಟ್‌ಗೆ ಹಾಕಲಾಗಿದೆ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ಚಿತ್ರವನ್ನು ಕಳುಹಿಸಲಾಗಿದೆ"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ಕೆಲಸ 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ಪರೀಕ್ಷೆ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ಸಮುದಾಯ"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"ಮೇಲ್ವಿಚಾರಣೆಯಾಗುತ್ತಿದೆ"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"ಪ್ರೈವೆಟ್ ಸ್ಪೇಸ್"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ಕ್ಲೋನ್"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 253d162..bd48cb3 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"고정 해제 시 잠금 해제 패턴 요청"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"고정 해제 이전에 비밀번호 요청"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"관리자에 의해 설치되었습니다.\n부여된 권한을 확인하려면 설정으로 이동하세요."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"관리자에 의해 업데이트되었습니다.\n부여된 권한을 확인하려면 설정으로 이동하세요."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"관리자에 의해 삭제되었습니다."</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"확인"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"절전 모드는 어두운 테마를 사용하고 백그라운드 활동, 일부 시각 효과, 특정 기능 및 일부 네트워크 연결을 제한하거나 사용 중지합니다."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"스크롤"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"일시중지"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"위치"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"위로 스크롤"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"아래로 스크롤"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"왼쪽으로 스크롤"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"오른쪽으로 스크롤"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"스크롤 모드 종료"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"패널 스크롤"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 항목이 RESTRICTED 버킷으로 이동함"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"이미지 보냄"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"직장 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"테스트"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"공동"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"감독 중"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"직장 프로필"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"비공개 스페이스"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"클론"</string>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index 96f01ff..906d4a3 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Чоңойтуу"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Телефондун микрофонуна которуласызбы?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Угуу аппаратынын микрофонуна которуласызбы?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Үндүн сапатын жакшыртуу үчүн же угуу аппаратыңыздын батареясы аз болсо, телефондун микрофонун колдоно аласыз. Микрофонуңуз чалуу учурунда гана которулат."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Угуу аппаратыңыздын микрофонун үн режиминде чалуу үчүн колдоно аласыз. Микрофонуңуз чалуу учурунда гана которулат."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Угуу аппаратыңыз жакшы угулбай жатса же батареясы отурайын деп калса, микрофонго которула аласыз. Микрофонго чалуу учурунда гана которуласыз."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Телефон менен сүйлөшүп жатканда угуу аппаратыңыздын микрофонун колдоно аласыз. Микрофонго чалуу учурунда гана которуласыз."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Которулуу"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Параметрлер"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> дегенге которулууда…"</string>
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Сыдыруу"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Тындыруу"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Орду"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Жогору сыдыруу"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Ылдый сыдыруу"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Солго сыдырып кароо"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Оңго сыдырып кароо"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Сыдыруу режиминен чыгуу"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Сыдыруу панели"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ЧЕКТЕЛГЕН чакага коюлган"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"сүрөт жөнөттү"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Жумуш 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Сыноо"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Жалпы"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Көзөмөлдөнүүдө"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Жумуш профили"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Жеке мейкиндик"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клон"</string>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 4905a53..e6222da 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"​ຖາມ​ຫາ​ຮູບ​ແບບ​ປົດ​ລັອກ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"​ຖາມ​ຫາ​ລະ​ຫັດ​ຜ່ານ​ກ່ອນ​ຍົກ​ເລີກ​ການ​ປັກ​ໝຸດ"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"ຕິດຕັ້ງໂດຍຜູ້ເບິ່ງແຍງຂອງທ່ານ.\nເຂົ້າໄປການຕັ້ງຄ່າເພື່ອເບິ່ງສິດທີ່ໄດ້ຮັບອະນຸຍາດ"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"ອັບເດດໂດຍຜູ້ເບິ່ງແຍງຂອງທ່ານ.\nເຂົ້າໄປການຕັ້ງຄ່າເພື່ອເບິ່ງສິດທີ່ໄດ້ຮັບອະນຸຍາດ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"ຖືກລຶບອອກໂດຍຜູ້ເບິ່ງແຍງລະບົບຂອງທ່ານ"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ຕົກລົງ"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ຕົວປະຢັດແບັດເຕີຣີຈະເປີດໃຊ້ຮູບແບບສີສັນມືດ ແລະ ຈຳກັດ ຫຼື ປິດການເຄື່ອນໄຫວໃນພື້ນຫຼັງ, ເອັບເຟັກທາງພາບຈຳນວນໜຶ່ງ, ຄຸນສົມບັດບາງຢ່າງ ແລະ ການເຊື່ອມຕໍ່ເຄືອຂ່າຍບາງອັນ."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ເລື່ອນ"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ຢຸດຊົ່ວຄາວ"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ຕຳແໜ່ງ"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ເລື່ອນຂຶ້ນ"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ເລື່ອນລົງ"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ເລື່ອນໄປທາງຊ້າຍ"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ເລື່ອນໄປທາງຂວາ"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ອອກຈາກໂໝດເລື່ອນ"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ເລື່ອນແຜງ"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ຖືກວາງໄວ້ໃນກະຕ່າ \"ຈຳກັດ\" ແລ້ວ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ສົ່ງຮູບແລ້ວ"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ວຽກ 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ທົດສອບ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ສ່ວນກາງ"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"ການເບິ່ງແຍງກວດກາ"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"ພື້ນທີ່ສ່ວນບຸກຄົນ"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ໂຄລນ"</string>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 07a6c6e..3a28368 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -2275,18 +2275,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Slinkti"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pristabdyti"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozicija"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Slinkti aukštyn"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Slinkti žemyn"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Slinkti į kairę"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Slinkti į dešinę"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Išeiti iš slinkimo režimo"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Slinkimo skydelis"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"„<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>“ įkeltas į grupę APRIBOTA"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"išsiuntė vaizdą"</string>
@@ -2494,8 +2488,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Darbas (3)"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Bandymas"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Bendruomenės"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Prižiūrima"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Darbo profilis"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privati erdvė"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klonuoti"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 60a99b3..b0f6313 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pirms atspraušanas pieprasīt atbloķēšanas kombināciju"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pirms atspraušanas pieprasīt paroli"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalēja jūsu administrators.\nPārejiet uz iestatījumiem, lai skatītu piešķirtās atļaujas."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Instalēja jūsu administrators.\nPārejiet uz iestatījumiem, lai skatītu piešķirtās atļaujas."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dzēsa administrators"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Labi"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Akumulatora enerģijas taupīšanas režīmā tiek ieslēgts tumšais motīvs un tiek ierobežotas vai izslēgtas darbības fonā, daži vizuālie efekti, noteiktas funkcijas un noteikti tīkla savienojumi."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Ritināt"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pārtraukt"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozīcija"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Ritināt augšup"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Ritināt lejup"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Ritināt pa kreisi"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Ritināt pa labi"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izslēgt ritināšanas režīmu"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Ritināšanas panelis"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Pakotne “<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>” ir ievietota ierobežotā kopā."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"nosūtīts attēls"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Darbam (3.)"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Testēšanai"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Kopīgs"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Uzraudzība"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Darba profils"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privātā telpa"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klons"</string>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 6d98869..8b389a0 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Побарај шема за откл. пред откачување"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Побарај лозинка пред откачување"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирано од администраторот.\nОдете во „Поставки“ за да ги прегледате доделените дозволи"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Ажурирано од администраторот.\nОдете во „Поставки“ за да ги прегледате доделените дозволи"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избришано од администраторот"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Во ред"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"„Штедачот на батерија“ вклучува „Темна тема“ и ограничува или исклучува активност во заднина, некои визуелни ефекти, одредени функции и некои мрежни врски."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Лизгање"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Паузирај"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Позиционирај"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Лизгај нагоре"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Лизгај надолу"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Лизгај налево"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Лизгај надесно"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Излези од „Режим на лизгање“"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Табла за лизгање"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> е ставен во корпата ОГРАНИЧЕНИ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"испрати слика"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Работен профил 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Профил за тестирање"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Профил на заедницата"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Вршење надзор"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Работен профил"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Приватен простор"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клониран профил"</string>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index fca58a1..825da18 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"സ്‌ക്രോൾ ചെയ്യുക"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"താൽക്കാലികമായി നിർത്തുക"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"സ്ഥാനം"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"മുകളിലേക്ക് സ്‌ക്രോൾ ചെയ്യുക"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"താഴേക്ക് സ്‌ക്രോൾ ചെയ്യുക"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ഇടത്തേക്ക് സ്‌ക്രോൾ ചെയ്യുക"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"വലത്തേക്ക് സ്‌ക്രോൾ ചെയ്യുക"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"സ്ക്രോൾ മോഡിൽ നിന്ന് പുറത്തുകടക്കുക"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"സ്‌ക്രോൾ പാനൽ"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> നിയന്ത്രിത ബക്കറ്റിലേക്ക് നീക്കി"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ചിത്രം അയച്ചു"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ഔദ്യോഗികം 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ടെസ്‌റ്റ്"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"കമ്മ്യൂണൽ"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"മേൽനോട്ടമുണ്ട്"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"സ്വകാര്യ സ്പേസ്"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ക്ലോൺ ചെയ്യുക"</string>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index 58f4cf7..4222ce1 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -1820,7 +1820,7 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Томруулах"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Утасны микрофон руу сэлгэх үү?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Сонсголын төхөөрөмжийн микрофон руу сэлгэх үү?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дуу чимээг сайжруулахын тулд эсвэл таны сонсголын төхөөрөмжийн батарей бага бол. Энэ нь зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Дуу чимээг сайжруулахын тулд эсвэл таны сонсголын төхөөрөмжийн цэнэг бага үед, зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string>
     <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Та гараас хамаарахгүй дуудлагад сонсголын төхөөрөмжийнхөө микрофоныг ашиглаж болно. Энэ нь зөвхөн дуудлагын үеэр таны микрофоныг сэлгэнэ."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Сэлгэх"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Тохиргоо"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Бэхэлснийг болиулахаас өмнө түгжээ тайлах хээ асуух"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тогтоосныг суллахаас өмнө нууц үг асуух"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Танай админ суулгасан.\nОлгосон зөвшөөрлүүдийг харахын тулд тохиргоо руу очно уу"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Танай админ шинэчилсэн.\nОлгосон зөвшөөрлийг харахын тулд тохиргоо руу очно уу"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Таны админ устгасан"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Батарей хэмнэгч нь Бараан загварыг асааж, дэвсгэрийн үйл ажиллагаа, зарим визуал эффект, тодорхой онцлогууд болон зарим сүлжээний холболтыг хязгаарлах эсвэл унтраана."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Гүйлгэх"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Түр зогсоох"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Байрлал"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Дээш гүйлгэх"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Доош гүйлгэх"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Зүүн тийш гүйлгэх"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Баруун тийш гүйлгэх"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Гүйлгэх горимоос гарах"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Гүйлгэх үйлдлийн түр зуурын самбар"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>-г ХЯЗГААРЛАСАН сагс руу орууллаа"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"зураг илгээсэн"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Ажил 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Туршилт"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Нийтийн"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Хянаж байна"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Ажлын профайл"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Хаалттай орон зай"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клон"</string>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index c37884d..73fc1b6 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन करण्‍यापूर्वी अनलॉक नमुन्यासाठी विचारा"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"अनपिन करण्‍यापूर्वी संकेतशब्दासाठी विचारा"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"तुमच्या ॲडमिनने इंस्टॉल केले आहे.\nदिलेल्या परवानग्या पाहण्यासाठी सेटिंग्जवर जा"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"तुमच्या ॲडमिनने अपडेट केले आहे.\nदिलेल्या परवानग्या पाहण्यासाठी सेटिंग्जवर जा"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"आपल्या प्रशासकाने हटवले"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ओके"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"बॅटरी सेव्हर गडद थीम सुरू करते आणि बॅकग्राउंड ॲक्टिव्हिटी, काही व्हिज्युअल इफेक्ट, ठरावीक वैशिष्ट्ये व काही नेटवर्क कनेक्शन मर्यादित किंवा बंद करते."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"स्क्रोल करा"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"थांबवा"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"स्थिती"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"वर स्क्रोल करा"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"खाली स्क्रोल करा"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"डावीकडे स्क्रोल करा"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"उजवीकडे स्क्रोल करा"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"स्क्रोल करा मोड मधून बाहेर पडा"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"स्क्रोल करा पॅनल"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> हे प्रतिबंधित बादलीमध्ये ठेवण्यात आले आहे"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"इमेज पाठवली आहे"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ऑफिस ३"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"चाचणी"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"सामुदायिक"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"पर्यवेक्षण करत आहे"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"कार्य प्रोफाइल"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"खाजगी स्पेस"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"क्लोन"</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index d675246..4b2bb4d 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Minta corak buka kunci sebelum menyahsemat"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Minta kata laluan sebelum menyahsemat"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Dipasang oleh pentadbir anda.\nAkses tetapan untuk melihat kebenaran yang diberikan"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Dikemaskinikan oleh pentadbir anda.\nAkses tetapan untuk melihat kebenaran yang diberikan"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Dipadamkan oleh pentadbir anda"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Penjimat Bateri menghidupkan tema Gelap dan mengehadkan atau mematikan aktiviti latar, sesetengah kesan visual, ciri tertentu dan sesetengah sambungan rangkaian."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Tatal"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Jeda"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Kedudukan"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Tatal Ke Atas"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Tatal Ke Bawah"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Tatal Ke Kiri"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Tatal ke Kanan"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Keluar Daripada Mod Tatal"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Tatal Panel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> telah diletakkan dalam baldi TERHAD"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"menghantar imej"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Kerja 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Ujian"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Umum"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Mengawas"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil kerja"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Ruang persendirian"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 1a5bc7a..f3160d8 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ပင်မဖြုတ်မီ လော့ခ်ဖွင့်ပုံစံကို မေးရန်"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ပင်မဖြုတ်မီမှာ စကားဝှက်ကို မေးကြည့်ရန်"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"သင့်စီမံခန့်ခွဲသူက ထည့်သွင်းထားသည်။\nပေးထားသည့် ခွင့်ပြုချက်များကို ကြည့်ရန် ဆက်တင်များသို့ သွားပါ"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"သင့်စီမံခန့်ခွဲသူက အပ်ဒိတ်လုပ်ထားသည်။\nပေးထားသည့် ခွင့်ပြုချက်များကို ကြည့်ရန် ဆက်တင်များသို့ သွားပါ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"သင်၏ စီမံခန့်ခွဲသူက ဖျက်လိုက်ပါပြီ"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"‘ဘက်ထရီ အားထိန်း’ က ‘အမှောင်နောက်ခံ’ ကို ဖွင့်ပြီး နောက်ခံလုပ်ဆောင်ချက်၊ ဖန်တီးပြသချက်အချို့၊ ဝန်ဆောင်မှုအချို့နှင့် ကွန်ရက်ချိတ်ဆက်မှုအချို့တို့ကို ကန့်သတ်သည် သို့မဟုတ် ပိတ်သည်။"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"လှိမ့်ရန်"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ခဏရပ်ရန်"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"နေရာ"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"အပေါ်သို့ လှိမ့်ရန်"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"အောက်သို့ လှိမ့်ရန်"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ဘယ်ဘက်သို့ လှိမ့်ရန်"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ညာဘက်သို့ လှိမ့်ရန်"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"လှိမ့်ရန်မုဒ်မှ ထွက်ရန်"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"အကန့်ကို လှိမ့်ခြင်း"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ကို တားမြစ်ထားသော သိမ်းဆည်းမှုအတွင်းသို့ ထည့်ပြီးပါပြီ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>-"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ပုံပို့ထားသည်"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"အလုပ် ၃"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"စမ်းသပ်မှု"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"အများသုံး"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"ကြီးကြပ်နေသည်"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"အလုပ်ပရိုဖိုင်"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"သီးသန့်နေရာ"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ပုံတူပွားရန်"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 4b44dd6..a4026db 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Krev opplåsingsmønster for å løsne apper"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Krev passord for å løsne apper"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Installert av administratoren din.\nGå til innstillingene for å se hvilke tillatelser som er gitt"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Oppdatert av administratoren din.\nGå til innstillingene for å se hvilke tillatelser som er gitt"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Slettet av administratoren din"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Batterisparing slår på mørkt tema og begrenser eller slår av bakgrunnsaktivitet, enkelte visuelle effekter, noen funksjoner og noen nettverkstilkoblinger."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rull"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sett på pause"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Plassér"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rull opp"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rull ned"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rull til venstre"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rull til høyre"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Avslutt rullemodus"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Rullepanel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> er blitt plassert i TILGANGSBEGRENSET-toppmappen"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"har sendt et bilde"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Jobb 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Felles"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Med tilsyn"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Jobbprofil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privat område"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 16e48d5..5e32b96 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -1819,9 +1819,9 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"तपाईंले अर्को पटक यो सर्टकट प्रयोग गर्दा यो सुविधा खुल्ने छ। ३ वटा औँलाले स्क्रिनको पुछारबाट माथितिर स्वाइप गर्नुहोस् र तुरुन्तै औँला उठाउनुहोस्।"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"म्याग्निफिकेसन"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"फोनको माइक प्रयोग गर्ने हो?"</string>
-    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"श्रवण यन्त्रको माइक प्रयोग गर्ने हो?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"अझ राम्रो आवाज सुनाउन वा तपाईंको श्रवण यन्त्रको ब्याट्री कम भएका खण्डमा। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"तपाईं ह्यान्ड्सफ्री तरिकाले कल गर्न आफ्नो श्रवण यन्त्रको माइक्रोफोन प्रयोग गर्न सक्नुहुन्छ। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string>
+    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"हियरिङ एडको माइक प्रयोग गर्ने हो?"</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"अझ राम्रो आवाज सुनाउन वा तपाईंको हियरिङ एडको ब्याट्री कम भएका खण्डमा। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"तपाईं ह्यान्ड्सफ्री तरिकाले कल गर्न आफ्नो हियरिङ एडको माइक्रोफोन प्रयोग गर्न सक्नुहुन्छ। यसले कल भइरहेका बेला मात्र तपाईंको माइक बदल्छ।"</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"बदल्नुहोस्"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"सेटिङ"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"<xliff:g id="NAME">%1$s</xliff:g> मा स्विच गरिँदै छ…"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"अनपिन गर्नअघि अनलक प्याटर्न माग्नुहोस्"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"पिन निकाल्नुअघि पासवर्ड सोध्नुहोस्"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"यो प्याकेज तपाईंका एड्मिनले इन्स्टल गर्नुभएको हो।\nप्रदान गरिएका अनुमतिसम्बन्धी जानकारी हेर्न सेटिङमा जानुहोस्"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"यो प्याकेज तपाईंका एड्मिनले अपडेट गर्नुभएको हो।\nकुन कुन अनुमति दिइएका छन् भन्ने कुरा हेर्न सेटिङमा जानुहोस्"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"तपाईंका प्रशासकले मेट्नुभएको"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ठिक छ"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ब्याट्री सेभरले अँध्यारो थिम अन गर्छ र ब्याकग्राउन्डमा हुने क्रियाकलाप, केही भिजुअल इफेक्ट, निश्चित सुविधा र केही नेटवर्क कनेक्सनहरू अफ गर्छ वा सीमित रूपमा मात्र चल्न दिन्छ।"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"स्क्रोल गर्नुहोस्"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"पज गर्नुहोस्"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"स्थिति"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"माथितिर स्क्रोल गर्नुहोस्"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"तलतिर स्क्रोल गर्नुहोस्"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"बायाँतिर स्क्रोल गर्नुहोस्"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"दायाँतिर स्क्रोल गर्नुहोस्"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"स्क्रोल गर्नुहोस् मोडबाट बाहिरिनुहोस्"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"प्यानल स्क्रोल गर्नुहोस्"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> लाई प्रतिबन्धित बाल्टीमा राखियो"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"फोटो पठाइयो"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index 11c40fd..ebdd4c6 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Ontgrendelingspatroon vragen om app los te maken"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Vraag wachtwoord voor losmaken"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Geïnstalleerd door je beheerder.\nGa naar instellingen om verleende rechten te bekijken."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Geüpdatet door je beheerder.\nGa naar instellingen om verleende rechten te bekijken."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Verwijderd door je beheerder"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Met Batterijbesparing wordt het donkere thema aangezet en worden achtergrondactiviteit, bepaalde visuele effecten, bepaalde functies en sommige netwerkverbindingen beperkt of uitgezet."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scrollen"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauzeren"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Positie"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Omhoog scrollen"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Omlaag scrollen"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Naar links scrollen"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Naar rechts scrollen"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Scrollmodus sluiten"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Deelvenster scrollen"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> is in de bucket RESTRICTED geplaatst"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"heeft een afbeelding gestuurd"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Werk 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Gemeenschappelijk"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Toezicht"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Werkprofiel"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privégedeelte"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Kloon"</string>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index eca778a..2b91cff 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -1820,7 +1820,7 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"ମେଗ୍ନିଫିକେସନ"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ଫୋନ ମାଇକକୁ ସୁଇଚ କରିବେ?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"ଶ୍ରବଣ ଯନ୍ତ୍ର ମାଇକକୁ ସୁଇଚ କରିବେ?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ଭଲ ସାଉଣ୍ଡ ପାଇଁ କିମ୍ବା ଯଦି ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ର ବେଟେରୀ କମ ଥିଲେ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକକୁ ସୁଇଚ କରିଥାଏ।"</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"ଭଲ ସାଉଣ୍ଡ ପାଇଁ କିମ୍ବା ଯଦି ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ରର ବେଟେରୀ କମ ଥାଏ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକକୁ ସୁଇଚ କରିଥାଏ।"</string>
     <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"ହେଣ୍ଡସ-ଫ୍ରି କଲିଂ ପାଇଁ ଆପଣ ଆପଣଙ୍କର ଶ୍ରବଣ ଯନ୍ତ୍ର ମାଇକ୍ରୋଫୋନ ବ୍ୟବହାର କରିପାରିବେ। କଲ ସମୟରେ ଏହା କେବଳ ଆପଣଙ୍କର ମାଇକକୁ ସୁଇଚ କରିଥାଏ।"</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"ସେଟିଂସ"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ ଲକ୍‌ ଖୋଲିବା ପାଟର୍ନ ପଚାରନ୍ତୁ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ଅନପିନ୍‌ କରିବା ପୂର୍ବରୁ ପାସ୍‌ୱର୍ଡ ପଚାରନ୍ତୁ"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଇନଷ୍ଟଲ କରାଯାଇଛି।\nଅନୁମୋଦିତ ଅମୁମତିଗୁଡ଼ିକ ଭ୍ୟୁ କରିବା ପାଇଁ ସେଟିଂସକୁ ଯାଆନ୍ତୁ"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"ଆପଣଙ୍କ ଆଡମିନଙ୍କ ଦ୍ୱାରା ଅପଡେଟ କରାଯାଇଛି।\nଅନୁମୋଦିତ ଅମୁମତିଗୁଡ଼ିକ ଭ୍ୟୁ କରିବା ପାଇଁ ସେଟିଂସକୁ ଯାଆନ୍ତୁ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"ଆପଣଙ୍କ ଆଡମିନ୍‌‌ ଡିଲିଟ୍‍ କରିଛନ୍ତି"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ଠିକ ଅଛି"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ବେଟେରୀ ସେଭର ଗାଢ଼ା ଥିମକୁ ଚାଲୁ କରେ ଏବଂ ପୃଷ୍ଠପଟ କାର୍ଯ୍ୟକଳାପ, କିଛି ଭିଜୁଆଲ ଇଫେକ୍ଟ, କିଛି ଫିଚର ଏବଂ କିଛି ନେଟୱାର୍କ ସଂଯୋଗକୁ ସୀମିତ କିମ୍ବା ବନ୍ଦ କରେ।"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ବିରତ କରନ୍ତୁ"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ସ୍ଥିତି"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ଉପରକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ତଳକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ବାମକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ଡାହାଣକୁ ସ୍କ୍ରୋଲ କରନ୍ତୁ"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ସ୍କ୍ରୋଲ ମୋଡରୁ ବାହାରି ଯାଆନ୍ତୁ"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ସ୍କ୍ରୋଲ ପେନେଲ"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>କୁ ପ୍ରତିବନ୍ଧିତ ବକେଟରେ ରଖାଯାଇଛି"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ଏକ ଛବି ପଠାଯାଇଛି"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ୱାର୍କ 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ଟେଷ୍ଟ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"କମ୍ୟୁନାଲ"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"ନିରୀକ୍ଷଣ କରାଯାଉଛି"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ୱାର୍କ ପ୍ରୋଫାଇଲ"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"ପ୍ରାଇଭେଟ ସ୍ପେସ"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"କ୍ଲୋନ"</string>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 2da2a60..5a9f227 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ਅਨਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਅਣਲਾਕ ਪੈਟਰਨ ਵਾਸਤੇ ਪੁੱਛੋ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ਅਣਪਿੰਨ ਕਰਨ ਤੋਂ ਪਹਿਲਾਂ ਪਾਸਵਰਡ ਮੰਗੋ"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਸਥਾਪਤ ਕੀਤਾ ਗਿਆ।\nਦਿੱਤੀਆਂ ਗਈਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਅੱਪਡੇਟ ਕੀਤਾ ਗਿਆ।\nਦਿੱਤੀਆਂ ਗਈਆਂ ਇਜਾਜ਼ਤਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਸੈਟਿੰਗਾਂ \'ਤੇ ਜਾਓ"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"ਤੁਹਾਡੇ ਪ੍ਰਸ਼ਾਸਕ ਵੱਲੋਂ ਮਿਟਾਇਆ ਗਿਆ"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ਠੀਕ ਹੈ"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"ਬੈਟਰੀ ਸੇਵਰ ਗੂੜ੍ਹੇ ਥੀਮ ਨੂੰ ਚਾਲੂ ਕਰਦਾ ਹੈ ਅਤੇ ਬੈਕਗ੍ਰਾਊਂਡ ਸਰਗਰਮੀ, ਕੁਝ ਦ੍ਰਿਸ਼ਟੀਗਤ ਪ੍ਰਭਾਵਾਂ, ਕੁਝ ਖਾਸ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਅਤੇ ਕੁਝ ਨੈੱਟਵਰਕ ਕਨੈਕਸ਼ਨਾਂ ਨੂੰ ਸੀਮਤ ਜਾਂ ਬੰਦ ਕਰਦਾ ਹੈ।"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"ਸਕ੍ਰੋਲ ਕਰੋ"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"ਰੋਕੋ"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ਸਥਿਤੀ"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ਉੱਪਰ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"ਹੇਠਾਂ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ਖੱਬੇ ਪਾਸੇ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"ਸੱਜੇ ਪਾਸੇ ਵੱਲ ਸਕ੍ਰੋਲ ਕਰੋ"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ਸਕ੍ਰੋਲ ਮੋਡ ਤੋਂ ਬਾਹਰ ਜਾਓ"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ਸਕ੍ਰੋਲ ਪੈਨਲ"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ਨੂੰ ਪ੍ਰਤਿਬੰਧਿਤ ਖਾਨੇ ਵਿੱਚ ਪਾਇਆ ਗਿਆ ਹੈ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ਚਿੱਤਰ ਭੇਜਿਆ ਗਿਆ"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ਕੰਮ ਸੰਬੰਧੀ 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ਜਾਂਚ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ਭਾਈਚਾਰਕ"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"ਨਿਗਰਾਨੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"ਪ੍ਰਾਈਵੇਟ ਸਪੇਸ"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ਕਲੋਨ"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 730429d..5f02c1f 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -1967,8 +1967,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Aby odpiąć, poproś o wzór odblokowania"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Aby odpiąć, poproś o hasło"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Zainstalowany przez administratora.\nOtwórz ustawienia, aby wyświetlić przyznane uprawnienia"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Zaktualizowany przez administratora.\nAby zobaczyć przyznane uprawnienia, przejdź do ustawień"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Usunięty przez administratora"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Oszczędzanie baterii uruchamia ciemny motyw oraz wyłącza lub ogranicza aktywność w tle, niektóre efekty wizualne, pewne funkcje oraz wybrane połączenia sieciowe."</string>
@@ -2276,18 +2275,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Przewijanie"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Wstrzymaj"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozycja"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Przewiń w górę"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Przewiń w dół"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Przewiń w lewo"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Przewiń w prawo"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Wyłącz tryb przewijania"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Przewiń panel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Umieszczono pakiet <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> w zasobniku danych RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"wysłano obraz"</string>
@@ -2495,8 +2488,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Służbowy 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Testowy"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Wspólny"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzorujesz"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil służbowy"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Przestrzeń prywatna"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index cea3b73..32d883a 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Atualizado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rolar"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posição"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rolar para cima"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rolar para baixo"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rolar para a esquerda"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rolar para a direita"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sair do modo de rolagem"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Painel de rolagem"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no intervalo \"RESTRITO\""</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"enviou uma imagem"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Trabalho 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Público"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisionando"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabalho"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espaço privado"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 2951d482..57507df 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -2274,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Deslocar"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posição"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Deslocar página para cima"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Deslocar página para baixo"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Deslocar página para a esquerda"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Deslocar página para a direita"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sair do modo de deslocamento"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Deslocar painel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no contentor RESTRITO."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"enviou uma imagem"</string>
@@ -2493,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Trabalho 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Comum"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"A supervisionar"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabalho"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espaço privado"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index cea3b73..32d883a 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Pedir padrão de desbloqueio antes de liberar"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Pedir senha antes de liberar"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Atualizado pelo administrador.\nAcesse as configurações para conferir as permissões concedidas"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Excluído pelo seu administrador"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"A Economia de bateria ativa o tema escuro e limita ou desativa atividades em segundo plano, alguns efeitos visuais, recursos específicos e algumas conexões de rede."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Rolar"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausar"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posição"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Rolar para cima"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Rolar para baixo"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Rolar para a esquerda"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Rolar para a direita"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Sair do modo de rolagem"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Painel de rolagem"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> foi colocado no intervalo \"RESTRITO\""</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"enviou uma imagem"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Trabalho 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Teste"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Público"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supervisionando"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Perfil de trabalho"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Espaço privado"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 19158cc..2e6f58dc 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Solicită mai întâi modelul pentru deblocare"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Solicită parola înainte de a anula fixarea"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instalat de administrator.\nAccesează setările ca să vezi permisiunile acordate."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Instalat de administrator.\nAccesează setările ca să vezi permisiunile acordate"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Șters de administrator"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Economisirea bateriei activează tema întunecată și restricționează sau dezactivează activitatea în fundal, unele efecte vizuale, alte funcții și câteva conexiuni la rețea."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Derulează"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Întrerupe"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Poziție"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Derulează în sus"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Derulează în jos"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Derulează la stânga"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Derulează la dreapta"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Ieși din modul de derulare"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Panou de derulare"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> a fost adăugat la grupul RESTRICȚIONATE"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"a trimis o imagine"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Serviciu 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Comun"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Supraveghere activă"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profil de serviciu"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Spațiu privat"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clonă"</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 136f76a..2beebd7 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -1967,8 +1967,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запрашивать графический ключ"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запрашивать пароль"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Установлено администратором.\nЧтобы посмотреть предоставленные разрешения, перейдите в настройки."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Обновлено администратором.\nЧтобы посмотреть предоставленные разрешения, перейдите в настройки."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Удалено администратором"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"В режиме энергосбережения включается тёмная тема, ограничиваются или отключаются фоновые процессы, а также некоторые визуальные эффекты, часть функций и сетевых подключений."</string>
@@ -2276,18 +2275,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Прокрутить"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Приостановить"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Положение"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Прокрутка вверх"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Прокрутка вниз"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Прокрутка влево"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Прокрутка вправо"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Отключить режим прокрутки"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Панель прокрутки"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Приложение \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" помещено в категорию с ограниченным доступом."</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"Отправлено изображение"</string>
@@ -2495,8 +2488,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Рабочий 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Тестовый"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Совместный"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Управляющий профиль"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Рабочий профиль"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Частное пространство"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клонированный"</string>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 7a4de0e..a59187c 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"ගැලවීමට පෙර අගුළු අරින රටාව සඳහා අසන්න"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"ගැලවීමට පෙර මුරපදය විමසන්න"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"ඔබේ පරිපාලකයා විසින් ස්ථාපන කරනු ලබයි.\nදෙන ලද අවසර බැලීමට සැකසීම් වෙත යන්න"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"ඔබේ පරිපාලක විසින් යාවත්කාලීන කරන ලදි.\n ලබා දී ඇති අවසර බැලීමට සැකසීම් වෙත යන්න"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"ඔබගේ පරිපාලක මඟින් මකා දමා ඇත"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"හරි"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"බැටරි සුරැකුම අඳුරු තේමාව ක්‍රියාත්මක කර පසුබිම් ක්‍රියාකාරකම්, සමහර දෘශ්‍ය ප්‍රයෝග, යම් විශේෂාංග සහ සමහර ජාල සම්බන්ධතා සීමා හෝ ක්‍රියාවිරහිත කරයි."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"අනුචලනය කරන්න"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"විරාම කරන්න"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"ස්ථානය"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"ඉහළට අනුචලනය කරන්න"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"පහළට අනුචලනය කරන්න"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"වමට අනුචලනය කරන්න"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"දකුණට අනුචලනය කරන්න"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"අනුචලන ප්‍රකාරයෙන් පිටවන්න"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"අනුචලන පැනලය"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> අවහිර කළ බාල්දියට දමා ඇත"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"රූපයක් එව්වා"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"කාර්යාලය 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"පරීක්ෂණය"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"වාර්ගික"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"අධීක්ෂණය කිරීම"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"කාර්යාල පැතිකඩ"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"රහසිගත අවකාශය"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"ක්ලෝන කරන්න"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index c47ce65..999000e 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -1822,8 +1822,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Zväčšenie"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Chcete prepnúť na mikrofón telefónu?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Chcete prepnúť na mikrofón načúvadla?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Keď chcete zlepšiť zvuk alebo ak je batéria načúvadla slabá. Týmto iba prepnete mikrofón počas hovoru."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Volať handsfree môžete pomocou mikrofónu načúvadla. Týmto iba prepnete mikrofón počas hovoru."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Pre lepší zvuk alebo ak je batéria načúvadla takmer vybitá. Mikrofón sa prepne iba na čas hovoru."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Pomocou mikrofónu načúvadla môžete volať handsfree. Mikrofón sa prepne iba na čas hovoru."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Prepnúť"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavenia"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Prepína sa na účet <xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -2275,18 +2275,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Posúvať"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pozastaviť"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Pozícia"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Posunúť nahor"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Posunúť nadol"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Posunúť doľava"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Posunúť doprava"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Ukončiť režim posúvania"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Posúvateľný panel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Balík <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> bol vložený do kontajnera OBMEDZENÉ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"odoslal(a) obrázok"</string>
@@ -2494,8 +2488,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"3. pracovný"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Spoločné"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Dohľad"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Pracovný profil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Súkromný priestor"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 07cb71c..4751cb9 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -1821,9 +1821,9 @@
     <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Funkcija se bo odprla, ko boste naslednjič uporabili to bližnjico. S tremi prsti povlecite navzgor z dna zaslona in hitro spustite."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Povečava"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Želite preklopiti na mikrofon telefona?"</string>
-    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite preklopiti na mikrofon za slušni aparat?"</string>
+    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Želite preklopiti na mikrofon slušnega aparata?"</string>
     <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Za boljši zvok ali pri skoraj prazni bateriji slušnega aparata. S tem preklopite mikrofon samo med klicem."</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon za slušni aparat lahko uporabljate za prostoročno klicanje. S tem preklopite mikrofon samo med klicem."</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Mikrofon slušnega aparata lahko uporabljate za prostoročno klicanje. S tem preklopite mikrofon samo med klicem."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Preklopi"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Nastavitve"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"Preklapljanje na uporabnika <xliff:g id="NAME">%1$s</xliff:g> …"</string>
@@ -2275,18 +2275,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Drsenje"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Začasna zaustavitev"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Položaj"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Pomik gor"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Pomik dol"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Pomik levo"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Pomik desno"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Izhod iz načina pomikanja"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Podokno za pomikanje"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Paket <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> je bil dodan v segment OMEJENO"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"je poslal(-a) sliko"</string>
@@ -2494,8 +2488,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Delo 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Preizkus"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Skupno"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Nadzor"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Delovni profil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Zasebni prostor"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index 1b3feed..a15cf4e 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Kërko motivin e shkyçjes para heqjes së gozhdimit"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Kërko fjalëkalim para heqjes nga gozhdimi."</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Instaluar nga administratori.\nShko te cilësimet për të shikuar lejet e dhëna"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Përditësuar nga administratori.\nShko te cilësimet për të shikuar lejet e dhëna"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Fshirë nga administratori"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Në rregull"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"\"Kursyesi i baterisë\" aktivizon \"Temën e errët\" dhe kufizon ose çaktivizon aktivitetin në sfond, disa efekte vizuale, veçori të caktuara dhe disa lidhje të rrjetit."</string>
@@ -2493,8 +2492,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Puna 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"I përbashkët"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Në mbikëqyrje"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profili i punës"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Hapësira private"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 24624f7..112173a 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -1966,8 +1966,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Тражи шаблон за откључавање пре откачињања"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Тражи лозинку пре откачињања"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Инсталирао је администратор.\nИдите у подешавања да бисте видели одобрене дозволе"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Ажурирао је администратор.\nИдите у подешавања да бисте видели одобрене дозволе"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Избрисао је администратор"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Потврди"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Уштеда батерије укључује тамну тему и ограничава или искључује активности у позадини, неке визуелне ефекте, одређене функције и неке мрежне везе."</string>
@@ -2275,18 +2274,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Скролујте"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Паузирај"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Позиција"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Скролуј нагоре"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Скролуј надоле"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Скролуј улево"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Скролуј удесно"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Изађи из режима скроловања"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Окно за скроловање"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> је додат у сегмент ОГРАНИЧЕНО"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"је послао/ла слику"</string>
@@ -2494,8 +2487,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Посао 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Тест"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Заједничко"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Надзире се"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Пословни профил"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Приватан простор"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Клонирано"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index c471f06..5cb528b 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Scrolla"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pausa"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Position"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Scrolla uppåt"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Scrolla nedåt"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Scrolla åt vänster"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Scrolla åt höger"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Avsluta scrollningsläget"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scrollningspanel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> har placerats i hinken RESTRICTED"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"har skickat en bild"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Arbete 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Allmän"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Kontrollerar"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Jobbprofil"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Privat utrymme"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klona"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 2a920b23..5207e03 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Omba mchoro wa kufungua kabla hujabandua"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Omba nenosiri kabla hujabandua"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Kimewekwa na msimamizi wako.\nNenda kwenye mipangilio ili uone ruhusa zilizotolewa"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Imesasishwa na msimamizi wako.\nNenda kwenye mipangilio ili uone ruhusa zilizotolewa"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Imefutwa na msimamizi wako"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Sawa"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Kiokoa Betri huwasha Mandhari meusi na kudhibiti au kuzima shughuli za chinichini, baadhi ya madoido yanayoonekana, vipengele fulani na baadhi ya miunganisho ya mtandao."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Sogeza"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Sitisha"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Nafasi"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Sogeza Juu"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Sogeza Chini"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Sogeza Kushoto"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Sogeza Kulia"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Funga Hali ya Kusogeza"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Sogeza Kidirisha"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> kimewekwa katika kikundi KILICHODHIBITIWA"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"alituma picha"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Wa 3 wa Kazini"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Jaribio"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Unaoshirikiwa"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Unasimamia"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Wasifu wa kazini"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Sehemu ya faragha"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Nakala"</string>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index 1fade55..015ce08 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"அகற்றும் முன் அன்லாக் பேட்டர்னைக் கேள்"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"அகற்றும் முன் கடவுச்சொல்லைக் கேள்"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"உங்கள் நிர்வாகி நிறுவியுள்ளார்.\nவழங்கப்பட்டுள்ள அனுமதிகளை பார்க்க அமைப்புகளுக்குச் செல்லவும்"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"உங்கள் நிர்வாகி புதுப்பித்துள்ளார்.\nவழங்கப்பட்டுள்ள அனுமதிகளைப் பார்க்க அமைப்புகளுக்குச் செல்லவும்"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"உங்கள் நிர்வாகி நீக்கியுள்ளார்"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"சரி"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"பேட்டரி சேமிப்பான் அம்சம் டார்க் தீமை இயக்குவதோடு பின்னணிச் செயல்பாடு, சில விஷுவல் எஃபக்ட்கள், குறிப்பிட்ட அம்சங்கள், சில நெட்வொர்க் இணைப்புகள் ஆகியவற்றைக் கட்டுப்படுத்தும் அல்லது முடக்கும்."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"நகர்த்தும்"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"இடைநிறுத்து"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"நிலை"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"மேலே நகர்த்து"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"கீழே நகர்த்து"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"இடப்புறம் நகர்த்து"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"வலப்புறம் நகர்த்து"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"நகர்த்துதல் பயன்முறையில் இருந்து வெளியேறு"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"பேனலை நகர்த்து"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> என்பதை வரம்பிடப்பட்ட பக்கெட்திற்குள் சேர்க்கப்பட்டது"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"படம் அனுப்பப்பட்டது"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"பணி 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"பரிசோதனை"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"பொது"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"கண்காணிக்கப்படுகிறது"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"பணிக் கணக்கு"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"ரகசிய இடம்"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"குளோன்"</string>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 4f6eaf3..74ab1e8 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -1820,7 +1820,7 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"మ్యాగ్నిఫికేషన్"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"ఫోన్ మైక్‌కు మారాలా?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"వినికిడి పరికరం మైక్‌కు మారాలా?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"మెరుగైన సౌండ్ కోసం లేదా మీ వినికిడి పరికరం బ్యాటరీ తక్కువగా ఉన్నప్పుడు. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్‌ను మారుస్తుంది."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"మెరుగైన సౌండ్ కావాల్సినప్పుడు లేదా మీ వినికిడి పరికరం బ్యాటరీ తక్కువగా ఉన్నప్పుడు ఇది ఉపయోగపడుతుంది. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్‌ను మారుస్తుంది."</string>
     <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"హ్యాండ్స్-ఫ్రీ కాలింగ్ కోసం మీరు మీ వినికిడి పరికరాన్ని ఉపయోగించవచ్చు. ఇది కాల్ సమయంలో మాత్రమే మీ మైక్‌ను మారుస్తుంది."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"మారండి"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"సెట్టింగ్‌లు"</string>
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"స్క్రోల్ చేయండి"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"పాజ్ చేయండి"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"స్థానం"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"పైకి స్క్రోల్ చేయండి"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"కిందికి స్క్రోల్ చేయండి"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"ఎడమ వైపునకు స్క్రోల్ చేయండి"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"కుడి వైపునకు స్క్రోల్ చేయండి"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"స్క్రోల్ మోడ్ నుండి ఎగ్జిట్ అవ్వండి"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"ప్యానెల్‌కు స్క్రోల్ చేయండి"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> పరిమితం చేయబడిన బకెట్‌లో ఉంచబడింది"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ఇమేజ్‌ను పంపారు"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"ఆఫీస్ 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"పరీక్ష"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"కమ్యూనల్"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"పర్యవేక్షిస్తున్నారు"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"వర్క్ ప్రొఫైల్"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"ప్రైవేట్ స్పేస్"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"క్లోన్"</string>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index b67f382..224ac78 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"เลื่อน"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"หยุดชั่วคราว"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"วางตำแหน่ง"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"เลื่อนขึ้น"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"เลื่อนลง"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"เลื่อนไปทางซ้าย"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"เลื่อนไปทางขวา"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"ออกจากโหมดเลื่อน"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"เลื่อนแผง"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"ใส่ <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ในที่เก็บข้อมูลที่ถูกจำกัดแล้ว"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ส่งรูปภาพ"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"งาน 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ทดสอบ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"ส่วนกลาง"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"ผู้ควบคุมดูแล"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"โปรไฟล์งาน"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"พื้นที่ส่วนตัว"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"โคลน"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 3c38088..9b6ecd3 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Mag-scroll"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"I-pause"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Posisyon"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Mag-scroll Pataas"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Mag-scroll Pababa"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Mag-scroll Pakaliwa"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Mag-scroll Pakanan"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Umalis sa Scroll Mode"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Scroll Panel"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Inilagay ang <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> sa PINAGHIHIGPITANG bucket"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"nagpadala ng larawan"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Trabaho 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Communal"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Namamahala"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Profile sa trabaho"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Pribadong space"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Clone"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index dfaa061..ea4cfa6 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -962,7 +962,7 @@
     <string name="phoneTypeMms" msgid="1799747455131365989">"MMS"</string>
     <string name="eventTypeCustom" msgid="3257367158986466481">"Özel"</string>
     <string name="eventTypeBirthday" msgid="7770026752793912283">"Doğum günü"</string>
-    <string name="eventTypeAnniversary" msgid="4684702412407916888">"Yıldönümü"</string>
+    <string name="eventTypeAnniversary" msgid="4684702412407916888">"Yıl dönümü"</string>
     <string name="eventTypeOther" msgid="530671238533887997">"Diğer"</string>
     <string name="emailTypeCustom" msgid="1809435350482181786">"Özel"</string>
     <string name="emailTypeHome" msgid="1597116303154775999">"Ev"</string>
@@ -1820,7 +1820,7 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Büyütme"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofonuna geçilsin mi?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"İşitme cihazı mikrofonuna geçilsin mi?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Daha iyi ses kalitesi için veya işitme cihazınızın pili azaldığında Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Daha iyi ses kalitesi için veya işitme cihazınızın pili azaldığında. Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string>
     <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Eller serbest modunda arama yapmak için işitme cihazı mikrofonunu kullanabilirsiniz. Bu işlem yalnızca görüşme sırasında mikrofonunuzu değiştirir."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Geçiş yap"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Ayarlar"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Sabitlemeyi kaldırmadan önce kilit açma desenini sor"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Sabitlemeyi kaldırmadan önce şifre sor"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Yöneticiniz tarafından yüklendi.\nVerilen izinleri görüntülemek için ayarlara gidin"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Yöneticiniz tarafından güncellendi.\nVerilen izinleri görüntülemek için ayarlara gidin"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Yöneticiniz tarafından silindi"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"Tamam"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Pil Tasarrufu, Koyu temayı açıp arka plan etkinliğini, bazı görsel efektleri, belirli özellikleri ve bazı ağ bağlantılarını sınırlandırır veya kapatır."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Kaydırma"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Duraklatma"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Konum"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Yukarı Kaydır"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Aşağı Kaydır"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Sola Kaydır"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Sağa Kaydır"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Kaydırma Modundan Çık"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Paneli Kaydır"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> KISITLANMIŞ gruba yerleştirildi"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"bir resim gönderildi"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"İş 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Paylaşılan"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Gözetim"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"İş profili"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Özel alan"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Klon"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 34dda97..693b16e 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -1967,8 +1967,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Запитувати ключ розблокування перед відкріпленням"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Запитувати пароль перед відкріпленням"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Установлено адміністратором.\nПерейдіть у налаштування, щоб переглянути надані дозволи."</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Оновлено адміністратором.\nПерейдіть у налаштування, щоб переглянути надані дозволи."</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Видалено адміністратором"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"ОК"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"У режимі енергозбереження вмикається темна тема й обмежуються чи вимикаються дії у фоновому режимі, а також деякі візуальні ефекти, функції та з’єднання з мережами."</string>
@@ -2276,18 +2275,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Прокрутити"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Призупинити"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Змінити позицію"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Прокрутити вгору"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Прокрутити вниз"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Прокрутити ліворуч"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Прокрутити праворуч"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Вимкнути режим прокручування"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Панель прокручування"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Пакет \"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>\" додано в сегмент з обмеженнями"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"надіслано зображення"</string>
@@ -2495,8 +2488,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Робочий профіль 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Тестовий профіль"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Спільний профіль"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Батьківськ. контроль"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Робочий профіль"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Приватний простір"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Копія профілю"</string>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 31b5999..df87d192 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -21,7 +21,7 @@
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="byteShort" msgid="202579285008794431">"بائٹس"</string>
-    <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
+    <string name="fileSizeSuffix" msgid="4233671691980131257">"<xliff:g id="NUMBER">%1$s</xliff:g>‎ <xliff:g id="UNIT">%2$s</xliff:g>"</string>
     <string name="untitled" msgid="3381766946944136678">"‏‎&gt;‎بلا عنوان‎&lt;‎"</string>
     <string name="emptyPhoneNumber" msgid="5812172618020360048">"(کوئی فون نمبر نہیں ہے)"</string>
     <string name="unknownName" msgid="7078697621109055330">"نامعلوم"</string>
@@ -2273,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"اسکرول کریں"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"موقوف کریں"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"پوزیشن"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"اوپر اسکرول کریں"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"نیچے اسکرول کریں"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"بائیں اسکرول کریں"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"دائیں اسکرول کریں"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"اسکرول موڈ سے باہر نکلیں"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"اسکرول پینل"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> کو پابند کردہ بکٹ میں رکھ دیا گیا ہے"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"ایک تصویر بھیجی"</string>
@@ -2492,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"تیسری دفتری پروفائل"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"ٹیسٹ"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"کمیونل"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"نگرانی کرنے والی"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"دفتری پروفائل"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"پرائیویٹ اسپیس"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"کلون"</string>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 35c35ac..f7b10bf 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -1818,9 +1818,9 @@
     <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 2 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"Keyingi safar shu buyruqdan foydalanganingizda funksiya ochiladi. Ekranning pastidan 3 barmoq bilan tepaga suring va darhol qoʻyib yuboring."</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"Kattalashtirish"</string>
-    <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofoniga almashtirilsinmi?"</string>
-    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Eshitish moslamasi mikrofoniga almashtirilsinmi?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Tovush yaxshilanishi uchun yoki eshitish moslamasi batareyasi quvvati kam boʻlsa. Bu faqat chaqiruv paytida mikrofonni almashtiradi."</string>
+    <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"Telefon mikrofoniga almashilsinmi?"</string>
+    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"Eshitish moslamasi mikrofoniga almashilsinmi?"</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"Tovush sifati sizni qoniqtirmasa yoki eshitish moslamasi batareyasi quvvati kamligida telefon mikrofonidan foydalanishingiz mumkin. Mikrofon faqat chaqiruv vaqtida almashadi."</string>
     <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"Garniturali chaqiruv uchun eshitish moslamasi mikrofonidan foydalanish mumkin. Bu faqat chaqiruv paytida mikrofonni almashtiradi."</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"Almashtirish"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"Sozlamalar"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Yechishdan oldin grafik kalit so‘ralsin"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Bo‘shatishdan oldin parol so‘ralsin"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Administrator oʻrnatgan.\nBerilgan ruxsatlarni koʻrish uchun sozlamalarni oching"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Administrator yangilagan.\nBerilgan ruxsatlarni koʻrish uchun sozlamalarni oching"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Administrator tomonidan o‘chirilgan"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Quvvat tejash funksiyasi Tungi mavzuni va cheklovlarni yoqadi hamda fondagi harakatlar, vizual effektlar, ayrim funksiyalar va tarmoq aloqalari kabi boshqa funksiyalarni faolsizlantiradi yoki cheklaydi."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Aylantirish"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Pauza"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Joylashuvi"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Tepaga varaqlash"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Pastga varaqlash"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Chapga varaqlash"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Oʻngga varaqlash"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Varaqlash rejimidan chiqish"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Varaqlash paneli"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> cheklangan turkumga joylandi"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"rasm yuborildi"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Ish 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Test"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Umumiy"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Nazorat ostida"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Ish profili"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Maxfiy makon"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Nusxalash"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 626625f..4ee534c 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Hỏi hình mở khóa trước khi bỏ ghim"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Hỏi mật khẩu trước khi bỏ ghim"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Do quản trị viên của bạn cài đặt.\nChuyển đến phần cài đặt để xem các quyền được cấp"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Do quản trị viên của bạn cập nhật.\nChuyển đến phần cài đặt để xem các quyền được cấp"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Do quản trị viên của bạn xóa"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"OK"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Trình tiết kiệm pin sẽ bật Giao diện tối, đồng thời hạn chế hoặc tắt hoạt động chạy trong nền, một số hiệu ứng hình ảnh, các tính năng nhất định và một số đường kết nối mạng."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Cuộn"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Tạm dừng"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Vị trí"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Cuộn lên"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Cuộn xuống"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Cuộn sang trái"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Cuộn sang phải"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Thoát khỏi chế độ cuộn"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Cuộn bảng điều khiển"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"Đã đưa <xliff:g id="PACKAGE_NAME">%1$s</xliff:g> vào bộ chứa BỊ HẠN CHẾ"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"đã gửi hình ảnh"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Công việc 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Kiểm thử"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Dùng chung"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Giám sát"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Hồ sơ công việc"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Không gian riêng tư"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Nhân bản"</string>
diff --git a/core/res/res/values-w192dp/dimens_watch.xml b/core/res/res/values-w192dp/dimens_watch.xml
new file mode 100644
index 0000000..a3730aa
--- /dev/null
+++ b/core/res/res/values-w192dp/dimens_watch.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <!--  watch's indeterminate progress bar dimens based on the current screen size -->
+    <dimen name="loader_horizontal_min_width_watch">67dp</dimen>
+    <dimen name="loader_horizontal_min_height_watch">15dp</dimen>
+</resources>
diff --git a/core/res/res/values-w204dp/dimens_watch.xml b/core/res/res/values-w204dp/dimens_watch.xml
new file mode 100644
index 0000000..3509474
--- /dev/null
+++ b/core/res/res/values-w204dp/dimens_watch.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <!--  watch's indeterminate progress bar dimens based on the current screen size -->
+    <dimen name="loader_horizontal_min_width_watch">70dp</dimen>
+    <dimen name="loader_horizontal_min_height_watch">15dp</dimen>
+</resources>
diff --git a/core/res/res/values-w216dp/dimens_watch.xml b/core/res/res/values-w216dp/dimens_watch.xml
new file mode 100644
index 0000000..96d80ab
--- /dev/null
+++ b/core/res/res/values-w216dp/dimens_watch.xml
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources>
+    <!--  watch's indeterminate progress bar dimens based on the current screen size -->
+    <dimen name="loader_horizontal_min_width_watch">74dp</dimen>
+    <dimen name="loader_horizontal_min_height_watch">16dp</dimen>
+</resources>
\ No newline at end of file
diff --git a/core/res/res/values-w228dp/dimens_watch.xml b/core/res/res/values-w228dp/dimens_watch.xml
new file mode 100644
index 0000000..960e322
--- /dev/null
+++ b/core/res/res/values-w228dp/dimens_watch.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<resources>
+    <!--  watch's indeterminate progress bar dimens based on the current screen size -->
+    <dimen name="loader_horizontal_min_width_watch">78dp</dimen>
+    <dimen name="loader_horizontal_min_height_watch">16dp</dimen>
+</resources>
diff --git a/core/res/res/values-w240dp/dimens_watch.xml b/core/res/res/values-w240dp/dimens_watch.xml
new file mode 100644
index 0000000..d8478a8
--- /dev/null
+++ b/core/res/res/values-w240dp/dimens_watch.xml
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<resources>
+    <!--  watch's indeterminate progress bar dimens based on the current screen size -->
+    <dimen name="loader_horizontal_min_width_watch">82dp</dimen>
+    <dimen name="loader_horizontal_min_height_watch">17dp</dimen>
+</resources>
diff --git a/core/res/res/values-watch/config.xml b/core/res/res/values-watch/config.xml
index ef5875e..57a09ea 100644
--- a/core/res/res/values-watch/config.xml
+++ b/core/res/res/values-watch/config.xml
@@ -114,4 +114,7 @@
     <!-- By default ActivityOptions#makeScaleUpAnimation is only used between activities. This
      config enables OEMs to support its usage across tasks.-->
     <bool name="config_enableCrossTaskScaleUpAnimation">true</bool>
+
+    <!-- The amount of friction applied to scrolls and flings. -->
+    <item name="config_scrollFriction" format="float" type="dimen">0.023</item>
 </resources>
diff --git a/core/res/res/values-watch/styles_device_defaults.xml b/core/res/res/values-watch/styles_device_defaults.xml
index fb7dbb0..eeb66e7 100644
--- a/core/res/res/values-watch/styles_device_defaults.xml
+++ b/core/res/res/values-watch/styles_device_defaults.xml
@@ -42,5 +42,8 @@
         <item name="indeterminateOnly">false</item>
         <!-- Use Wear Material3 ring shape as default determinate drawable -->
         <item name="progressDrawable">@drawable/progress_ring_watch</item>
+        <item name="indeterminateDrawable">@drawable/loader_horizontal_watch</item>
+        <item name="android:minWidth">@dimen/loader_horizontal_min_width_watch</item>
+        <item name="android:minHeight">@dimen/loader_horizontal_min_height_watch</item>
     </style>
 </resources>
diff --git a/core/res/res/values-watch/themes_device_defaults.xml b/core/res/res/values-watch/themes_device_defaults.xml
index 60aec53..4738d20 100644
--- a/core/res/res/values-watch/themes_device_defaults.xml
+++ b/core/res/res/values-watch/themes_device_defaults.xml
@@ -48,6 +48,9 @@
         <item name="disabledAlpha">@dimen/disabled_alpha_device_default</item>
         <item name="primaryContentAlpha">@dimen/primary_content_alpha_device_default</item>
         <item name="secondaryContentAlpha">@dimen/secondary_content_alpha_device_default</item>
+
+        <!-- Material3 default delay before scroll bar fading animation. -->
+        <item name="scrollbarDefaultDelayBeforeFade">1000</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar -->
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 921a464..98069c6 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -1820,8 +1820,8 @@
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大功能"</string>
     <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要切换为手机麦克风吗?"</string>
     <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要切换为助听器麦克风吗?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可改善音质,或在助听器电池电量不足时使用。此操作只会切换通话期间的麦克风。"</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"您可以使用助听器麦克风进行免提通话。此操作只会切换通话期间的麦克风。"</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可改善音质,或在助听器电池电量不足时使用。系统仅会在通话期间切换麦克风。"</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"您可以使用助听器麦克风进行免提通话。系统只会在通话期间切换麦克风。"</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切换"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"设置"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定前要求绘制解锁图案"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消时要求输入密码"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"由您的管理员安装。\n前往设置可查看已授予的权限"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"由您的管理员更新。\n前往设置可查看已授予的权限"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由您的管理员删除"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"确定"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"在省电模式下,系统会启用深色主题,并限制或关闭后台活动、某些视觉效果、特定功能和部分网络连接。"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"滚动"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暂停"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"向上滚动"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"向下滚动"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"向左滚动"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"向右滚动"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"退出滚动模式"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"滚动面板"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已被放入受限存储分区"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"发送了一张图片"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"工作 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"测试"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"共用"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"监管"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"工作资料"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"私密空间"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"克隆"</string>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 8681d03..038973d 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -1818,10 +1818,10 @@
     <string name="accessibility_gesture_instructional_text" msgid="4133877896011098550">"下次使用此快速鍵時,就會開啟此功能。請用 2 隻手指從螢幕底部向上滑動並快速放開。"</string>
     <string name="accessibility_gesture_3finger_instructional_text" msgid="1124458279366968154">"下次使用此快速鍵時,就會開啟此功能。請用 3 隻手指從螢幕底部向上滑動並快速放開。"</string>
     <string name="accessibility_magnification_chooser_text" msgid="1502075582164931596">"放大"</string>
-    <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要切換至手機麥克風嗎?"</string>
-    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要切換至助聽器麥克風嗎?"</string>
-    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"可改善音質,也在助聽器電量不足時適用。此操作只會切換通話期間的麥克風。"</string>
-    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"你可使用助聽器麥克風進行免提通話。此操作只會切換通話期間的麥克風。"</string>
+    <string name="hearing_device_switch_phone_mic_notification_title" msgid="6645178038359708836">"要轉用手機麥克風嗎?"</string>
+    <string name="hearing_device_switch_hearing_mic_notification_title" msgid="4612074852145289569">"要轉用助聽器麥克風嗎?"</string>
+    <string name="hearing_device_switch_phone_mic_notification_text" msgid="1332426273666077412">"這樣可改善音質,助聽器電量不足時亦適用。系統只會在通話期間切換麥克風。"</string>
+    <string name="hearing_device_switch_hearing_mic_notification_text" msgid="8288368365767284208">"你可使用助聽器麥克風進行免提通話。系統只會在通話期間切換麥克風。"</string>
     <string name="hearing_device_notification_switch_button" msgid="3619524619430941300">"切換"</string>
     <string name="hearing_device_notification_settings_button" msgid="6673651052880279178">"設定"</string>
     <string name="user_switching_message" msgid="1912993630661332336">"正在切換至<xliff:g id="NAME">%1$s</xliff:g>…"</string>
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須提供解鎖圖案"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"已由你的管理員安裝。\n請前往設定查看已授予的權限"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"已由你的管理員更新。\n請前往設定查看已授予的權限"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"好"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"「慳電模式」會開啟深色主題背景,並限制或關閉背景活動、部分視覺效果、特定功能和部分網絡連線。"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"捲動"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暫停"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"向上捲動"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"向下捲動"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"向左捲動"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"向右捲動"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"退出捲動模式"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"捲動面板"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> 已納入受限制的儲存區"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"已傳送圖片"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"工作 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"測試"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"共用"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"監管"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"工作設定檔"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"私人空間"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"複製"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 21e9113..8ff587b 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"取消固定時必須畫出解鎖圖案"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"取消固定時必須輸入密碼"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"這是管理員安裝的套件。\n你可以前往設定查看授予的權限"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"管理員已更新套件。\n你可以前往設定查看授予的權限"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"已由你的管理員刪除"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"確定"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"省電模式會開啟深色主題,並限制或關閉背景活動、某些視覺效果、特定功能和部分網路連線。"</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"捲動"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"暫停"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"位置"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"向上捲動"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"向下捲動"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"向左捲動"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"向右捲動"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"退出捲動模式"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"捲動面板"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"已將「<xliff:g id="PACKAGE_NAME">%1$s</xliff:g>」移入受限制的值區"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"傳送了一張圖片"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"工作 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"測試"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"通用"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"監督中"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"工作資料夾"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"私人空間"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"複製"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 695f319..3fc910c 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -1965,8 +1965,7 @@
     <string name="lock_to_app_unlock_pattern" msgid="2694204070499712503">"Cela iphethini yokuvula ngaphambi kokususa ukuphina"</string>
     <string name="lock_to_app_unlock_password" msgid="9126722403506560473">"Cela iphasiwedi ngaphambi kokususa ukuphina"</string>
     <string name="package_installed_device_owner" msgid="8684974629306529138">"Kufakwe ngumphathi wakho.\nIya kumasethingi ukuze ubuke izimvume ezinikeziwe"</string>
-    <!-- no translation found for package_updated_device_owner (7770195449213776218) -->
-    <skip />
+    <string name="package_updated_device_owner" msgid="7770195449213776218">"Kubuyekezwe ngumphathi wakho.\nIya kumasethingi ukuze ubuke izimvume ezinikeziwe"</string>
     <string name="package_deleted_device_owner" msgid="2292335928930293023">"Kususwe umlawuli wakho"</string>
     <string name="confirm_battery_saver" msgid="5247976246208245754">"KULUNGILE"</string>
     <string name="battery_saver_description_with_learn_more" msgid="5444908404021316250">"Isilondolozi Sebhethri sivula ingqikithi emnyama futhi sibeke umkhawulo noma sivale umsebenzi ongemuva, imiphumela ethile yokubuka, izici ezithile, nokuxhumeka okuthile kwenethiwekhi."</string>
@@ -2274,18 +2273,12 @@
     <string name="accessibility_autoclick_scroll" msgid="3499385943728726933">"Skrola"</string>
     <string name="accessibility_autoclick_pause" msgid="3272200156172573568">"Misa"</string>
     <string name="accessibility_autoclick_position" msgid="2933660969907663545">"Indawo"</string>
-    <!-- no translation found for accessibility_autoclick_scroll_up (2044948780797117443) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_down (3733401063292018116) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_left (8564421367992824198) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_right (8932417330753984265) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_exit (3788610039146769696) -->
-    <skip />
-    <!-- no translation found for accessibility_autoclick_scroll_panel_title (7120598166296447036) -->
-    <skip />
+    <string name="accessibility_autoclick_scroll_up" msgid="2044948780797117443">"Skrolela Phezulu"</string>
+    <string name="accessibility_autoclick_scroll_down" msgid="3733401063292018116">"Skrolela Phansi"</string>
+    <string name="accessibility_autoclick_scroll_left" msgid="8564421367992824198">"Skrolela Ngakwesokunxele"</string>
+    <string name="accessibility_autoclick_scroll_right" msgid="8932417330753984265">"Skrolela Ngakwesokudla"</string>
+    <string name="accessibility_autoclick_scroll_exit" msgid="3788610039146769696">"Phuma Kumodi Yokuskrola"</string>
+    <string name="accessibility_autoclick_scroll_panel_title" msgid="7120598166296447036">"Iphaneli Yokuskrola"</string>
     <string name="as_app_forced_to_restricted_bucket" msgid="8233871289353898964">"I-<xliff:g id="PACKAGE_NAME">%1$s</xliff:g> ifakwe kubhakede LOKUKHAWULELWE"</string>
     <string name="conversation_single_line_name_display" msgid="8958948312915255999">"<xliff:g id="SENDER_NAME">%1$s</xliff:g>:"</string>
     <string name="conversation_single_line_image_placeholder" msgid="6983271082911936900">"uthumele isithombe"</string>
@@ -2493,8 +2486,7 @@
     <string name="profile_label_work_3" msgid="4834572253956798917">"Umsebenzi 3"</string>
     <string name="profile_label_test" msgid="9168641926186071947">"Hlola"</string>
     <string name="profile_label_communal" msgid="8743921499944800427">"Okomphakathi"</string>
-    <!-- no translation found for profile_label_supervising (5649312778545745371) -->
-    <skip />
+    <string name="profile_label_supervising" msgid="5649312778545745371">"Ukugada"</string>
     <string name="accessibility_label_managed_profile" msgid="3366526886209832641">"Iphrofayela yomsebenzi"</string>
     <string name="accessibility_label_private_profile" msgid="1436459319135548969">"Indawo engasese"</string>
     <string name="accessibility_label_clone_profile" msgid="7579118375042398784">"Yenza i-Clone"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index d2c993ae..647e3dc 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5573,6 +5573,14 @@
 
     <!-- @hide internal use only -->
     <declare-styleable name="NotificationProgressBar">
+        <!-- Minimum required drawing width for segments. The drawing width refers to the width
+             after the original segments have been adjusted for the neighboring Points and gaps.
+             This is enforced by stretching the segments that are too short. -->
+        <attr name="segMinWidth" format="dimension" />
+        <!-- The gap between two segments. -->
+        <attr name="segSegGap" format="dimension" />
+        <!-- The gap between a segment and a point. -->
+        <attr name="segPointGap" format="dimension" />
         <!-- Draws the tracker on a NotificationProgressBar. -->
         <attr name="tracker" format="reference" />
         <!-- Height of the tracker. -->
@@ -7580,25 +7588,9 @@
     <!-- NotificationProgressDrawable class -->
     <!-- ================================== -->
 
-    <!-- Drawable used to render a notification progress bar, with segments and points. -->
-    <!-- @hide internal use only -->
-    <declare-styleable name="NotificationProgressDrawable">
-        <!-- The gap between two segments. -->
-        <attr name="segSegGap" format="dimension" />
-        <!-- The gap between a segment and a point. -->
-        <attr name="segPointGap" format="dimension" />
-    </declare-styleable>
-
     <!-- Used to config the segments of a NotificationProgressDrawable. -->
     <!-- @hide internal use only -->
     <declare-styleable name="NotificationProgressDrawableSegments">
-        <!-- TODO: b/390196782 - maybe move this to NotificationProgressBar, because that's the only
-         place this is used actually. Same for NotificationProgressDrawable.segSegGap/segPointGap
-         above. -->
-        <!-- Minimum required drawing width. The drawing width refers to the width after
-         the original segments have been adjusted for the neighboring Points and gaps. This is
-         enforced by stretching the segments that are too short. -->
-        <attr name="minWidth" />
         <!-- Height of the solid segments. -->
         <attr name="height" />
         <!-- Height of the faded segments. -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 7a38dce..e47adc9 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2831,6 +2831,10 @@
     <!-- Whether dreams are disabled when ambient mode is suppressed. -->
     <bool name="config_dreamsDisabledByAmbientModeSuppressionConfig">false</bool>
 
+    <!-- The default for the setting that controls when to auto-start hub mode.
+          0 means "never" -->
+    <integer name="config_whenToStartHubModeDefault">0</integer>
+
     <!-- The duration in milliseconds of the dream opening animation.  -->
     <integer name="config_dreamOpenAnimationDuration">250</integer>
     <!-- The duration in milliseconds of the dream closing animation.  -->
@@ -6108,6 +6112,9 @@
     <!-- Whether to default to an expanded list of users on the lock screen user switcher. -->
     <bool name="config_expandLockScreenUserSwitcher">false</bool>
 
+    <!-- Help URI, action disabled by advanced protection [DO NOT TRANSLATE] -->
+    <string name="config_help_url_action_disabled_by_advanced_protection" translatable="false"></string>
+
     <!-- Toasts posted from these packages will be shown to the current user, regardless of the user
          the process belongs to. This is useful for packages that run under a single user but serve
          multiple users, e.g. the system.
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 6e54083..c0d2779 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -295,6 +295,11 @@
     <!-- The margin of the notification action list at the bottom in the 2025 redesign -->
     <dimen name="notification_2025_action_list_margin_bottom">6dp</dimen>
 
+    <!-- The minimum height of the notification action container, to act as a bottom padding for the
+         notification when there are no actions. This should always be equal to
+         notification_2025_margin - notification_2025_action_list_margin_bottom. -->
+    <dimen name="notification_2025_action_list_min_height">10dp</dimen>
+
     <!-- The overall height of the emphasized notification action -->
     <dimen name="notification_action_emphasized_height">48dp</dimen>
 
@@ -333,9 +338,9 @@
 
     <!-- The spacing between the content and the header text above it, scaling with text size.
          This value is chosen so that, taking into account the text spacing for both the text in the
-         top line and the text in the content, the distance between them is 4dp with the default
+         top line and the text in the content, the distance between them is ~2dp with the default
          screen configuration (and will grow accordingly for larger font sizes) -->
-    <dimen name="notification_2025_content_margin_top">10sp</dimen>
+    <dimen name="notification_2025_content_margin_top">8sp</dimen>
 
     <!-- height of the content margin that is applied at the end of the notification content -->
     <dimen name="notification_content_margin">20dp</dimen>
@@ -445,6 +450,8 @@
     <!-- the size of the notification close button -->
     <dimen name="notification_close_button_size">16dp</dimen>
 
+    <dimen name="notification_close_button_padding">2dp</dimen>
+
     <!-- Margin for all notification content -->
     <dimen name="notification_2025_margin">16dp</dimen>
 
@@ -516,6 +523,9 @@
     <!-- The spacing between messages in Notification.MessagingStyle -->
     <dimen name="notification_messaging_spacing">6dp</dimen>
 
+    <!-- The spacing between messages in Notification.MessagingStyle (2025 redesign version) -->
+    <dimen name="notification_2025_messaging_spacing">14dp</dimen>
+
     <!-- The spacing between messages in Notification.MessagingStyle -->
     <dimen name="notification_messaging_spacing_conversation_group">24dp</dimen>
 
diff --git a/core/res/res/values/dimens_watch.xml b/core/res/res/values/dimens_watch.xml
index 7462b73..a8ed666 100644
--- a/core/res/res/values/dimens_watch.xml
+++ b/core/res/res/values/dimens_watch.xml
@@ -61,4 +61,8 @@
     <dimen name="disabled_alpha_wear_material3">0.12</dimen>
     <!-- Alpha transparency applied to elements which are considered primary (e.g. primary text) -->
     <dimen name="primary_content_alpha_wear_material3">0.38</dimen>
+
+    <!--  watch's indeterminate progress bar dimens -->
+    <dimen name="loader_horizontal_min_width_watch">76dp</dimen>
+    <dimen name="loader_horizontal_min_height_watch">14dp</dimen>
 </resources>
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 73681d2..8f13ee1 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -503,6 +503,9 @@
     <style name="Widget.Material.Notification.ProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal" />
 
     <style name="Widget.Material.Notification.NotificationProgressBar" parent="Widget.Material.Light.ProgressBar.Horizontal">
+        <item name="segMinWidth">@dimen/notification_progress_segments_min_width</item>
+        <item name="segSegGap">@dimen/notification_progress_segSeg_gap</item>
+        <item name="segPointGap">@dimen/notification_progress_segPoint_gap</item>
         <item name="progressDrawable">@drawable/notification_progress</item>
         <item name="trackerHeight">@dimen/notification_progress_tracker_height</item>
     </style>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 922d59d..a37ca28 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2072,6 +2072,7 @@
   <java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" />
   <java-symbol type="bool" name="config_keepDreamingWhenUnplugging" />
   <java-symbol type="bool" name="config_glanceableHubEnabled" />
+  <java-symbol type="integer" name="config_whenToStartHubModeDefault" />
   <java-symbol type="integer" name="config_keyguardDrawnTimeout" />
   <java-symbol type="bool" name="config_goToSleepOnButtonPressTheaterMode" />
   <java-symbol type="bool" name="config_supportLongPressPowerWhenNonInteractive" />
@@ -3243,6 +3244,7 @@
   <java-symbol type="id" name="expand_button_pill_colorized_layer" />
   <java-symbol type="id" name="expand_button_number" />
   <java-symbol type="id" name="expand_button_icon" />
+  <java-symbol type="id" name="close_button_pill_colorized_layer" />
   <java-symbol type="id" name="alternate_expand_target" />
   <java-symbol type="id" name="notification_header" />
   <java-symbol type="id" name="notification_top_line" />
@@ -5963,6 +5965,8 @@
   <!-- Device CMF Theming Settings -->
   <java-symbol type="array" name="theming_defaults" />
 
+  <java-symbol type="string" name="config_help_url_action_disabled_by_advanced_protection" />
+
   <!-- Advanced Protection Service USB feature -->
   <java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_title" />
   <java-symbol type="string" name="usb_apm_usb_plugged_in_when_locked_notification_text" />
diff --git a/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java b/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java
index e8b295b..0287e6c 100644
--- a/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/BrailleDisplayControllerImplTest.java
@@ -22,7 +22,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.hardware.usb.UsbDevice;
 import android.platform.test.annotations.RequiresFlagsEnabled;
@@ -118,6 +118,6 @@
 
         verify(mBrailleDisplayCallback).onConnectionFailed(
                 BrailleDisplayController.BrailleDisplayCallback.FLAG_ERROR_CANNOT_ACCESS);
-        verifyZeroInteractions(mAccessibilityServiceConnection);
+        verifyNoMoreInteractions(mAccessibilityServiceConnection);
     }
 }
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java b/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java
index 6d86bd2..746ba96 100644
--- a/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java
@@ -38,6 +38,7 @@
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
 
 
 @MediumTest
@@ -490,9 +491,24 @@
 
     @Test
     public void testCancelOnPendingEndListener() throws Throwable {
+        testPendingEndListener(AnimatorSet::cancel);
+    }
+
+    @Test
+    public void testEndOnPendingEndListener() throws Throwable {
+        testPendingEndListener(animatorSet -> {
+            // This verifies that isRunning() and isStarted() are true at last frame.
+            // Then the end() should invoke the end callback immediately.
+            if (animatorSet.isRunning() && animatorSet.isStarted()) {
+                animatorSet.end();
+            }
+        });
+    }
+
+    private void testPendingEndListener(Consumer<AnimatorSet> finishOnLastFrame) throws Throwable {
         final CountDownLatch endLatch = new CountDownLatch(1);
         final Handler handler = new Handler(Looper.getMainLooper());
-        final boolean[] endCalledRightAfterCancel = new boolean[2];
+        final boolean[] endCalledImmediately = new boolean[2];
         final AnimatorSet set = new AnimatorSet();
         final ValueAnimatorTests.MyListener asListener = new ValueAnimatorTests.MyListener();
         final ValueAnimatorTests.MyListener vaListener = new ValueAnimatorTests.MyListener();
@@ -502,9 +518,9 @@
         va.addUpdateListener(animation -> {
             if (animation.getAnimatedFraction() == 1f) {
                 handler.post(() -> {
-                    set.cancel();
-                    endCalledRightAfterCancel[0] = vaListener.endCalled;
-                    endCalledRightAfterCancel[1] = asListener.endCalled;
+                    finishOnLastFrame.accept(set);
+                    endCalledImmediately[0] = vaListener.endCalled;
+                    endCalledImmediately[1] = asListener.endCalled;
                     endLatch.countDown();
                 });
             }
@@ -517,8 +533,8 @@
         try {
             handler.post(set::start);
             assertTrue(endLatch.await(1, TimeUnit.SECONDS));
-            assertTrue(endCalledRightAfterCancel[0]);
-            assertTrue(endCalledRightAfterCancel[1]);
+            assertTrue(endCalledImmediately[0]);
+            assertTrue(endCalledImmediately[1]);
         } finally {
             ValueAnimator.setPostNotifyEndListenerEnabled(false);
         }
diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
index a55909f..89664ff 100644
--- a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
+++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
@@ -44,6 +44,7 @@
 import java.util.ArrayList;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
+import java.util.function.Consumer;
 
 @RunWith(AndroidJUnit4.class)
 @MediumTest
@@ -923,9 +924,25 @@
 
     @Test
     public void testCancelOnPendingEndListener() throws Throwable {
+        testPendingEndListener(ValueAnimator::cancel);
+    }
+
+    @Test
+    public void testEndOnPendingEndListener() throws Throwable {
+        testPendingEndListener(animator -> {
+            // This verifies that isRunning() and isStarted() are true at last frame.
+            // Then the end() should invoke the end callback immediately.
+            if (animator.isRunning() && animator.isStarted()) {
+                animator.end();
+            }
+        });
+    }
+
+    private void testPendingEndListener(Consumer<ValueAnimator> finishOnLastFrame)
+            throws Throwable {
+        final boolean[] endCalledImmediately = new boolean[1];
         final CountDownLatch endLatch = new CountDownLatch(1);
         final Handler handler = new Handler(Looper.getMainLooper());
-        final boolean[] endCalledRightAfterCancel = new boolean[1];
         final MyListener listener = new MyListener();
         final ValueAnimator va = new ValueAnimator();
         va.setFloatValues(0f, 1f);
@@ -933,8 +950,8 @@
         va.addUpdateListener(animation -> {
             if (animation.getAnimatedFraction() == 1f) {
                 handler.post(() -> {
-                    va.cancel();
-                    endCalledRightAfterCancel[0] = listener.endCalled;
+                    finishOnLastFrame.accept(va);
+                    endCalledImmediately[0] = listener.endCalled;
                     endLatch.countDown();
                 });
             }
@@ -945,7 +962,7 @@
         try {
             handler.post(va::start);
             assertThat(endLatch.await(1, TimeUnit.SECONDS)).isTrue();
-            assertThat(endCalledRightAfterCancel[0]).isTrue();
+            assertThat(endCalledImmediately[0]).isTrue();
         } finally {
             ValueAnimator.setPostNotifyEndListenerEnabled(false);
         }
diff --git a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
index 62d89f6..146b386 100644
--- a/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
+++ b/core/tests/coretests/src/android/app/ApplicationPackageManagerTest.java
@@ -16,19 +16,37 @@
 
 package android.app;
 
+import static android.content.Intent.ACTION_MAIN;
+import static android.content.Intent.CATEGORY_INFO;
+import static android.content.Intent.CATEGORY_LAUNCHER;
+import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
 import static android.os.storage.VolumeInfo.STATE_MOUNTED;
 import static android.os.storage.VolumeInfo.STATE_UNMOUNTED;
 
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.argThat;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
+import android.content.ComponentName;
 import android.content.Context;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageManager;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager.ResolveInfoFlags;
+import android.content.pm.ResolveInfo;
 import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.content.res.XmlResourceParser;
@@ -44,6 +62,7 @@
 
 import junit.framework.TestCase;
 
+import org.mockito.ArgumentMatcher;
 import org.mockito.Mockito;
 import org.xmlpull.v1.XmlPullParser;
 
@@ -102,14 +121,14 @@
         sVolumes.add(sPrivateUnmountedVol);
     }
 
-    private static final class MockedApplicationPackageManager extends ApplicationPackageManager {
+    public static class MockedApplicationPackageManager extends ApplicationPackageManager {
         private boolean mForceAllowOnExternal = false;
         private boolean mAllow3rdPartyOnInternal = true;
         private HashMap<ApplicationInfo, Resources> mResourcesMap;
 
         public MockedApplicationPackageManager() {
             super(null, null);
-            mResourcesMap = new HashMap<ApplicationInfo, Resources>();
+            mResourcesMap = new HashMap<>();
         }
 
         public void setForceAllowOnExternal(boolean forceAllowOnExternal) {
@@ -153,7 +172,7 @@
     }
 
     private StorageManager getMockedStorageManager() {
-        StorageManager storageManager = Mockito.mock(StorageManager.class);
+        StorageManager storageManager = mock(StorageManager.class);
         Mockito.when(storageManager.getVolumes()).thenReturn(sVolumes);
         Mockito.when(storageManager.findVolumeById(VolumeInfo.ID_PRIVATE_INTERNAL))
                 .thenReturn(sInternalVol);
@@ -190,7 +209,7 @@
         sysAppInfo.flags = ApplicationInfo.FLAG_SYSTEM;
 
         StorageManager storageManager = getMockedStorageManager();
-        IPackageManager pm = Mockito.mock(IPackageManager.class);
+        IPackageManager pm = mock(IPackageManager.class);
 
         MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
 
@@ -220,7 +239,7 @@
         ApplicationInfo appInfo = new ApplicationInfo();
         StorageManager storageManager = getMockedStorageManager();
 
-        IPackageManager pm = Mockito.mock(IPackageManager.class);
+        IPackageManager pm = mock(IPackageManager.class);
         Mockito.when(pm.isPackageDeviceAdminOnAnyUser(Mockito.anyString())).thenReturn(false);
 
         MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
@@ -249,7 +268,7 @@
         ApplicationInfo appInfo = new ApplicationInfo();
         StorageManager storageManager = getMockedStorageManager();
 
-        IPackageManager pm = Mockito.mock(IPackageManager.class);
+        IPackageManager pm = mock(IPackageManager.class);
 
         MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
         appPkgMgr.setForceAllowOnExternal(true);
@@ -291,15 +310,15 @@
 
     public void testExtractPackageItemInfoAttributes_noMetaData() {
         final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
-        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
+        final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class);
         assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
                 new int[]{})).isNull();
     }
 
     public void testExtractPackageItemInfoAttributes_noParser() {
         final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
-        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
-        final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+        final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class);
+        final ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
         when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
         assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
                 new int[]{})).isNull();
@@ -307,8 +326,8 @@
 
     public void testExtractPackageItemInfoAttributes_noMetaDataXml() {
         final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
-        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
-        final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
+        final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class);
+        final ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
         when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
         when(packageItemInfo.loadXmlMetaData(any(), any())).thenReturn(null);
         assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, null,
@@ -318,9 +337,9 @@
     public void testExtractPackageItemInfoAttributes_nonMatchingRootTag() throws Exception {
         final String rootTag = "rootTag";
         final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
-        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
-        final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
-        final XmlResourceParser parser = Mockito.mock(XmlResourceParser.class);
+        final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class);
+        final ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
+        final XmlResourceParser parser = mock(XmlResourceParser.class);
 
         when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
         packageItemInfo.metaData = new Bundle();
@@ -334,11 +353,11 @@
     public void testExtractPackageItemInfoAttributes_successfulExtraction() throws Exception {
         final String rootTag = "rootTag";
         final MockedApplicationPackageManager appPkgMgr = new MockedApplicationPackageManager();
-        final PackageItemInfo packageItemInfo = Mockito.mock(PackageItemInfo.class);
-        final ApplicationInfo applicationInfo = Mockito.mock(ApplicationInfo.class);
-        final XmlResourceParser parser = Mockito.mock(XmlResourceParser.class);
-        final Resources resources = Mockito.mock(Resources.class);
-        final TypedArray attributes = Mockito.mock(TypedArray.class);
+        final PackageItemInfo packageItemInfo = mock(PackageItemInfo.class);
+        final ApplicationInfo applicationInfo = mock(ApplicationInfo.class);
+        final XmlResourceParser parser = mock(XmlResourceParser.class);
+        final Resources resources = mock(Resources.class);
+        final TypedArray attributes = mock(TypedArray.class);
 
         when(packageItemInfo.getApplicationInfo()).thenReturn(applicationInfo);
         packageItemInfo.metaData = new Bundle();
@@ -351,4 +370,123 @@
         assertThat(appPkgMgr.extractPackageItemInfoAttributes(packageItemInfo, null, rootTag,
                 new int[]{})).isEqualTo(attributes);
     }
+
+    public void testGetLaunchIntentForPackage_categoryInfoActivity_returnsIt() throws Exception {
+        String pkg = "com.some.package";
+        int userId = 42;
+        ResolveInfo categoryInfoResolveInfo = new ResolveInfo();
+        categoryInfoResolveInfo.activityInfo = new ActivityInfo();
+        categoryInfoResolveInfo.activityInfo.packageName = pkg;
+        categoryInfoResolveInfo.activityInfo.name = "activity";
+        Intent baseIntent = new Intent(ACTION_MAIN).setPackage(pkg);
+
+        final MockedApplicationPackageManager pm = spy(new MockedApplicationPackageManager());
+        doReturn(userId).when(pm).getUserId();
+        doReturn(List.of(categoryInfoResolveInfo))
+                .when(pm).queryIntentActivitiesAsUser(
+                        eqIntent(new Intent(baseIntent).addCategory(CATEGORY_INFO)),
+                        any(ResolveInfoFlags.class),
+                        anyInt());
+        doReturn(
+                List.of())
+                .when(pm).queryIntentActivitiesAsUser(
+                        eqIntent(new Intent(baseIntent).addCategory(CATEGORY_LAUNCHER)),
+                        any(ResolveInfoFlags.class),
+                        anyInt());
+
+        Intent intent = pm.getLaunchIntentForPackage(pkg, true);
+
+        assertThat(intent).isNotNull();
+        assertThat(intent.getComponent()).isEqualTo(new ComponentName(pkg, "activity"));
+        assertThat(intent.getCategories()).containsExactly(CATEGORY_INFO);
+        assertThat(intent.getFlags()).isEqualTo(FLAG_ACTIVITY_NEW_TASK);
+        verify(pm).queryIntentActivitiesAsUser(
+                eqIntent(new Intent(ACTION_MAIN).addCategory(CATEGORY_INFO).setPackage(pkg)),
+                eqResolveInfoFlags(MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE),
+                eq(userId));
+    }
+
+    public void testGetLaunchIntentForPackage_categoryLauncherActivity_returnsIt() {
+        String pkg = "com.some.package";
+        int userId = 42;
+        ResolveInfo categoryLauncherResolveInfo1 = new ResolveInfo();
+        categoryLauncherResolveInfo1.activityInfo = new ActivityInfo();
+        categoryLauncherResolveInfo1.activityInfo.packageName = pkg;
+        categoryLauncherResolveInfo1.activityInfo.name = "activity1";
+        ResolveInfo categoryLauncherResolveInfo2 = new ResolveInfo();
+        categoryLauncherResolveInfo2.activityInfo = new ActivityInfo();
+        categoryLauncherResolveInfo2.activityInfo.packageName = pkg;
+        categoryLauncherResolveInfo2.activityInfo.name = "activity2";
+        Intent baseIntent = new Intent(ACTION_MAIN).setPackage(pkg);
+
+        final MockedApplicationPackageManager pm = spy(new MockedApplicationPackageManager());
+        doReturn(userId).when(pm).getUserId();
+        doReturn(List.of())
+                .when(pm).queryIntentActivitiesAsUser(
+                        eqIntent(new Intent(baseIntent).addCategory(CATEGORY_INFO)),
+                        any(ResolveInfoFlags.class),
+                        anyInt());
+        doReturn(
+                List.of(categoryLauncherResolveInfo1, categoryLauncherResolveInfo2))
+                .when(pm).queryIntentActivitiesAsUser(
+                        eqIntent(new Intent(baseIntent).addCategory(CATEGORY_LAUNCHER)),
+                        any(ResolveInfoFlags.class),
+                        anyInt());
+
+        Intent intent = pm.getLaunchIntentForPackage(pkg, true);
+
+        assertThat(intent).isNotNull();
+        assertThat(intent.getComponent()).isEqualTo(new ComponentName(pkg, "activity1"));
+        assertThat(intent.getCategories()).containsExactly(CATEGORY_LAUNCHER);
+        assertThat(intent.getFlags()).isEqualTo(FLAG_ACTIVITY_NEW_TASK);
+    }
+
+    public void testGetLaunchIntentForPackage_noSuitableActivity_returnsNull() throws Exception {
+        String pkg = "com.some.package";
+        int userId = 42;
+
+        final MockedApplicationPackageManager pm = spy(new MockedApplicationPackageManager());
+        doReturn(userId).when(pm).getUserId();
+        doReturn(List.of())
+                .when(pm).queryIntentActivitiesAsUser(
+                        any(),
+                        any(ResolveInfoFlags.class),
+                        anyInt());
+
+        Intent intent = pm.getLaunchIntentForPackage(pkg, true);
+
+        assertThat(intent).isNull();
+    }
+
+    /** Equality check for intents -- ignoring extras */
+    private static Intent eqIntent(Intent wanted) {
+        return argThat(
+                new ArgumentMatcher<>() {
+                    @Override
+                    public boolean matches(Intent argument) {
+                        return wanted.filterEquals(argument)
+                                && wanted.getFlags() == argument.getFlags();
+                    }
+
+                    @Override
+                    public String toString() {
+                        return wanted.toString();
+                    }
+                });
+    }
+
+    private static ResolveInfoFlags eqResolveInfoFlags(long flagsWanted) {
+        return argThat(
+                new ArgumentMatcher<>() {
+                    @Override
+                    public boolean matches(ResolveInfoFlags argument) {
+                        return argument.getValue() == flagsWanted;
+                    }
+
+                    @Override
+                    public String toString() {
+                        return String.valueOf(flagsWanted);
+                    }
+                });
+    }
 }
diff --git a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
index f75a72d..21ab8fc 100644
--- a/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
+++ b/core/tests/coretests/src/android/app/PropertyInvalidatedCacheTests.java
@@ -41,7 +41,6 @@
 import com.android.internal.os.ApplicationSharedMemory;
 
 import android.platform.test.annotations.DisabledOnRavenwood;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
diff --git a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
index dccbf40..70b4150 100644
--- a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheTest.java
@@ -233,7 +233,7 @@
     /**
      * Mock implementation of {@link android.content.pm.RegisteredServicesCache} for testing
      */
-    private class TestServicesCache extends RegisteredServicesCache<TestServiceType> {
+    public class TestServicesCache extends RegisteredServicesCache<TestServiceType> {
         static final String SERVICE_INTERFACE = "RegisteredServicesCacheTest";
         static final String SERVICE_META_DATA = "RegisteredServicesCacheTest";
         static final String ATTRIBUTES_NAME = "test";
@@ -245,12 +245,6 @@
                     SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME, new TestSerializer());
         }
 
-        TestServicesCache(Injector<TestServiceType> injector,
-                XmlSerializerAndParser<TestServiceType> serializerAndParser) {
-            super(injector, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME,
-                    serializerAndParser);
-        }
-
         @Override
         public TestServiceType parseServiceAttributes(Resources res, String packageName,
                 AttributeSet attrs) {
@@ -338,7 +332,7 @@
         }
     }
 
-    static class TestSerializer implements XmlSerializerAndParser<TestServiceType> {
+    public static class TestSerializer implements XmlSerializerAndParser<TestServiceType> {
 
         public void writeAsXml(TestServiceType item, TypedXmlSerializer out) throws IOException {
             out.attribute(null, "type", item.type);
@@ -353,7 +347,7 @@
         }
     }
 
-    static class TestServiceType implements Parcelable {
+    public static class TestServiceType implements Parcelable {
         final String type;
         final String value;
 
diff --git a/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheUnitTest.java b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheUnitTest.java
new file mode 100644
index 0000000..8349659
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/RegisteredServicesCacheUnitTest.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content.pm;
+
+import static android.content.pm.Flags.FLAG_OPTIMIZE_PARSING_IN_REGISTERED_SERVICES_CACHE;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.RegisteredServicesCacheTest.TestServiceType;
+import android.content.res.Resources;
+import android.os.Handler;
+import android.os.Message;
+import android.os.UserHandle;
+import android.platform.test.annotations.Presubmit;
+import android.platform.test.annotations.RequiresFlagsEnabled;
+import android.platform.test.flag.junit.CheckFlagsRule;
+import android.platform.test.flag.junit.DeviceFlagsValueProvider;
+import android.util.AttributeSet;
+import android.util.SparseArray;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import com.android.internal.os.BackgroundThread;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Unit tests for {@link android.content.pm.RegisteredServicesCache}
+ */
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+@RequiresFlagsEnabled(FLAG_OPTIMIZE_PARSING_IN_REGISTERED_SERVICES_CACHE)
+public class RegisteredServicesCacheUnitTest {
+    private static final String TAG = "RegisteredServicesCacheUnitTest";
+    private static final int U0 = 0;
+    private static final int U1 = 1;
+    private static final int UID1 = 1;
+
+    @Rule
+    public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
+
+    private final ResolveInfo mResolveInfo1 = new ResolveInfo();
+    private final ResolveInfo mResolveInfo2 = new ResolveInfo();
+    private final TestServiceType mTestServiceType1 = new TestServiceType("t1", "value1");
+    private final TestServiceType mTestServiceType2 = new TestServiceType("t2", "value2");
+    @Mock
+    RegisteredServicesCache.Injector<TestServiceType> mMockInjector;
+    @Mock
+    Context mMockContext;
+    Handler mMockBackgroundHandler;
+    @Mock
+    PackageManager mMockPackageManager;
+
+    @Before
+    public void setup() throws Exception {
+        MockitoAnnotations.initMocks(this);
+
+        when(mMockInjector.getContext()).thenReturn(mMockContext);
+        mMockBackgroundHandler = spy(BackgroundThread.getHandler());
+        when(mMockInjector.getBackgroundHandler()).thenReturn(mMockBackgroundHandler);
+        doReturn(mock(Intent.class)).when(mMockContext).registerReceiverAsUser(any(), any(), any(),
+                any(), any());
+        doReturn(mock(Intent.class)).when(mMockContext).registerReceiver(any(), any(), any(),
+                any());
+        when(mMockContext.getPackageManager()).thenReturn(mMockPackageManager);
+
+        addServiceInfoIntoResolveInfo(mResolveInfo1, "r1.package.name" /* packageName */,
+                "r1.service.name" /* serviceName */);
+        addServiceInfoIntoResolveInfo(mResolveInfo2, "r2.package.name" /* packageName */,
+                "r2.service.name" /* serviceName */);
+    }
+
+    @Test
+    public void testSaveServiceInfoIntoCaches() throws Exception {
+        PackageInfo packageInfo1 = createPackageInfo(1000L /* lastUpdateTime */);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo1.serviceInfo.packageName),
+                anyInt(), eq(U0))).thenReturn(packageInfo1);
+        PackageInfo packageInfo2 = createPackageInfo(2000L /* lastUpdateTime */);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo2.serviceInfo.packageName),
+                anyInt(), eq(U1))).thenReturn(packageInfo2);
+
+        TestRegisteredServicesCache testServicesCache = spy(
+                new TestRegisteredServicesCache(mMockInjector, null /* serializerAndParser */));
+        final RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo1 = newServiceInfo(
+                mTestServiceType1, UID1, mResolveInfo1.serviceInfo.getComponentName(),
+                1000L /* lastUpdateTime */);
+        testServicesCache.addServiceForQuerying(U0, mResolveInfo1, serviceInfo1);
+
+        int u1uid = UserHandle.getUid(U1, UID1);
+        final RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo2 = newServiceInfo(
+                mTestServiceType2, u1uid, mResolveInfo2.serviceInfo.getComponentName(),
+                2000L /* lastUpdateTime */);
+        testServicesCache.addServiceForQuerying(U1, mResolveInfo2, serviceInfo2);
+
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+        testServicesCache.getAllServices(U1);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo2), eq(2000L));
+
+        reset(testServicesCache);
+
+        testServicesCache.invalidateCache(U0);
+        testServicesCache.invalidateCache(U1);
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, never()).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+        testServicesCache.getAllServices(U1);
+        verify(testServicesCache, never()).parseServiceInfo(eq(mResolveInfo2), eq(2000L));
+    }
+
+    @Test
+    public void testClearServiceInfoCachesAfterRemoveUserId() throws Exception {
+        PackageInfo packageInfo1 = createPackageInfo(1000L /* lastUpdateTime */);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo1.serviceInfo.packageName),
+                anyInt(), eq(U0))).thenReturn(packageInfo1);
+
+        TestRegisteredServicesCache testServicesCache = spy(
+                new TestRegisteredServicesCache(mMockInjector, null /* serializerAndParser */));
+        final RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo1 = newServiceInfo(
+                mTestServiceType1, UID1, mResolveInfo1.serviceInfo.getComponentName(),
+                1000L /* lastUpdateTime */);
+        testServicesCache.addServiceForQuerying(U0, mResolveInfo1, serviceInfo1);
+
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+
+        reset(testServicesCache);
+
+        testServicesCache.onUserRemoved(U0);
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+    }
+
+    @Test
+    public void testGetServiceInfoCachesForMultiUser() throws Exception {
+        PackageInfo packageInfo1 = createPackageInfo(1000L /* lastUpdateTime */);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo1.serviceInfo.packageName),
+                anyInt(), eq(U0))).thenReturn(packageInfo1);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo1.serviceInfo.packageName),
+                anyInt(), eq(U1))).thenReturn(packageInfo1);
+
+        TestRegisteredServicesCache testServicesCache = spy(
+                new TestRegisteredServicesCache(mMockInjector, null /* serializerAndParser */));
+        final RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo1 = newServiceInfo(
+                mTestServiceType1, UID1, mResolveInfo1.serviceInfo.getComponentName(),
+                1000L /* lastUpdateTime */);
+        testServicesCache.addServiceForQuerying(U0, mResolveInfo1, serviceInfo1);
+
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+
+        reset(testServicesCache);
+
+        testServicesCache.clearServicesForQuerying();
+        int u1uid = UserHandle.getUid(U1, UID1);
+        assertThat(u1uid).isNotEqualTo(UID1);
+
+        final RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo2 = newServiceInfo(
+                mTestServiceType1, u1uid, mResolveInfo1.serviceInfo.getComponentName(),
+                1000L /* lastUpdateTime */);
+        testServicesCache.addServiceForQuerying(U1, mResolveInfo1, serviceInfo2);
+
+        testServicesCache.getAllServices(U1);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+
+        reset(testServicesCache);
+
+        testServicesCache.invalidateCache(U0);
+        testServicesCache.invalidateCache(U1);
+
+        // There is a bug to return the same info from the cache for different users. Make sure it
+        // will return the different info from the cache for different users.
+        Collection<RegisteredServicesCache.ServiceInfo<TestServiceType>> serviceInfos;
+        serviceInfos = testServicesCache.getAllServices(U0);
+        // Make sure the service info is retrieved from the cache for U0.
+        verify(testServicesCache, never()).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+        for (RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo : serviceInfos) {
+            assertThat(serviceInfo.componentInfo.applicationInfo.uid).isEqualTo(UID1);
+        }
+
+        serviceInfos = testServicesCache.getAllServices(U1);
+        // Make sure the service info is retrieved from the cache for U1.
+        verify(testServicesCache, never()).parseServiceInfo(eq(mResolveInfo2), eq(2000L));
+        for (RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo : serviceInfos) {
+            assertThat(serviceInfo.componentInfo.applicationInfo.uid).isEqualTo(u1uid);
+        }
+    }
+
+    @Test
+    public void testUpdateServiceInfoIntoCachesWhenPackageInfoNotFound() throws Exception {
+        PackageInfo packageInfo1 = createPackageInfo(1000L /* lastUpdateTime */);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo1.serviceInfo.packageName),
+                anyInt(), eq(U0))).thenReturn(packageInfo1);
+
+        TestRegisteredServicesCache testServicesCache = spy(
+                new TestRegisteredServicesCache(mMockInjector, null /* serializerAndParser */));
+        final RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo1 = newServiceInfo(
+                mTestServiceType1, UID1, mResolveInfo1.serviceInfo.getComponentName(),
+                1000L /* lastUpdateTime */);
+        testServicesCache.addServiceForQuerying(U0, mResolveInfo1, serviceInfo1);
+
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+
+        reset(testServicesCache);
+        reset(mMockPackageManager);
+
+        doThrow(new SecurityException("")).when(mMockPackageManager).getPackageInfoAsUser(
+                eq(mResolveInfo1.serviceInfo.packageName), anyInt(), eq(U0));
+
+        testServicesCache.invalidateCache(U0);
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), anyLong());
+    }
+
+    @Test
+    public void testUpdateServiceInfoIntoCachesWhenTheApplicationHasBeenUpdated() throws Exception {
+        PackageInfo packageInfo1 = createPackageInfo(1000L /* lastUpdateTime */);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo1.serviceInfo.packageName),
+                anyInt(), eq(U0))).thenReturn(packageInfo1);
+
+        TestRegisteredServicesCache testServicesCache = spy(
+                new TestRegisteredServicesCache(mMockInjector, null /* serializerAndParser */));
+        final RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo1 = newServiceInfo(
+                mTestServiceType1, UID1, mResolveInfo1.serviceInfo.getComponentName(),
+                1000L /* lastUpdateTime */);
+        testServicesCache.addServiceForQuerying(U0, mResolveInfo1, serviceInfo1);
+
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+
+        reset(testServicesCache);
+        reset(mMockPackageManager);
+
+        PackageInfo packageInfo2 = createPackageInfo(2000L /* lastUpdateTime */);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo1.serviceInfo.packageName),
+                anyInt(), eq(U0))).thenReturn(packageInfo2);
+
+        testServicesCache.invalidateCache(U0);
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(2000L));
+    }
+
+    @Test
+    public void testClearServiceInfoCachesAfterTimeout() throws Exception {
+        PackageInfo packageInfo1 = createPackageInfo(1000L /* lastUpdateTime */);
+        when(mMockPackageManager.getPackageInfoAsUser(eq(mResolveInfo1.serviceInfo.packageName),
+                anyInt(), eq(U0))).thenReturn(packageInfo1);
+
+        TestRegisteredServicesCache testServicesCache = spy(
+                new TestRegisteredServicesCache(mMockInjector, null /* serializerAndParser */));
+        final RegisteredServicesCache.ServiceInfo<TestServiceType> serviceInfo1 = newServiceInfo(
+                mTestServiceType1, UID1, mResolveInfo1.serviceInfo.getComponentName(),
+                1000L /* lastUpdateTime */);
+        testServicesCache.addServiceForQuerying(U0, mResolveInfo1, serviceInfo1);
+
+        // Immediately invoke run on the Runnable posted to the handler
+        doAnswer(invocation -> {
+            Message message = invocation.getArgument(0);
+            message.getCallback().run();
+            return true;
+        }).when(mMockBackgroundHandler).sendMessageAtTime(any(Message.class), anyLong());
+
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+        verify(mMockBackgroundHandler, times(1)).sendMessageAtTime(any(Message.class), anyLong());
+
+        reset(testServicesCache);
+
+        testServicesCache.invalidateCache(U0);
+        testServicesCache.getAllServices(U0);
+        verify(testServicesCache, times(1)).parseServiceInfo(eq(mResolveInfo1), eq(1000L));
+    }
+
+    private static RegisteredServicesCache.ServiceInfo<TestServiceType> newServiceInfo(
+            TestServiceType type, int uid, ComponentName componentName, long lastUpdateTime) {
+        final ComponentInfo info = new ComponentInfo();
+        info.applicationInfo = new ApplicationInfo();
+        info.applicationInfo.uid = uid;
+        return new RegisteredServicesCache.ServiceInfo<>(type, info, componentName, lastUpdateTime);
+    }
+
+    private void addServiceInfoIntoResolveInfo(ResolveInfo resolveInfo, String packageName,
+            String serviceName) {
+        final ServiceInfo serviceInfo = new ServiceInfo();
+        serviceInfo.packageName = packageName;
+        serviceInfo.name = serviceName;
+        resolveInfo.serviceInfo = serviceInfo;
+    }
+
+    private PackageInfo createPackageInfo(long lastUpdateTime) {
+        PackageInfo packageInfo = new PackageInfo();
+        packageInfo.lastUpdateTime = lastUpdateTime;
+        return packageInfo;
+    }
+
+    /**
+     * Mock implementation of {@link android.content.pm.RegisteredServicesCache} for testing
+     */
+    public class TestRegisteredServicesCache extends RegisteredServicesCache<TestServiceType> {
+        static final String SERVICE_INTERFACE = "RegisteredServicesCacheUnitTest";
+        static final String SERVICE_META_DATA = "RegisteredServicesCacheUnitTest";
+        static final String ATTRIBUTES_NAME = "test";
+        private SparseArray<Map<ResolveInfo, ServiceInfo<TestServiceType>>> mServices =
+                new SparseArray<>();
+
+        public TestRegisteredServicesCache(Injector<TestServiceType> injector,
+                XmlSerializerAndParser<TestServiceType> serializerAndParser) {
+            super(injector, SERVICE_INTERFACE, SERVICE_META_DATA, ATTRIBUTES_NAME,
+                    serializerAndParser);
+        }
+
+        @Override
+        public TestServiceType parseServiceAttributes(Resources res, String packageName,
+                AttributeSet attrs) {
+            return null;
+        }
+
+        @Override
+        protected List<ResolveInfo> queryIntentServices(int userId) {
+            Map<ResolveInfo, ServiceInfo<TestServiceType>> map = mServices.get(userId,
+                    new HashMap<ResolveInfo, ServiceInfo<TestServiceType>>());
+            return new ArrayList<>(map.keySet());
+        }
+
+        void addServiceForQuerying(int userId, ResolveInfo resolveInfo,
+                ServiceInfo<TestServiceType> serviceInfo) {
+            Map<ResolveInfo, ServiceInfo<TestServiceType>> map = mServices.get(userId);
+            if (map == null) {
+                map = new HashMap<>();
+                mServices.put(userId, map);
+            }
+            map.put(resolveInfo, serviceInfo);
+        }
+
+        void clearServicesForQuerying() {
+            mServices.clear();
+        }
+
+        @Override
+        protected ServiceInfo<TestServiceType> parseServiceInfo(ResolveInfo resolveInfo,
+                long lastUpdateTime) throws XmlPullParserException, IOException {
+            int size = mServices.size();
+            for (int i = 0; i < size; i++) {
+                Map<ResolveInfo, ServiceInfo<TestServiceType>> map = mServices.valueAt(i);
+                ServiceInfo<TestServiceType> serviceInfo = map.get(resolveInfo);
+                if (serviceInfo != null) {
+                    return serviceInfo;
+                }
+            }
+            throw new IllegalArgumentException("Unexpected service " + resolveInfo);
+        }
+
+        @Override
+        public void onUserRemoved(int userId) {
+            super.onUserRemoved(userId);
+        }
+    }
+}
diff --git a/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java b/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java
index 8b513cb..524e355 100644
--- a/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java
+++ b/core/tests/coretests/src/android/content/pm/SystemFeaturesCacheTest.java
@@ -136,9 +136,11 @@
         SystemFeaturesCache cache = new SystemFeaturesCache(features);
 
         SystemFeaturesCache.clearInstance();
+        assertThat(SystemFeaturesCache.hasInstance()).isFalse();
         assertThrows(IllegalStateException.class, () -> SystemFeaturesCache.getInstance());
 
         SystemFeaturesCache.setInstance(cache);
+        assertThat(SystemFeaturesCache.hasInstance()).isTrue();
         assertThat(SystemFeaturesCache.getInstance()).isEqualTo(cache);
 
         assertThrows(
@@ -149,6 +151,7 @@
     @Test
     public void testSingletonAutomaticallySetWithFeatureEnabled() {
         assumeTrue(android.content.pm.Flags.cacheSdkSystemFeatures());
+        assertThat(SystemFeaturesCache.hasInstance()).isTrue();
         assertThat(SystemFeaturesCache.getInstance()).isNotNull();
     }
 
diff --git a/core/tests/coretests/src/android/content/pm/UserInfoTest.java b/core/tests/coretests/src/android/content/pm/UserInfoTest.java
index edeea6d..c84c215 100644
--- a/core/tests/coretests/src/android/content/pm/UserInfoTest.java
+++ b/core/tests/coretests/src/android/content/pm/UserInfoTest.java
@@ -16,19 +16,44 @@
 
 package android.content.pm;
 
+import static android.content.pm.UserInfo.FLAG_DEMO;
+import static android.content.pm.UserInfo.FLAG_FULL;
+import static android.content.pm.UserInfo.FLAG_GUEST;
+import static android.content.pm.UserInfo.FLAG_MAIN;
+import static android.content.pm.UserInfo.FLAG_PROFILE;
+import static android.content.pm.UserInfo.FLAG_SYSTEM;
+import static android.os.UserManager.USER_TYPE_FULL_RESTRICTED;
+import static android.os.UserManager.USER_TYPE_FULL_SYSTEM;
+import static android.os.UserManager.USER_TYPE_SYSTEM_HEADLESS;
+
 import static com.google.common.truth.Truth.assertThat;
 
+import android.content.pm.UserInfo.UserInfoFlag;
 import android.os.UserHandle;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
+import com.google.common.truth.Expect;
+
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-public class UserInfoTest {
+public final class UserInfoTest {
+
+    @Rule
+    public final SetFlagsRule flags =
+            new SetFlagsRule(SetFlagsRule.DefaultInitValueType.DEVICE_DEFAULT);
+
+    @Rule public final Expect expect = Expect.create();
+
     @Test
     public void testSimple() throws Exception {
         final UserInfo ui = new UserInfo(10, "Test", UserInfo.FLAG_GUEST);
@@ -56,9 +81,6 @@
         assertThat(ui.isInitialized()).isEqualTo(false);
         assertThat(ui.isFull()).isEqualTo(false);
         assertThat(ui.isMain()).isEqualTo(false);
-
-        // Derived dynamically
-        assertThat(ui.canHaveProfile()).isEqualTo(false);
     }
 
     @Test
@@ -68,4 +90,64 @@
         assertThat(ui.toString()).isNotEmpty();
         assertThat(ui.toFullString()).isNotEmpty();
     }
+
+    @Test
+    @DisableFlags(android.multiuser.Flags.FLAG_PROFILES_FOR_ALL)
+    public void testCanHaveProfile_flagProfilesForAllDisabled() {
+        expectCannotHaveProfile("non-full user", createTestUserInfo(/* flags= */ 0));
+        expectCannotHaveProfile("guest user", createTestUserInfo(FLAG_FULL | FLAG_GUEST));
+        expectCanHaveProfile("main user", createTestUserInfo(FLAG_FULL | FLAG_MAIN));
+        expectCannotHaveProfile("non-main user", createTestUserInfo(FLAG_FULL));
+        expectCannotHaveProfile("demo user", createTestUserInfo(FLAG_FULL | FLAG_DEMO));
+        expectCannotHaveProfile("restricted user",
+                createTestUserInfo(USER_TYPE_FULL_RESTRICTED, FLAG_FULL));
+        expectCannotHaveProfile("profile user", createTestUserInfo(FLAG_PROFILE));
+        expectCanHaveProfile("(full) system user that's also main user",
+                createTestUserInfo(USER_TYPE_FULL_SYSTEM, FLAG_FULL | FLAG_SYSTEM | FLAG_MAIN));
+        expectCannotHaveProfile("headless system user that's not main user",
+                createTestUserInfo(USER_TYPE_SYSTEM_HEADLESS, FLAG_SYSTEM));
+    }
+
+    @Test
+    @EnableFlags(android.multiuser.Flags.FLAG_PROFILES_FOR_ALL)
+    public void testCanHaveProfile_flagProfilesForAllEnabled() {
+        expectCannotHaveProfile("non-full user", createTestUserInfo(/* flags= */ 0));
+        expectCannotHaveProfile("guest user", createTestUserInfo(FLAG_FULL | FLAG_GUEST));
+        expectCanHaveProfile("main user", createTestUserInfo(FLAG_FULL | FLAG_MAIN));
+        expectCanHaveProfile("non-main user", createTestUserInfo(FLAG_FULL));
+        expectCannotHaveProfile("demo user", createTestUserInfo(FLAG_FULL | FLAG_DEMO));
+        expectCannotHaveProfile("restricted user",
+                createTestUserInfo(USER_TYPE_FULL_RESTRICTED, FLAG_FULL));
+        expectCannotHaveProfile("profile user", createTestUserInfo(FLAG_PROFILE));
+        expectCanHaveProfile("(full) system user that's also main user",
+                createTestUserInfo(USER_TYPE_FULL_SYSTEM, FLAG_FULL | FLAG_SYSTEM | FLAG_MAIN));
+        expectCannotHaveProfile("headless system user that's not main user",
+                createTestUserInfo(USER_TYPE_SYSTEM_HEADLESS, FLAG_SYSTEM));
+    }
+
+    /**
+     * Creates a new {@link UserInfo} with id {@code 10}, name {@code Test}, and the given
+     * {@code flags}.
+     */
+    private UserInfo createTestUserInfo(@UserInfoFlag int flags) {
+        return new UserInfo(10, "Test", flags);
+    }
+
+    /**
+     * Creates a new {@link UserInfo} with id {@code 10}, name {@code Test}, and the given
+     * {@code userType} and {@code flags}.
+     */
+    private UserInfo createTestUserInfo(String userType, @UserInfoFlag int flags) {
+        return new UserInfo(10, "Test", /* iconPath= */ null, flags, userType);
+    }
+
+    private void expectCanHaveProfile(String description, UserInfo user) {
+        expect.withMessage("canHaveProfile() on %s (%s)", description, user)
+                .that(user.canHaveProfile()).isTrue();
+    }
+
+    private void expectCannotHaveProfile(String description, UserInfo user) {
+        expect.withMessage("canHaveProfile() on %s (%s)", description, user)
+                .that(user.canHaveProfile()).isFalse();
+    }
 }
diff --git a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
index de5f0ff..34650be 100644
--- a/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
+++ b/core/tests/coretests/src/android/hardware/display/DisplayManagerGlobalTest.java
@@ -264,7 +264,7 @@
                         /* isEventFilterExplicit */ true);
         callback.onDisplayEvent(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
         waitForHandler();
-        Mockito.verifyZeroInteractions(mDisplayListener);
+        Mockito.verifyNoMoreInteractions(mDisplayListener);
 
         mDisplayManagerGlobal.registerDisplayListener(mDisplayListener, mHandler,
                 ALL_DISPLAY_EVENTS
@@ -272,7 +272,7 @@
                         /* isEventFilterExplicit */ true);
         callback.onDisplayEvent(displayId, DisplayManagerGlobal.EVENT_DISPLAY_BASIC_CHANGED);
         waitForHandler();
-        Mockito.verifyZeroInteractions(mDisplayListener);
+        Mockito.verifyNoMoreInteractions(mDisplayListener);
 
         mDisplayManagerGlobal.registerDisplayListener(mDisplayListener, mHandler,
                 ALL_DISPLAY_EVENTS
@@ -280,7 +280,7 @@
                         /* isEventFilterExplicit */ true);
         callback.onDisplayEvent(displayId, DisplayManagerGlobal.EVENT_DISPLAY_REMOVED);
         waitForHandler();
-        Mockito.verifyZeroInteractions(mDisplayListener);
+        Mockito.verifyNoMoreInteractions(mDisplayListener);
     }
 
     @Test
diff --git a/core/tests/coretests/src/android/os/AidlTest.java b/core/tests/coretests/src/android/os/AidlTest.java
index 006828f..570f236 100644
--- a/core/tests/coretests/src/android/os/AidlTest.java
+++ b/core/tests/coretests/src/android/os/AidlTest.java
@@ -22,7 +22,7 @@
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
@@ -35,7 +35,7 @@
 
 import java.util.List;
 
-@IgnoreUnderRavenwood(blockedBy = Parcel.class)
+@DisabledOnRavenwood(blockedBy = Parcel.class)
 public class AidlTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/BinderDeathRecipientTest.java b/core/tests/coretests/src/android/os/BinderDeathRecipientTest.java
index 5ef1460..3125fdd 100644
--- a/core/tests/coretests/src/android/os/BinderDeathRecipientTest.java
+++ b/core/tests/coretests/src/android/os/BinderDeathRecipientTest.java
@@ -25,7 +25,7 @@
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.ArraySet;
 import android.util.Log;
@@ -55,7 +55,7 @@
  * Tests functionality of {@link android.os.IBinder.DeathRecipient} callbacks.
  */
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
+@DisabledOnRavenwood(blockedBy = ActivityManager.class)
 public class BinderDeathRecipientTest {
     private static final String TAG = BinderDeathRecipientTest.class.getSimpleName();
     private static final String TEST_PACKAGE_NAME_1 =
diff --git a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
index 523fe1a..0ebd293 100644
--- a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
+++ b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java
@@ -27,7 +27,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.Log;
 
@@ -55,7 +55,7 @@
  * Tests functionality of {@link android.os.IBinder.FrozenStateChangeCallback}.
  */
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
+@DisabledOnRavenwood(blockedBy = ActivityManager.class)
 public class BinderFrozenStateChangeNotificationTest {
     private static final String TAG = BinderFrozenStateChangeNotificationTest.class.getSimpleName();
 
diff --git a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java
index 4dfe2e2..31353e7 100644
--- a/core/tests/coretests/src/android/os/BinderProxyCountingTest.java
+++ b/core/tests/coretests/src/android/os/BinderProxyCountingTest.java
@@ -24,7 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.Log;
 
@@ -74,7 +74,7 @@
  */
 @LargeTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
+@DisabledOnRavenwood(blockedBy = ActivityManager.class)
 public class BinderProxyCountingTest {
     private static final String TAG = BinderProxyCountingTest.class.getSimpleName();
 
diff --git a/core/tests/coretests/src/android/os/BinderProxyTest.java b/core/tests/coretests/src/android/os/BinderProxyTest.java
index 5fff0b8..656d3bf 100644
--- a/core/tests/coretests/src/android/os/BinderProxyTest.java
+++ b/core/tests/coretests/src/android/os/BinderProxyTest.java
@@ -27,7 +27,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.InstrumentationRegistry;
@@ -43,7 +43,7 @@
 import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
+@DisabledOnRavenwood(blockedBy = ActivityManager.class)
 public class BinderProxyTest {
     private static class CountingListener implements Binder.ProxyTransactListener {
         int mStartedCount;
diff --git a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
index 9a679d8..3438028 100644
--- a/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
+++ b/core/tests/coretests/src/android/os/BinderThreadPriorityTest.java
@@ -24,7 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.Log;
 
@@ -46,7 +46,7 @@
  * Test whether Binder calls inherit thread priorities correctly.
  */
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
+@DisabledOnRavenwood(blockedBy = ActivityManager.class)
 public class BinderThreadPriorityTest {
     private static final String TAG = "BinderThreadPriorityTest";
 
diff --git a/core/tests/coretests/src/android/os/BinderWorkSourceTest.java b/core/tests/coretests/src/android/os/BinderWorkSourceTest.java
index 98e96c2..9b61cd2 100644
--- a/core/tests/coretests/src/android/os/BinderWorkSourceTest.java
+++ b/core/tests/coretests/src/android/os/BinderWorkSourceTest.java
@@ -24,7 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.ravenwood.RavenwoodRule;
 
@@ -45,7 +45,7 @@
 @LargeTest
 @Presubmit
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
+@DisabledOnRavenwood(blockedBy = ActivityManager.class)
 public class BinderWorkSourceTest {
     private static Context sContext;
     private static final int UID = 100;
diff --git a/core/tests/coretests/src/android/os/CancellationSignalBeamerTest.java b/core/tests/coretests/src/android/os/CancellationSignalBeamerTest.java
index 2117e74..1e6fc15 100644
--- a/core/tests/coretests/src/android/os/CancellationSignalBeamerTest.java
+++ b/core/tests/coretests/src/android/os/CancellationSignalBeamerTest.java
@@ -22,7 +22,7 @@
 
 import android.content.Context;
 import android.os.CancellationSignalBeamer.Receiver;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.PollingCheck;
 import android.util.PollingCheck.PollingCheckCondition;
@@ -44,7 +44,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@IgnoreUnderRavenwood(blockedBy = CancellationSignalBeamer.class)
+@DisabledOnRavenwood(blockedBy = CancellationSignalBeamer.class)
 public class CancellationSignalBeamerTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/CancellationSignalTest.java b/core/tests/coretests/src/android/os/CancellationSignalTest.java
index 8e11df5..3b05cf7 100644
--- a/core/tests/coretests/src/android/os/CancellationSignalTest.java
+++ b/core/tests/coretests/src/android/os/CancellationSignalTest.java
@@ -19,11 +19,8 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.ravenwood.RavenwoodRule;
-
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -32,11 +29,6 @@
 
 @RunWith(AndroidJUnit4.class)
 public class CancellationSignalTest {
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     @Test
     public void testSimple() throws Exception {
         final CancellationSignal signal = new CancellationSignal();
diff --git a/core/tests/coretests/src/android/os/EnvironmentTest.java b/core/tests/coretests/src/android/os/EnvironmentTest.java
index 1b49624..99ce175 100644
--- a/core/tests/coretests/src/android/os/EnvironmentTest.java
+++ b/core/tests/coretests/src/android/os/EnvironmentTest.java
@@ -28,7 +28,7 @@
 
 import android.content.Context;
 import android.os.storage.StorageManager;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.InstrumentationRegistry;
@@ -46,7 +46,7 @@
 import java.util.function.BiFunction;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = Environment.class)
+@DisabledOnRavenwood(blockedBy = Environment.class)
 public class EnvironmentTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/FileBridgeTest.java b/core/tests/coretests/src/android/os/FileBridgeTest.java
index 726670b..fa2a5f4 100644
--- a/core/tests/coretests/src/android/os/FileBridgeTest.java
+++ b/core/tests/coretests/src/android/os/FileBridgeTest.java
@@ -24,7 +24,7 @@
 import static org.junit.Assert.fail;
 
 import android.os.FileBridge.FileBridgeOutputStream;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.test.MoreAsserts;
 
@@ -46,7 +46,7 @@
 import java.util.Random;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ParcelFileDescriptor.class)
+@DisabledOnRavenwood(blockedBy = ParcelFileDescriptor.class)
 public class FileBridgeTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/FileObserverTest.java b/core/tests/coretests/src/android/os/FileObserverTest.java
index 3cd8045..6412023 100644
--- a/core/tests/coretests/src/android/os/FileObserverTest.java
+++ b/core/tests/coretests/src/android/os/FileObserverTest.java
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.Log;
 
@@ -42,7 +42,7 @@
 import java.util.Map;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = FileObserver.class)
+@DisabledOnRavenwood(blockedBy = FileObserver.class)
 public class FileObserverTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/IpcDataCacheTest.java b/core/tests/coretests/src/android/os/IpcDataCacheTest.java
index 791ec5d..2b49b38 100644
--- a/core/tests/coretests/src/android/os/IpcDataCacheTest.java
+++ b/core/tests/coretests/src/android/os/IpcDataCacheTest.java
@@ -26,7 +26,7 @@
 import android.app.PropertyInvalidatedCache;
 import android.app.PropertyInvalidatedCache.Args;
 import android.multiuser.Flags;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
diff --git a/core/tests/coretests/src/android/os/MemoryFileTest.java b/core/tests/coretests/src/android/os/MemoryFileTest.java
index a695424..38ba639 100644
--- a/core/tests/coretests/src/android/os/MemoryFileTest.java
+++ b/core/tests/coretests/src/android/os/MemoryFileTest.java
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -40,7 +40,7 @@
 import java.util.List;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = MemoryFile.class)
+@DisabledOnRavenwood(blockedBy = MemoryFile.class)
 public class MemoryFileTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/MessengerTest.java b/core/tests/coretests/src/android/os/MessengerTest.java
index eb6263f..2014aa7 100644
--- a/core/tests/coretests/src/android/os/MessengerTest.java
+++ b/core/tests/coretests/src/android/os/MessengerTest.java
@@ -21,7 +21,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.InstrumentationRegistry;
@@ -35,7 +35,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ActivityManager.class)
+@DisabledOnRavenwood(blockedBy = ActivityManager.class)
 public class MessengerTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/PerfettoTraceTest.java b/core/tests/coretests/src/android/os/PerfettoTraceTest.java
index 790ac4a..b345315 100644
--- a/core/tests/coretests/src/android/os/PerfettoTraceTest.java
+++ b/core/tests/coretests/src/android/os/PerfettoTraceTest.java
@@ -23,7 +23,7 @@
 import static perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.LatencyComponentType.COMPONENT_INPUT_EVENT_LATENCY_BEGIN_RWH;
 import static perfetto.protos.ChromeLatencyInfoOuterClass.ChromeLatencyInfo.LatencyComponentType.COMPONENT_INPUT_EVENT_LATENCY_SCROLL_UPDATE_ORIGINAL;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.flag.junit.CheckFlagsRule;
 import android.platform.test.flag.junit.DeviceFlagsValueProvider;
@@ -68,7 +68,7 @@
  * while tracing on the emulator and then run traceview to view the trace.
  */
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = PerfettoTrace.class)
+@DisabledOnRavenwood(blockedBy = PerfettoTrace.class)
 public class PerfettoTraceTest {
     @Rule
     public final CheckFlagsRule mCheckFlagsRule =
diff --git a/core/tests/coretests/src/android/os/PerformanceCollectorTest.java b/core/tests/coretests/src/android/os/PerformanceCollectorTest.java
index 436720e..c256680 100644
--- a/core/tests/coretests/src/android/os/PerformanceCollectorTest.java
+++ b/core/tests/coretests/src/android/os/PerformanceCollectorTest.java
@@ -22,7 +22,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.os.PerformanceCollector.PerformanceResultsWriter;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -40,7 +40,7 @@
 import java.util.Random;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = PerformanceCollector.class)
+@DisabledOnRavenwood(blockedBy = PerformanceCollector.class)
 public class PerformanceCollectorTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
index 4b49fde..b7c25f2 100644
--- a/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
+++ b/core/tests/coretests/src/android/os/PerformanceHintManagerTest.java
@@ -24,7 +24,7 @@
 import static org.junit.Assume.assumeNotNull;
 
 import android.os.PerformanceHintManager.Session;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.InstrumentationRegistry;
@@ -38,7 +38,7 @@
 import org.mockito.MockitoAnnotations;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = PerformanceHintManager.class)
+@DisabledOnRavenwood(blockedBy = PerformanceHintManager.class)
 public class PerformanceHintManagerTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/ProcessTest.java b/core/tests/coretests/src/android/os/ProcessTest.java
index ea39db7..3d50cfe 100644
--- a/core/tests/coretests/src/android/os/ProcessTest.java
+++ b/core/tests/coretests/src/android/os/ProcessTest.java
@@ -21,7 +21,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import org.junit.Rule;
@@ -29,7 +29,7 @@
 
 import java.util.Arrays;
 
-@IgnoreUnderRavenwood(blockedBy = Process.class)
+@DisabledOnRavenwood(blockedBy = Process.class)
 public class ProcessTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
index e22c862..a6160bb 100644
--- a/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
+++ b/core/tests/coretests/src/android/os/RedactingFileDescriptorTest.java
@@ -24,7 +24,7 @@
 import static org.junit.Assert.assertEquals;
 
 import android.content.Context;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.system.Os;
 
@@ -44,7 +44,7 @@
 import java.util.Arrays;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = RedactingFileDescriptor.class)
+@DisabledOnRavenwood(blockedBy = RedactingFileDescriptor.class)
 public class RedactingFileDescriptorTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/RemoteCallbackTest.java b/core/tests/coretests/src/android/os/RemoteCallbackTest.java
index ddcc380..cbbaa75 100644
--- a/core/tests/coretests/src/android/os/RemoteCallbackTest.java
+++ b/core/tests/coretests/src/android/os/RemoteCallbackTest.java
@@ -19,11 +19,8 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.ravenwood.RavenwoodRule;
-
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -32,11 +29,6 @@
 
 @RunWith(AndroidJUnit4.class)
 public class RemoteCallbackTest {
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     @Test
     public void testSimple() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
diff --git a/core/tests/coretests/src/android/os/ResultReceiverTest.java b/core/tests/coretests/src/android/os/ResultReceiverTest.java
index be67825..21d4078 100644
--- a/core/tests/coretests/src/android/os/ResultReceiverTest.java
+++ b/core/tests/coretests/src/android/os/ResultReceiverTest.java
@@ -19,11 +19,8 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.ravenwood.RavenwoodRule;
-
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -32,11 +29,6 @@
 
 @RunWith(AndroidJUnit4.class)
 public class ResultReceiverTest {
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     @Test
     public void testSimple() throws Exception {
         final CountDownLatch latch = new CountDownLatch(1);
diff --git a/core/tests/coretests/src/android/os/TraceTest.java b/core/tests/coretests/src/android/os/TraceTest.java
index 5462f32..4117dd6 100644
--- a/core/tests/coretests/src/android/os/TraceTest.java
+++ b/core/tests/coretests/src/android/os/TraceTest.java
@@ -16,7 +16,7 @@
 
 package android.os;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.Log;
 
@@ -105,7 +105,7 @@
 
     @Test
     @SmallTest
-    @IgnoreUnderRavenwood(blockedBy = Debug.class)
+    @DisabledOnRavenwood(blockedBy = Debug.class)
     public void testNativeTracingFromJava()
     {
         long start = System.currentTimeMillis();
@@ -126,7 +126,7 @@
     
     // This should not run in the automated suite.
     @Suppress
-    @IgnoreUnderRavenwood(blockedBy = Debug.class)
+    @DisabledOnRavenwood(blockedBy = Debug.class)
     public void disableTestNativeTracingFromC()
     {
         long start = System.currentTimeMillis();
@@ -142,7 +142,7 @@
     @Test
     @LargeTest
     @Suppress  // Failing.
-    @IgnoreUnderRavenwood(blockedBy = Debug.class)
+    @DisabledOnRavenwood(blockedBy = Debug.class)
     public void testMethodTracing()
     {
         long start = System.currentTimeMillis();
diff --git a/core/tests/coretests/src/android/os/VintfObjectTest.java b/core/tests/coretests/src/android/os/VintfObjectTest.java
index f81b31d..1b7bb41 100644
--- a/core/tests/coretests/src/android/os/VintfObjectTest.java
+++ b/core/tests/coretests/src/android/os/VintfObjectTest.java
@@ -20,7 +20,7 @@
 
 import static java.util.stream.Collectors.toList;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.Pair;
 
@@ -37,7 +37,7 @@
 import javax.xml.parsers.DocumentBuilderFactory;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = VintfObject.class)
+@DisabledOnRavenwood(blockedBy = VintfObject.class)
 public class VintfObjectTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/os/WorkSourceParcelTest.java b/core/tests/coretests/src/android/os/WorkSourceParcelTest.java
index 5f49186..0ebf128 100644
--- a/core/tests/coretests/src/android/os/WorkSourceParcelTest.java
+++ b/core/tests/coretests/src/android/os/WorkSourceParcelTest.java
@@ -18,7 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -30,7 +30,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@IgnoreUnderRavenwood(reason = "JNI")
+@DisabledOnRavenwood(reason = "JNI")
 public class WorkSourceParcelTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
@@ -49,7 +49,7 @@
             String[] names, int parcelEndMarker);
 
     static {
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             System.loadLibrary("worksourceparceltest_jni");
         }
     }
diff --git a/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java b/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java
index 45864b0..e06ff98 100644
--- a/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java
+++ b/core/tests/coretests/src/android/security/advancedprotection/AdvancedProtectionManagerTest.java
@@ -16,10 +16,14 @@
 
 package android.security.advancedprotection;
 
+import static android.os.UserManager.DISALLOW_CELLULAR_2G;
+import static android.os.UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY;
 import static android.security.advancedprotection.AdvancedProtectionManager.ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG;
 import static android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_FEATURE;
 import static android.security.advancedprotection.AdvancedProtectionManager.EXTRA_SUPPORT_DIALOG_TYPE;
 import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G;
+import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
+import static android.security.advancedprotection.AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE;
 import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION;
 import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING;
 import static android.security.advancedprotection.AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN;
@@ -37,6 +41,9 @@
 public class AdvancedProtectionManagerTest {
     private static final int FEATURE_ID_INVALID = -1;
     private static final int SUPPORT_DIALOG_TYPE_INVALID = -1;
+    //TODO(b/378931989): Switch to android.app.admin.DevicePolicyIdentifiers.MEMORY_TAGGING_POLICY
+    //when the appropriate flag is launched.
+    private static final String MEMORY_TAGGING_POLICY = "memoryTagging";
 
     @Test
     public void testCreateSupportIntent_validFeature_validTypeUnknown_createsIntent() {
@@ -94,4 +101,44 @@
                 AdvancedProtectionManager.createSupportIntent(FEATURE_ID_INVALID,
                         SUPPORT_DIALOG_TYPE_INVALID));
     }
+
+    @Test
+    public void testCreateSupportIntentForPolicy_2g_typeUnknown_createsIntentForDisabledSetting() {
+        Intent intent = AdvancedProtectionManager
+                .createSupportIntentForPolicyIdentifierOrRestriction(
+                        DISALLOW_CELLULAR_2G, SUPPORT_DIALOG_TYPE_UNKNOWN);
+
+        assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
+        assertEquals(FEATURE_ID_DISALLOW_CELLULAR_2G, intent.getIntExtra(
+                EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
+        assertEquals(SUPPORT_DIALOG_TYPE_DISABLED_SETTING, intent.getIntExtra(
+                EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_INVALID));
+    }
+
+    @Test
+    public void testCreateSupportIntentForPolicy_mte_typeUnknown_createsIntentForDisabledSetting() {
+        Intent intent = AdvancedProtectionManager
+                .createSupportIntentForPolicyIdentifierOrRestriction(
+                        MEMORY_TAGGING_POLICY, SUPPORT_DIALOG_TYPE_UNKNOWN);
+
+        assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
+        assertEquals(FEATURE_ID_ENABLE_MTE, intent.getIntExtra(
+                EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
+        assertEquals(SUPPORT_DIALOG_TYPE_DISABLED_SETTING, intent.getIntExtra(
+                EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_INVALID));
+    }
+
+    @Test
+    public void
+            testCreateSupportIntentForPolicy_unknownSources_typeUnknown_createsIntentForUnknown() {
+        Intent intent = AdvancedProtectionManager
+                .createSupportIntentForPolicyIdentifierOrRestriction(
+                        DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY, SUPPORT_DIALOG_TYPE_UNKNOWN);
+
+        assertEquals(ACTION_SHOW_ADVANCED_PROTECTION_SUPPORT_DIALOG, intent.getAction());
+        assertEquals(FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES, intent.getIntExtra(
+                EXTRA_SUPPORT_DIALOG_FEATURE, FEATURE_ID_INVALID));
+        assertEquals(SUPPORT_DIALOG_TYPE_UNKNOWN, intent.getIntExtra(
+                EXTRA_SUPPORT_DIALOG_TYPE, SUPPORT_DIALOG_TYPE_INVALID));
+    }
 }
diff --git a/core/tests/coretests/src/android/util/ArrayMapTest.java b/core/tests/coretests/src/android/util/ArrayMapTest.java
index c7efe6f9..d71a603 100644
--- a/core/tests/coretests/src/android/util/ArrayMapTest.java
+++ b/core/tests/coretests/src/android/util/ArrayMapTest.java
@@ -18,7 +18,7 @@
 
 import static org.junit.Assert.fail;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.ravenwood.RavenwoodRule;
 
@@ -57,7 +57,7 @@
      */
     @Test
     @Ignore("Failing; b/399137661")
-    @IgnoreUnderRavenwood(reason = "Long test runtime")
+    @DisabledOnRavenwood(reason = "Long test runtime")
     public void testConcurrentModificationException() throws Exception {
         final int TEST_LEN_MS = 5000;
         System.out.println("Starting ArrayMap concurrency test");
diff --git a/core/tests/coretests/src/android/util/CharsetUtilsTest.java b/core/tests/coretests/src/android/util/CharsetUtilsTest.java
index 33936e9..cf6e1eb 100644
--- a/core/tests/coretests/src/android/util/CharsetUtilsTest.java
+++ b/core/tests/coretests/src/android/util/CharsetUtilsTest.java
@@ -18,7 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -33,7 +33,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = CharsetUtils.class)
+@DisabledOnRavenwood(blockedBy = CharsetUtils.class)
 public class CharsetUtilsTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
@@ -43,7 +43,7 @@
 
     @Before
     public void setUp() {
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             dest = (byte[]) VMRuntime.getRuntime().newNonMovableArray(byte.class, 8);
             destPtr = VMRuntime.getRuntime().addressOf(dest);
         }
diff --git a/core/tests/coretests/src/android/util/CloseGuardTest.java b/core/tests/coretests/src/android/util/CloseGuardTest.java
index 15c57b1..c91ef1c 100644
--- a/core/tests/coretests/src/android/util/CloseGuardTest.java
+++ b/core/tests/coretests/src/android/util/CloseGuardTest.java
@@ -16,7 +16,7 @@
 
 package android.util;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import libcore.dalvik.system.CloseGuardSupport;
@@ -26,7 +26,7 @@
 import org.junit.rules.TestRule;
 
 /** Unit tests for {@link android.util.CloseGuard} */
-@IgnoreUnderRavenwood(blockedBy = CloseGuard.class)
+@DisabledOnRavenwood(blockedBy = CloseGuard.class)
 public class CloseGuardTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
@@ -35,7 +35,7 @@
     public final TestRule rule;
 
     public CloseGuardTest() {
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             rule = CloseGuardSupport.getRule();
         } else {
             rule = null;
diff --git a/core/tests/coretests/src/android/util/HashedStringCacheTest.java b/core/tests/coretests/src/android/util/HashedStringCacheTest.java
index 08c85ac..c26855b 100644
--- a/core/tests/coretests/src/android/util/HashedStringCacheTest.java
+++ b/core/tests/coretests/src/android/util/HashedStringCacheTest.java
@@ -26,7 +26,7 @@
 import android.content.SharedPreferences;
 import android.os.Environment;
 import android.os.storage.StorageManager;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.InstrumentationRegistry;
@@ -40,7 +40,7 @@
 /**
  * Unit tests for {@link HashedStringCache}.
  */
-@IgnoreUnderRavenwood(blockedBy = HashedStringCache.class)
+@DisabledOnRavenwood(blockedBy = HashedStringCache.class)
 public class HashedStringCacheTest {
     private static final String TAG = "HashedStringCacheTest";
     private Context mContext;
@@ -51,7 +51,7 @@
 
     @Before
     public void setup() {
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             mContext = InstrumentationRegistry.getContext();
             clearSharedPreferences();
         } else {
diff --git a/core/tests/coretests/src/android/util/LogNullabilityTest.java b/core/tests/coretests/src/android/util/LogNullabilityTest.java
index 5aa2626..795444d 100644
--- a/core/tests/coretests/src/android/util/LogNullabilityTest.java
+++ b/core/tests/coretests/src/android/util/LogNullabilityTest.java
@@ -37,7 +37,7 @@
         Log.i(null, "");
         Log.w(null, "");
         Log.e(null, "");
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             Log.wtf(null, "");
             Log.wtfStack(null, "");
         }
@@ -53,7 +53,7 @@
         Log.i(null, "", new Throwable());
         Log.w(null, "", new Throwable());
         Log.e(null, "", new Throwable());
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             Log.wtf(null, "", new Throwable());
         }
         Log.printlns(Log.LOG_ID_MAIN, Log.INFO, null, "", new Throwable());
@@ -90,7 +90,7 @@
         } catch (NullPointerException expected) {
         }
 
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             Log.wtf("", (String) null);
             Log.wtfStack("", (String) null);
         }
@@ -111,7 +111,7 @@
         Log.i("", null, new Throwable());
         Log.w("", null, new Throwable());
         Log.e("", null, new Throwable());
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             Log.wtf("", null, new Throwable());
         }
         Log.printlns(Log.LOG_ID_MAIN, Log.INFO, "", null, new Throwable());
@@ -124,7 +124,7 @@
         Log.i("", "", null);
         Log.w("", "", null);
         Log.e("", "", null);
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             Log.wtf("", "", null);
         }
 
@@ -136,7 +136,7 @@
         // Implicit assertions of not crashing.
 
         // WTF has its own (String, Throwable) overload with different behavior.
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             try {
                 Log.wtf("", (Throwable) null);
                 fail();
@@ -152,7 +152,7 @@
         Log.i("", null, null);
         Log.w("", null, null);
         Log.e("", null, null);
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             Log.wtf("", null, null);
         }
         Log.printlns(Log.LOG_ID_MAIN, Log.INFO, "", null, null);
diff --git a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
index ce1eabc..32fb3a2 100644
--- a/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
+++ b/core/tests/coretests/src/android/util/NtpTrustedTimeTest.java
@@ -31,7 +31,7 @@
 import static java.util.Arrays.asList;
 
 import android.net.Network;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -56,7 +56,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = NtpTrustedTime.class)
+@DisabledOnRavenwood(blockedBy = NtpTrustedTime.class)
 public class NtpTrustedTimeTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
index 48e76f7..56d6594 100644
--- a/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
+++ b/core/tests/coretests/src/android/util/apk/SourceStampVerifierTest.java
@@ -26,7 +26,7 @@
 import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
 
 import android.content.Context;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -52,7 +52,7 @@
 
 /** Unit test for {@link android.util.apk.SourceStampVerifier} */
 @RunWith(JUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = SourceStampVerifier.class)
+@DisabledOnRavenwood(blockedBy = SourceStampVerifier.class)
 public class SourceStampVerifierTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/android/view/InsetsControllerTest.java b/core/tests/coretests/src/android/view/InsetsControllerTest.java
index af87af0..79d8bb1 100644
--- a/core/tests/coretests/src/android/view/InsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/InsetsControllerTest.java
@@ -1208,8 +1208,9 @@
         });
         InstrumentationRegistry.getInstrumentation().waitForIdleSync();
 
-        verify(mTestHost, times(1)).updateAnimatingTypes(eq(types));
-        verify(mTestHost, times(1)).updateAnimatingTypes(eq(0) /* animatingTypes */);
+        verify(mTestHost, times(1)).updateAnimatingTypes(eq(types), any() /* statsToken */);
+        verify(mTestHost, times(1)).updateAnimatingTypes(eq(0) /* animatingTypes */,
+                any() /* statsToken */);
     }
 
     private void waitUntilNextFrame() throws Exception {
diff --git a/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java b/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
index 8ac9292..50cd4c0 100644
--- a/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
+++ b/core/tests/coretests/src/android/view/PendingInsetsControllerTest.java
@@ -29,7 +29,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.os.CancellationSignal;
@@ -230,7 +230,7 @@
         InsetsController secondController = mock(InsetsController.class);
         mPendingInsetsController.replayAndAttach(secondController);
         verify(mReplayedController).show(eq(systemBars()));
-        verifyZeroInteractions(secondController);
+        verifyNoMoreInteractions(secondController);
     }
 
     @Test
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index 39f3d33..5774109 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -1063,7 +1063,7 @@
         ViewRootImpl viewRootImpl = mView.getViewRootImpl();
         sInstrumentation.runOnMainSync(() -> {
             mView.invalidate();
-            viewRootImpl.updateAnimatingTypes(Type.systemBars());
+            viewRootImpl.updateAnimatingTypes(Type.systemBars(), null /* statsToken */);
             mView.invalidate();
         });
         sInstrumentation.waitForIdleSync();
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java
index eb482f2e..f811d8e 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java
@@ -20,7 +20,7 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.MockitoAnnotations.initMocks;
 
 import android.os.Bundle;
@@ -74,7 +74,7 @@
                 MOCK_CONNECTION_ID, windowId, accessibilityNodeId, true, 0, null);
         assertEquals("Node got lost along the way", nodeFromConnection, node);
 
-        verifyZeroInteractions(mMockCache);
+        verifyNoMoreInteractions(mMockCache);
     }
 
     @Test
diff --git a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
index 5f89f9c..8bbe81d 100644
--- a/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
+++ b/core/tests/coretests/src/android/view/contentcapture/MainContentCaptureSessionTest.java
@@ -27,7 +27,7 @@
 import static org.mockito.Mockito.eq;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.content.ComponentName;
 import android.content.ContentCaptureOptions;
@@ -130,7 +130,7 @@
         mTestableLooper.processAllMessages();
 
         assertThat(session.mContentProtectionEventProcessor).isNull();
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
     }
 
     @Test
@@ -151,7 +151,7 @@
         mTestableLooper.processAllMessages();
 
         assertThat(session.mContentProtectionEventProcessor).isNull();
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
     }
 
     @Test
@@ -172,7 +172,7 @@
         mTestableLooper.processAllMessages();
 
         assertThat(session.mContentProtectionEventProcessor).isNull();
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
     }
 
     @Test
@@ -197,7 +197,7 @@
         session.sendEvent(EVENT);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mEvents).isNull();
     }
 
@@ -227,7 +227,7 @@
         session.sendEvent(EVENT);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mEvents).isNotNull();
         assertThat(session.mEvents).containsExactly(EVENT);
     }
@@ -255,7 +255,7 @@
         session.sendEvent(EVENT);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mEvents).isNull();
     }
 
@@ -272,8 +272,8 @@
         session.flush(REASON);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentCaptureDirectManager);
         assertThat(session.mEvents).containsExactly(EVENT);
     }
 
@@ -289,8 +289,8 @@
         session.flush(REASON);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentCaptureDirectManager);
         assertThat(session.mEvents).containsExactly(EVENT);
     }
 
@@ -307,7 +307,7 @@
         session.flush(REASON);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mEvents).isEmpty();
         assertEventFlushedContentCapture(options);
     }
@@ -325,7 +325,7 @@
         session.flush(REASON);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mEvents).isEmpty();
         assertEventFlushedContentCapture(options);
     }
@@ -339,7 +339,7 @@
         mTestableLooper.processAllMessages();
 
         verify(mMockSystemServerInterface).finishSession(anyInt());
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mDirectServiceInterface).isNull();
         assertThat(session.mContentProtectionEventProcessor).isNull();
     }
@@ -352,8 +352,8 @@
         session.resetSession(/* newState= */ 0);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockSystemServerInterface);
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockSystemServerInterface);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mDirectServiceInterface).isNull();
         assertThat(session.mContentProtectionEventProcessor).isNull();
     }
@@ -370,8 +370,8 @@
         notifyContentCaptureEvents(session);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentCaptureDirectManager);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mEvents).isNull();
     }
 
@@ -388,8 +388,8 @@
         notifyContentCaptureEvents(session);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentCaptureDirectManager);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mEvents).isNull();
     }
 
@@ -407,8 +407,8 @@
         notifyContentCaptureEvents(session);
         mTestableLooper.processAllMessages();
 
-        verifyZeroInteractions(mMockContentCaptureDirectManager);
-        verifyZeroInteractions(mMockContentProtectionEventProcessor);
+        verifyNoMoreInteractions(mMockContentCaptureDirectManager);
+        verifyNoMoreInteractions(mMockContentProtectionEventProcessor);
         assertThat(session.mEvents).isNull();
     }
 
diff --git a/core/tests/coretests/src/android/view/contentprotection/ContentProtectionEventProcessorTest.java b/core/tests/coretests/src/android/view/contentprotection/ContentProtectionEventProcessorTest.java
index ba0dbf4..e75452c 100644
--- a/core/tests/coretests/src/android/view/contentprotection/ContentProtectionEventProcessorTest.java
+++ b/core/tests/coretests/src/android/view/contentprotection/ContentProtectionEventProcessorTest.java
@@ -26,7 +26,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.annotation.NonNull;
@@ -443,7 +442,7 @@
         mTestLooper.dispatchAll();
         verify(mMockEventBuffer, never()).clear();
         verify(mMockEventBuffer, never()).toArray();
-        verifyZeroInteractions(mMockContentCaptureManager);
+        verifyNoMoreInteractions(mMockContentCaptureManager);
     }
 
     private void assertLoginDetected() throws Exception {
diff --git a/core/tests/coretests/src/android/widget/RemoteViewsTest.java b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
index 9110898..2dcb692 100644
--- a/core/tests/coretests/src/android/widget/RemoteViewsTest.java
+++ b/core/tests/coretests/src/android/widget/RemoteViewsTest.java
@@ -1080,6 +1080,9 @@
         rv.setOnClickFillInIntent(R.id.view, fillInIntent);
         assertNotEquals(0, fillInIntent.getExtendedFlags()
                 & Intent.EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED);
+
+        RemoteViews.RemoteResponse rr = RemoteViews.RemoteResponse.fromFillInIntent(null);
+        assertNotNull(rr);
     }
 
     private static LayoutInflater.Factory2 createLayoutInflaterFactory(String viewTypeToReplace,
diff --git a/core/tests/coretests/src/android/widget/TextViewReceiveContentTest.java b/core/tests/coretests/src/android/widget/TextViewReceiveContentTest.java
index b61d868..3570c2e 100644
--- a/core/tests/coretests/src/android/widget/TextViewReceiveContentTest.java
+++ b/core/tests/coretests/src/android/widget/TextViewReceiveContentTest.java
@@ -33,7 +33,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.app.Activity;
 import android.app.Instrumentation;
@@ -159,7 +158,7 @@
         ContentInfo payload =
                 new ContentInfo.Builder(clip, SOURCE_AUTOFILL).build();
         mDefaultReceiver.onReceiveContent(mEditText, payload);
-        verifyZeroInteractions(ic.mMock);
+        verifyNoMoreInteractions(ic.mMock);
     }
 
     @Test
@@ -180,19 +179,19 @@
         ContentInfo payload =
                 new ContentInfo.Builder(clip, SOURCE_CLIPBOARD).build();
         mDefaultReceiver.onReceiveContent(mEditText, payload);
-        verifyZeroInteractions(ic.mMock);
+        verifyNoMoreInteractions(ic.mMock);
 
         payload = new ContentInfo.Builder(clip, SOURCE_INPUT_METHOD).build();
         mDefaultReceiver.onReceiveContent(mEditText, payload);
-        verifyZeroInteractions(ic.mMock);
+        verifyNoMoreInteractions(ic.mMock);
 
         payload = new ContentInfo.Builder(clip, SOURCE_DRAG_AND_DROP).build();
         mDefaultReceiver.onReceiveContent(mEditText, payload);
-        verifyZeroInteractions(ic.mMock);
+        verifyNoMoreInteractions(ic.mMock);
 
         payload = new ContentInfo.Builder(clip, SOURCE_PROCESS_TEXT).build();
         mDefaultReceiver.onReceiveContent(mEditText, payload);
-        verifyZeroInteractions(ic.mMock);
+        verifyNoMoreInteractions(ic.mMock);
     }
 
     private static class MyInputConnection extends InputConnectionWrapper {
diff --git a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
index 8900745..1977ff5 100644
--- a/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
+++ b/core/tests/coretests/src/com/android/internal/accessibility/AccessibilityShortcutControllerTest.java
@@ -44,7 +44,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.accessibilityservice.AccessibilityServiceInfo;
@@ -522,7 +522,7 @@
                 AccessibilityShortcutController.DialogStatus.SHOWN);
         getController().performAccessibilityShortcut();
 
-        verifyZeroInteractions(mAlertDialogBuilder, mAlertDialog);
+        verifyNoMoreInteractions(mAlertDialogBuilder, mAlertDialog);
         verify(mToast).show();
         verify(mAccessibilityManagerService).performAccessibilityShortcut(
                 Display.DEFAULT_DISPLAY, HARDWARE, null);
@@ -615,7 +615,7 @@
                 AccessibilityShortcutController.DialogStatus.SHOWN);
         getController().performAccessibilityShortcut();
 
-        verifyZeroInteractions(mToast);
+        verifyNoMoreInteractions(mToast);
         verify(mAccessibilityManagerService).performAccessibilityShortcut(
                 Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
@@ -632,7 +632,7 @@
                 AccessibilityShortcutController.DialogStatus.SHOWN);
         getController().performAccessibilityShortcut();
 
-        verifyZeroInteractions(mToast);
+        verifyNoMoreInteractions(mToast);
         verify(mAccessibilityManagerService).performAccessibilityShortcut(
                 Display.DEFAULT_DISPLAY, HARDWARE, null);
     }
diff --git a/core/tests/coretests/src/com/android/internal/os/BackgroundThreadTest.java b/core/tests/coretests/src/com/android/internal/os/BackgroundThreadTest.java
index 8bdf4c6..402ba0d 100644
--- a/core/tests/coretests/src/com/android/internal/os/BackgroundThreadTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BackgroundThreadTest.java
@@ -21,19 +21,13 @@
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.Looper;
-import android.platform.test.ravenwood.RavenwoodRule;
 
-import org.junit.Rule;
 import org.junit.Test;
 
 import java.util.concurrent.Executor;
 
 public class BackgroundThreadTest {
 
-    @Rule
-    public final RavenwoodRule mRavenwood =
-            new RavenwoodRule.Builder().setProvideMainThread(true).build();
-
     @Test
     public void test_get() {
         BackgroundThread thread = BackgroundThread.get();
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 5f8ab28..f44aa05 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -29,7 +29,7 @@
 import android.os.Message;
 import android.os.Process;
 import android.os.SystemClock;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.ArrayMap;
@@ -59,7 +59,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 @Presubmit
-@IgnoreUnderRavenwood(blockedBy = BinderCallsStats.class)
+@DisabledOnRavenwood(blockedBy = BinderCallsStats.class)
 public class BinderCallsStatsTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
index 3355cc3..5c2bf38 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
@@ -23,7 +23,7 @@
 import static org.junit.Assert.assertEquals;
 
 import android.os.Binder;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.ArrayMap;
@@ -50,7 +50,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 @Presubmit
-@IgnoreUnderRavenwood(blockedBy = BinderLatencyObserver.class)
+@DisabledOnRavenwood(blockedBy = BinderLatencyObserver.class)
 public class BinderLatencyObserverTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/DebugTest.java b/core/tests/coretests/src/com/android/internal/os/DebugTest.java
index 4371f26..e6a0e4a 100644
--- a/core/tests/coretests/src/com/android/internal/os/DebugTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/DebugTest.java
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.os.Debug;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
@@ -28,7 +28,7 @@
 import org.junit.Test;
 
 @SmallTest
-@IgnoreUnderRavenwood(reason = "Requires ART support")
+@DisabledOnRavenwood(reason = "Requires ART support")
 public class DebugTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java
index 8fd87c0..a625317 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuProcStringReaderTest.java
@@ -24,7 +24,7 @@
 import android.content.Context;
 import android.os.FileUtils;
 import android.os.SystemClock;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.InstrumentationRegistry;
@@ -60,7 +60,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuProcStringReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java
index 78cf65c..06d7521 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderDiffTest.java
@@ -24,7 +24,7 @@
 
 import static java.util.stream.Collectors.toList;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.ravenwood.RavenwoodRule;
 
@@ -47,7 +47,7 @@
 @Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuThreadReaderDiffTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
index 8c5e3d0..bb7a81a 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderEndToEndTest.java
@@ -22,7 +22,7 @@
 
 import android.os.Process;
 import android.os.SystemClock;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -50,7 +50,7 @@
  */
 @RunWith(AndroidJUnit4.class)
 @LargeTest
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuThreadReaderEndToEndTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
index c3d4b83..74dd999 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuThreadReaderTest.java
@@ -25,7 +25,7 @@
 
 import android.content.Context;
 import android.os.FileUtils;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.Presubmit;
 import android.platform.test.ravenwood.RavenwoodRule;
 
@@ -51,7 +51,7 @@
 @Presubmit
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuThreadReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidActiveTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidActiveTimeReaderTest.java
index d35e0fc..fc090ca 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidActiveTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidActiveTimeReaderTest.java
@@ -21,7 +21,7 @@
 
 import android.content.Context;
 import android.os.FileUtils;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseArray;
 import android.util.SparseLongArray;
@@ -54,7 +54,7 @@
  */
 @SmallTest
 @RunWith(Parameterized.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuUidActiveTimeReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java
index b75ad7f..5a01175 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidBpfMapReaderTest.java
@@ -23,7 +23,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.content.Context;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseArray;
 
@@ -52,7 +52,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuUidBpfMapReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidClusterTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidClusterTimeReaderTest.java
index 8807de0..bde66c7 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidClusterTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidClusterTimeReaderTest.java
@@ -23,7 +23,7 @@
 
 import android.content.Context;
 import android.os.FileUtils;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseArray;
 
@@ -55,7 +55,7 @@
  */
 @SmallTest
 @RunWith(Parameterized.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuUidClusterTimeReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidFreqTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidFreqTimeReaderTest.java
index b730344..28c340d 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidFreqTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidFreqTimeReaderTest.java
@@ -24,7 +24,7 @@
 
 import android.content.Context;
 import android.os.FileUtils;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseArray;
 
@@ -58,7 +58,7 @@
  */
 @SmallTest
 @RunWith(Parameterized.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuUidFreqTimeReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java
index 864e198..010d3d6 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelCpuUidUserSysTimeReaderTest.java
@@ -23,7 +23,7 @@
 
 import android.content.Context;
 import android.os.FileUtils;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseArray;
 
@@ -52,7 +52,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelCpuUidUserSysTimeReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelMemoryBandwidthStatsTest.java b/core/tests/coretests/src/com/android/internal/os/KernelMemoryBandwidthStatsTest.java
index a74f339..2b99a27 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelMemoryBandwidthStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelMemoryBandwidthStatsTest.java
@@ -18,7 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.LongSparseLongArray;
 
@@ -36,7 +36,7 @@
  * Tests for KernelMemoryBandwidthStats parsing and delta calculation, based on memory_state_time.
  */
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelMemoryBandwidthStatsTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelSingleProcessCpuThreadReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelSingleProcessCpuThreadReaderTest.java
index cdfef25..a4b44c7 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelSingleProcessCpuThreadReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelSingleProcessCpuThreadReaderTest.java
@@ -19,7 +19,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -35,7 +35,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelSingleProcessCpuThreadReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelSingleUidTimeReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelSingleUidTimeReaderTest.java
index 0ba2d85..262d6a2 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelSingleUidTimeReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelSingleUidTimeReaderTest.java
@@ -24,7 +24,7 @@
 import static org.junit.Assert.assertTrue;
 
 import android.annotation.SuppressLint;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseArray;
 
@@ -47,7 +47,7 @@
 
 @SmallTest
 @RunWith(Parameterized.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class KernelSingleUidTimeReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/ProcTimeInStateReaderTest.java b/core/tests/coretests/src/com/android/internal/os/ProcTimeInStateReaderTest.java
index 93dd09d..0de5f15 100644
--- a/core/tests/coretests/src/com/android/internal/os/ProcTimeInStateReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/ProcTimeInStateReaderTest.java
@@ -21,7 +21,7 @@
 import static org.junit.Assert.fail;
 
 import android.os.FileUtils;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -40,7 +40,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ProcTimeInStateReader.class)
+@DisabledOnRavenwood(blockedBy = ProcTimeInStateReader.class)
 public class ProcTimeInStateReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/os/ProcessCpuTrackerTest.java b/core/tests/coretests/src/com/android/internal/os/ProcessCpuTrackerTest.java
index d11c500..46cb382 100644
--- a/core/tests/coretests/src/com/android/internal/os/ProcessCpuTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/ProcessCpuTrackerTest.java
@@ -18,7 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
@@ -30,7 +30,7 @@
 
 @SmallTest
 @RunWith(JUnit4.class)
-@IgnoreUnderRavenwood(reason = "Needs kernel support")
+@DisabledOnRavenwood(reason = "Needs kernel support")
 public class ProcessCpuTrackerTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java
index d1c0668..dad1f13 100644
--- a/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java
+++ b/core/tests/coretests/src/com/android/internal/ravenwood/RavenwoodEnvironmentTest.java
@@ -32,7 +32,7 @@
 
     @Test
     public void testIsRunningOnRavenwood() {
-        assertEquals(RavenwoodRule.isUnderRavenwood(),
+        assertEquals(RavenwoodRule.isOnRavenwood(),
                 RavenwoodEnvironment.getInstance().isRunningOnRavenwood());
     }
 }
diff --git a/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java b/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java
index aa59afe..28533de 100644
--- a/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java
@@ -23,7 +23,7 @@
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.graphics.Color;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.text.Spannable;
 import android.text.SpannableString;
@@ -43,7 +43,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = Color.class)
+@DisabledOnRavenwood(blockedBy = Color.class)
 public class ContrastColorUtilTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java
index aee352b..83eb1e6 100644
--- a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java
@@ -24,7 +24,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.provider.DeviceConfig;
 
@@ -45,7 +45,7 @@
  * {@link LatencyTrackerTest}
  */
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = DeviceConfig.class)
+@DisabledOnRavenwood(blockedBy = DeviceConfig.class)
 public class FakeLatencyTrackerTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java
index 316b95ac..f603fdb 100644
--- a/core/tests/coretests/src/com/android/internal/util/FastDataTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/FastDataTest.java
@@ -64,7 +64,7 @@
 
     @Parameters(name = "use4ByteSequence={0}")
     public static Collection<Object[]> data() {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             // TODO: 4-byte sequences are only supported on ART
             return Arrays.asList(new Object[][]{{false}});
         } else {
diff --git a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
index ce265a3..1415651 100644
--- a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
@@ -25,7 +25,7 @@
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.common.truth.Truth.assertWithMessage;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.provider.DeviceConfig;
 
@@ -51,7 +51,7 @@
 import java.util.stream.Collectors;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = DeviceConfig.class)
+@DisabledOnRavenwood(blockedBy = DeviceConfig.class)
 public class LatencyTrackerTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java
index e0d5499..bb1c9ed 100644
--- a/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/ProgressReporterTest.java
@@ -18,7 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -29,7 +29,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ProgressReporter.class)
+@DisabledOnRavenwood(blockedBy = ProgressReporter.class)
 public class ProgressReporterTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
index d1fbc77c..e0e24e7 100644
--- a/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/LockPatternUtilsTest.java
@@ -53,7 +53,7 @@
 import android.os.UserManager;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.provider.Settings;
@@ -80,7 +80,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@IgnoreUnderRavenwood(blockedBy = LockPatternUtils.class)
+@DisabledOnRavenwood(blockedBy = LockPatternUtils.class)
 public class LockPatternUtilsTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
index 17fe15c..21ef391 100644
--- a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
+++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java
@@ -28,7 +28,7 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.annotation.EnforcePermission;
 import android.hardware.devicestate.DeviceStateManager.DeviceStateCallback;
@@ -207,7 +207,7 @@
 
         mService.setSupportedStates(List.of(OTHER_DEVICE_STATE));
         mService.setBaseState(OTHER_DEVICE_STATE);
-        verifyZeroInteractions(callback);
+        verifyNoMoreInteractions(callback);
     }
 
     @Test
diff --git a/core/tests/utiltests/src/android/util/AtomicFileTest.java b/core/tests/utiltests/src/android/util/AtomicFileTest.java
index 742307b..8897f0f 100644
--- a/core/tests/utiltests/src/android/util/AtomicFileTest.java
+++ b/core/tests/utiltests/src/android/util/AtomicFileTest.java
@@ -24,7 +24,7 @@
 import static org.mockito.Mockito.spy;
 
 import android.os.SystemClock;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.annotation.NonNull;
@@ -281,7 +281,7 @@
     }
 
     @Test
-    @IgnoreUnderRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class)
+    @DisabledOnRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class)
     public void testTimeLogging() throws Exception {
         var logger = spy(new SystemConfigFileCommitEventLogger("name"));
         var file = new AtomicFile(mBaseFile, logger);
diff --git a/core/tests/utiltests/src/android/util/EventLogTest.java b/core/tests/utiltests/src/android/util/EventLogTest.java
index 0ebf2c1..35803e7 100644
--- a/core/tests/utiltests/src/android/util/EventLogTest.java
+++ b/core/tests/utiltests/src/android/util/EventLogTest.java
@@ -19,7 +19,7 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.EventLog.Event;
 
@@ -51,7 +51,7 @@
     }
 
     @Test
-    @IgnoreUnderRavenwood(reason = "Reading not yet supported")
+    @DisabledOnRavenwood(reason = "Reading not yet supported")
     public void testWithNewData() throws Throwable {
         Event event = createEvent(() -> {
             EventLog.writeEvent(314,  123);
diff --git a/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java b/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java
index 8093af9..1459212 100644
--- a/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java
+++ b/core/tests/utiltests/src/android/util/MemoryIntArrayTest.java
@@ -23,7 +23,7 @@
 import static org.junit.Assert.fail;
 
 import android.os.Parcel;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -39,13 +39,13 @@
 import java.util.concurrent.TimeUnit;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = MemoryIntArray.class)
+@DisabledOnRavenwood(blockedBy = MemoryIntArray.class)
 public class MemoryIntArrayTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
 
     static {
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             System.loadLibrary("cutils");
             System.loadLibrary("memoryintarraytest");
         }
diff --git a/core/tests/utiltests/src/android/util/MetadataReaderTest.java b/core/tests/utiltests/src/android/util/MetadataReaderTest.java
index 14feed8..5981506 100644
--- a/core/tests/utiltests/src/android/util/MetadataReaderTest.java
+++ b/core/tests/utiltests/src/android/util/MetadataReaderTest.java
@@ -20,7 +20,7 @@
 
 import android.media.ExifInterface;
 import android.os.Bundle;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.provider.DocumentsContract;
 import android.provider.MetadataReader;
@@ -41,7 +41,7 @@
 import java.io.InputStream;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = MetadataReader.class)
+@DisabledOnRavenwood(blockedBy = MetadataReader.class)
 public class MetadataReaderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java b/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java
index 3bb79ec..d64de68 100644
--- a/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java
+++ b/core/tests/utiltests/src/android/util/SystemConfigFileCommitEventLoggerTest.java
@@ -21,7 +21,7 @@
 import static org.mockito.Mockito.times;
 
 import android.os.SystemClock;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -32,7 +32,7 @@
 import org.mockito.Mockito;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class)
+@DisabledOnRavenwood(blockedBy = SystemConfigFileCommitEventLogger.class)
 public class SystemConfigFileCommitEventLoggerTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java b/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java
index 9888540..b86c815 100644
--- a/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/CharSequencesTest.java
@@ -21,7 +21,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
@@ -32,7 +32,7 @@
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = CharSequences.class)
+@DisabledOnRavenwood(blockedBy = CharSequences.class)
 public class CharSequencesTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java
index f91172d..259d394 100644
--- a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java
@@ -20,7 +20,7 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.provider.DeviceConfig;
 import android.util.Log;
@@ -145,7 +145,7 @@
 
     @Test
     @LargeTest
-    @IgnoreUnderRavenwood(reason = "Long test runtime")
+    @DisabledOnRavenwood(reason = "Long test runtime")
     public void testAllCharacters() throws Exception {
         boolean ok = true;
         for (int i = 0; i < 0xffff; i++) {
diff --git a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java
index 7203b8c..1af58a3 100644
--- a/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/InlinePresentationStyleUtilsTest.java
@@ -25,7 +25,7 @@
 import android.graphics.Color;
 import android.os.Binder;
 import android.os.Bundle;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
@@ -39,7 +39,7 @@
 
 @RunWith(AndroidJUnit4.class)
 @SmallTest
-@IgnoreUnderRavenwood(blockedBy = InlinePresentationStyleUtils.class)
+@DisabledOnRavenwood(blockedBy = InlinePresentationStyleUtils.class)
 public class InlinePresentationStyleUtilsTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java b/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java
index 6c34797..7e523bb 100644
--- a/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/MimeIconUtilsTest.java
@@ -18,7 +18,7 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -31,7 +31,7 @@
  * Tests for {@link MimeIconUtils}.
  */
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = MimeIconUtils.class)
+@DisabledOnRavenwood(blockedBy = MimeIconUtils.class)
 public class MimeIconUtilsTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java b/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java
index c852e9f..dc353a5 100644
--- a/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/ObservableServiceConnectionTest.java
@@ -29,7 +29,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.IBinder;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
@@ -52,7 +52,7 @@
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ObservableServiceConnection.class)
+@DisabledOnRavenwood(blockedBy = ObservableServiceConnection.class)
 public class ObservableServiceConnectionTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java b/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java
index 096f303..a881873 100644
--- a/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/PersistentServiceConnectionTest.java
@@ -30,7 +30,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.os.IBinder;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.runner.AndroidJUnit4;
@@ -52,7 +52,7 @@
 import java.util.concurrent.Executor;
 
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = PersistentServiceConnection.class)
+@DisabledOnRavenwood(blockedBy = PersistentServiceConnection.class)
 public class PersistentServiceConnectionTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java b/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java
index b0db8a1..c7e0bbd 100644
--- a/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/WakeupMessageTest.java
@@ -24,8 +24,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
-import android.platform.test.ravenwood.RavenwoodRule;
+import android.platform.test.annotations.DisabledOnRavenwood;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -47,7 +46,7 @@
  */
 @SmallTest
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = WakeupMessage.class)
+@DisabledOnRavenwood(blockedBy = WakeupMessage.class)
 public class WakeupMessageTest {
     private static final String TEST_CMD_NAME = "TEST cmd Name";
     private static final int TEST_CMD = 18;
@@ -55,11 +54,6 @@
     private static final int TEST_ARG2 = 182;
     private static final Object TEST_OBJ = "hello";
 
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     @Mock Context mContext;
     @Mock AlarmManager mAlarmManager;
     WakeupMessage mMessage;
diff --git a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java b/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
index 502d6b6..abedc4d 100644
--- a/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
+++ b/core/tests/utiltests/src/com/android/internal/util/test/FakeSettingsProviderTest.java
@@ -20,7 +20,7 @@
 import static org.junit.Assert.fail;
 
 import android.content.ContentProvider;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.provider.Settings;
 import android.test.mock.MockContentResolver;
@@ -37,7 +37,7 @@
  * Unit tests for FakeSettingsProvider.
  */
 @RunWith(AndroidJUnit4.class)
-@IgnoreUnderRavenwood(blockedBy = ContentProvider.class)
+@DisabledOnRavenwood(blockedBy = ContentProvider.class)
 public class FakeSettingsProviderTest {
     @Rule
     public final RavenwoodRule mRavenwood = new RavenwoodRule();
diff --git a/data/etc/preinstalled-packages-platform.xml b/data/etc/preinstalled-packages-platform.xml
index 3b40148..f25ceb1 100644
--- a/data/etc/preinstalled-packages-platform.xml
+++ b/data/etc/preinstalled-packages-platform.xml
@@ -139,4 +139,10 @@
     <install-in-user-type package="com.android.multiuser">
         <install-in user-type="FULL" />
     </install-in-user-type>
+
+    <!-- PrivateSpace App, only install in private profile -->
+    <install-in-user-type package="com.android.privatespace">
+        <install-in user-type="android.os.usertype.profile.PRIVATE" />
+    </install-in-user-type>
+
 </config>
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index cd5a54c..a4ba2b3 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -755,6 +755,9 @@
         if (b != null) {
             b.setPremultiplied(mRequestPremultiplied);
             b.mDensity = mDensity;
+            if (hasGainmap()) {
+                b.setGainmap(getGainmap().asShared());
+            }
         }
         return b;
     }
@@ -767,7 +770,8 @@
      */
     @NonNull
     public Bitmap asShared() {
-        if (nativeIsBackedByAshmem(mNativePtr) && nativeIsImmutable(mNativePtr)) {
+        if (nativeIsBackedByAshmem(mNativePtr) && nativeIsImmutable(mNativePtr)
+                && (!hasGainmap() || getGainmap().asShared() == getGainmap())) {
             return this;
         }
         Bitmap shared = createAshmemBitmap();
@@ -2091,7 +2095,7 @@
      */
     public void setGainmap(@Nullable Gainmap gainmap) {
         checkRecycled("Bitmap is recycled");
-        mGainmap = null;
+        mGainmap = gainmap;
         nativeSetGainmap(mNativePtr, gainmap == null ? 0 : gainmap.mNativePtr);
     }
 
diff --git a/graphics/java/android/graphics/Gainmap.java b/graphics/java/android/graphics/Gainmap.java
index 7fc13db..2417a12 100644
--- a/graphics/java/android/graphics/Gainmap.java
+++ b/graphics/java/android/graphics/Gainmap.java
@@ -161,6 +161,18 @@
     }
 
     /**
+     * @hide
+     */
+    public Gainmap asShared() {
+        final Bitmap sharedContents = mGainmapContents.asShared();
+        if (sharedContents == mGainmapContents) {
+            return this;
+        } else {
+            return new Gainmap(sharedContents, nCreateCopy(mNativePtr));
+        }
+    }
+
+    /**
      * @return Returns the image data of the gainmap represented as a Bitmap. This is represented
      * as a Bitmap for broad API compatibility, however certain aspects of the Bitmap are ignored
      * such as {@link Bitmap#getColorSpace()} or {@link Bitmap#getGainmap()} as they are not
diff --git a/libs/WindowManager/Shell/aconfig/multitasking.aconfig b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
index b6a1501..19455a3 100644
--- a/libs/WindowManager/Shell/aconfig/multitasking.aconfig
+++ b/libs/WindowManager/Shell/aconfig/multitasking.aconfig
@@ -211,3 +211,10 @@
     description: "Makes the split divider snap 'magnetically' to available snap points during drag"
     bug: "383631946"
 }
+
+flag {
+    name: "enable_dynamic_insets_for_app_launch"
+    namespace: "multitasking"
+    description: "Enables dynamic insets for app launch so the window is properly cropped"
+    bug: "336511494"
+}
diff --git a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
index 14c152102..90011f4 100644
--- a/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
+++ b/libs/WindowManager/Shell/multivalentTests/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerViewTest.kt
@@ -24,6 +24,9 @@
 import android.graphics.Rect
 import android.os.Handler
 import android.os.UserManager
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
 import android.view.IWindowManager
 import android.view.MotionEvent
 import android.view.View
@@ -36,6 +39,7 @@
 import com.android.internal.logging.testing.UiEventLoggerFake
 import com.android.internal.protolog.ProtoLog
 import com.android.internal.statusbar.IStatusBarService
+import com.android.wm.shell.Flags
 import com.android.wm.shell.R
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.bubbles.Bubble
@@ -64,6 +68,10 @@
 import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
 import com.android.wm.shell.shared.bubbles.BubbleBarLocation
 import com.android.wm.shell.shared.bubbles.DeviceConfig
+import com.android.wm.shell.shared.bubbles.DragZone
+import com.android.wm.shell.shared.bubbles.DragZoneFactory
+import com.android.wm.shell.shared.bubbles.DragZoneFactory.SplitScreenModeChecker.SplitScreenMode
+import com.android.wm.shell.shared.bubbles.DraggedObject
 import com.android.wm.shell.sysui.ShellCommandHandler
 import com.android.wm.shell.sysui.ShellController
 import com.android.wm.shell.sysui.ShellInit
@@ -88,6 +96,8 @@
         const val SCREEN_HEIGHT = 1000
     }
 
+    @get:Rule val setFlagsRule = SetFlagsRule()
+
     @get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this)
 
     private val context = ApplicationProvider.getApplicationContext<Context>()
@@ -101,6 +111,7 @@
     private lateinit var bgExecutor: TestShellExecutor
     private lateinit var bubbleLogger: BubbleLogger
     private lateinit var testBubblesList: MutableList<Bubble>
+    private lateinit var dragZoneFactory: DragZoneFactory
 
     @Before
     fun setUp() {
@@ -134,6 +145,10 @@
         whenever(bubbleData.bubbles).thenReturn(testBubblesList)
         whenever(bubbleData.hasBubbles()).thenReturn(!testBubblesList.isEmpty())
 
+        dragZoneFactory = DragZoneFactory(context, deviceConfig,
+            { SplitScreenMode.UNSUPPORTED },
+            { false })
+
         bubbleController =
             createBubbleController(
                 bubbleData,
@@ -280,6 +295,7 @@
         assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
     }
 
+    @DisableFlags(Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN, Flags.FLAG_ENABLE_BUBBLE_ANYTHING)
     @Test
     fun testEventLogging_dragExpandedViewLeft() {
         val bubble = createBubble("first")
@@ -287,7 +303,7 @@
 
         getInstrumentation().runOnMainSync {
             bubbleBarLayerView.showExpandedView(bubble)
-            bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true)
+            bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true /* visible */)
         }
         waitForExpandedViewAnimation()
 
@@ -305,6 +321,7 @@
         assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
     }
 
+    @DisableFlags(Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN, Flags.FLAG_ENABLE_BUBBLE_ANYTHING)
     @Test
     fun testEventLogging_dragExpandedViewRight() {
         val bubble = createBubble("first")
@@ -312,7 +329,7 @@
 
         getInstrumentation().runOnMainSync {
             bubbleBarLayerView.showExpandedView(bubble)
-            bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true)
+            bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true /* visible */)
         }
         waitForExpandedViewAnimation()
 
@@ -330,6 +347,76 @@
         assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
     }
 
+    @EnableFlags(Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN, Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE)
+    @Test
+    fun testEventLogging_dragExpandedViewLeft_bubbleAnything() {
+        val bubble = createBubble("first")
+        bubblePositioner.bubbleBarLocation = BubbleBarLocation.RIGHT
+
+        getInstrumentation().runOnMainSync {
+            bubbleBarLayerView.showExpandedView(bubble)
+            bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true /* visible */)
+        }
+        waitForExpandedViewAnimation()
+
+        val handleView = bubbleBarLayerView.findViewById<View>(R.id.bubble_bar_handle_view)
+        assertThat(handleView).isNotNull()
+
+        val dragZones = dragZoneFactory.createSortedDragZones(
+            DraggedObject.ExpandedView(BubbleBarLocation.RIGHT))
+        val rightDragZone = dragZones.filterIsInstance<DragZone.Bubble.Right>().first()
+        val rightPoint = PointF(rightDragZone.bounds.centerX().toFloat(),
+            rightDragZone.bounds.centerY().toFloat())
+        val leftDragZone = dragZones.filterIsInstance<DragZone.Bubble.Left>().first()
+        val leftPoint = PointF(leftDragZone.bounds.centerX().toFloat(),
+            leftDragZone.bounds.centerY().toFloat())
+
+        // Drag from right to left
+        handleView.dispatchTouchEvent(0L, MotionEvent.ACTION_DOWN, rightPoint)
+        handleView.dispatchTouchEvent(10L, MotionEvent.ACTION_MOVE, leftPoint)
+        handleView.dispatchTouchEvent(20L, MotionEvent.ACTION_UP, leftPoint)
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.logs[0].eventId)
+            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_LEFT_DRAG_EXP_VIEW.id)
+        assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
+    }
+
+    @EnableFlags(Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN, Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE)
+    @Test
+    fun testEventLogging_dragExpandedViewRight_bubbleAnything() {
+        val bubble = createBubble("first")
+        bubblePositioner.bubbleBarLocation = BubbleBarLocation.LEFT
+
+        getInstrumentation().runOnMainSync {
+            bubbleBarLayerView.showExpandedView(bubble)
+            bubble.bubbleBarExpandedView!!.onContentVisibilityChanged(true /* visible */)
+        }
+        waitForExpandedViewAnimation()
+
+        val handleView = bubbleBarLayerView.findViewById<View>(R.id.bubble_bar_handle_view)
+        assertThat(handleView).isNotNull()
+
+        val dragZones = dragZoneFactory.createSortedDragZones(
+            DraggedObject.ExpandedView(BubbleBarLocation.LEFT))
+        val rightDragZone = dragZones.filterIsInstance<DragZone.Bubble.Right>().first()
+        val rightPoint = PointF(rightDragZone.bounds.centerX().toFloat(),
+            rightDragZone.bounds.centerY().toFloat())
+        val leftDragZone = dragZones.filterIsInstance<DragZone.Bubble.Left>().first()
+        val leftPoint = PointF(leftDragZone.bounds.centerX().toFloat(),
+            leftDragZone.bounds.centerY().toFloat())
+
+        // Drag from left to right
+        handleView.dispatchTouchEvent(0L, MotionEvent.ACTION_DOWN, leftPoint)
+        handleView.dispatchTouchEvent(10L, MotionEvent.ACTION_MOVE, rightPoint)
+        handleView.dispatchTouchEvent(20L, MotionEvent.ACTION_UP, rightPoint)
+
+        assertThat(uiEventLoggerFake.numLogs()).isEqualTo(1)
+        assertThat(uiEventLoggerFake.logs[0].eventId)
+            .isEqualTo(BubbleLogger.Event.BUBBLE_BAR_MOVED_RIGHT_DRAG_EXP_VIEW.id)
+        assertThat(uiEventLoggerFake.logs[0]).hasBubbleInfo(bubble)
+    }
+
     @Test
     fun testUpdateExpandedView_updateLocation() {
         bubblePositioner.bubbleBarLocation = BubbleBarLocation.RIGHT
@@ -385,7 +472,7 @@
                 bubbleLogger,
             )
         // Mark visible so we don't wait for task view before animations can start
-        bubbleBarExpandedView.onContentVisibilityChanged(true)
+        bubbleBarExpandedView.onContentVisibilityChanged(true /* visible */)
 
         val viewInfo = FakeBubbleFactory.createViewInfo(bubbleBarExpandedView)
         return FakeBubbleFactory.createChatBubble(context, key, viewInfo).also {
diff --git a/libs/WindowManager/Shell/res/drawable/bubble_ic_settings.xml b/libs/WindowManager/Shell/res/drawable/bubble_ic_settings.xml
new file mode 100644
index 0000000..52b9ac2
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/bubble_ic_settings.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="20dp"
+    android:height="20dp"
+    android:viewportWidth="960"
+    android:viewportHeight="960"
+    android:tint="?attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M433,880Q406,880 386.5,862Q367,844 363,818L354,752Q341,747 329.5,740Q318,733 307,725L245,751Q220,762 195,753Q170,744 156,721L109,639Q95,616 101,590Q107,564 128,547L181,507Q180,500 180,493.5Q180,487 180,480Q180,473 180,466.5Q180,460 181,453L128,413Q107,396 101,370Q95,344 109,321L156,239Q170,216 195,207Q220,198 245,209L307,235Q318,227 330,220Q342,213 354,208L363,142Q367,116 386.5,98Q406,80 433,80L527,80Q554,80 573.5,98Q593,116 597,142L606,208Q619,213 630.5,220Q642,227 653,235L715,209Q740,198 765,207Q790,216 804,239L851,321Q865,344 859,370Q853,396 832,413L779,453Q780,460 780,466.5Q780,473 780,480Q780,487 780,493.5Q780,500 778,507L831,547Q852,564 858,590Q864,616 850,639L802,721Q788,744 763,753Q738,762 713,751L653,725Q642,733 630,740Q618,747 606,752L597,818Q593,844 573.5,862Q554,880 527,880L433,880ZM482,620Q540,620 581,579Q622,538 622,480Q622,422 581,381Q540,340 482,340Q423,340 382.5,381Q342,422 342,480Q342,538 382.5,579Q423,620 482,620Z"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
index fc8b2991..ef30d89 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_manage_education.xml
@@ -31,9 +31,10 @@
         android:layout_height="@dimen/bubble_popup_icon_size"
         android:tint="@androidprv:color/materialColorOutline"
         android:contentDescription="@null"
-        android:src="@drawable/pip_ic_settings"/>
+        android:src="@drawable/bubble_ic_settings"/>
 
     <TextView
+        android:id="@+id/education_manage_title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="@dimen/bubble_popup_text_margin"
@@ -45,6 +46,7 @@
         android:text="@string/bubble_bar_education_manage_title"/>
 
     <TextView
+        android:id="@+id/education_manage_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="@dimen/bubble_popup_text_margin"
diff --git a/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml b/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
index 1616707..9076d6a 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_bar_stack_education.xml
@@ -34,6 +34,7 @@
         android:src="@drawable/ic_floating_landscape"/>
 
     <TextView
+        android:id="@+id/education_title"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="@dimen/bubble_popup_text_margin"
@@ -45,6 +46,7 @@
         android:text="@string/bubble_bar_education_stack_title"/>
 
     <TextView
+        android:id="@+id/education_text"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_marginTop="@dimen/bubble_popup_text_margin"
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
index 4daaf9c..17ebac9 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
@@ -40,6 +40,7 @@
             android:tint="@color/bubbles_icon_tint"/>
 
         <TextView
+            android:id="@+id/manage_dismiss"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
@@ -67,6 +68,7 @@
             android:tint="@color/bubbles_icon_tint"/>
 
         <TextView
+            android:id="@+id/manage_dont_bubble"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginStart="16dp"
@@ -103,4 +105,35 @@
 
     </LinearLayout>
 
+    <!-- Menu option to move a bubble to fullscreen; only visible if bubble anything is enabled. -->
+    <LinearLayout
+        android:id="@+id/bubble_manage_menu_fullscreen_container"
+        android:background="@drawable/bubble_manage_menu_row"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:visibility="gone"
+        android:minHeight="@dimen/bubble_menu_item_height"
+        android:gravity="center_vertical"
+        android:paddingStart="@dimen/bubble_menu_padding"
+        android:paddingEnd="@dimen/bubble_menu_padding"
+        android:orientation="horizontal">
+
+        <ImageView
+            android:id="@+id/bubble_manage_menu_fullscreen_icon"
+            android:layout_width="@dimen/bubble_menu_icon_size"
+            android:layout_height="@dimen/bubble_menu_icon_size"
+            android:src="@drawable/desktop_mode_ic_handle_menu_fullscreen"
+            android:tint="@color/bubbles_icon_tint"/>
+
+        <TextView
+            android:id="@+id/bubble_manage_menu_fullscreen_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="16dp"
+            android:text="@string/bubble_fullscreen_text"
+            android:textColor="@androidprv:color/materialColorOnSurface"
+            android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
+
+    </LinearLayout>
+
 </LinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
index ed8b543..bfaa407 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu.xml
@@ -43,8 +43,7 @@
             android:layout_height="@dimen/desktop_mode_handle_menu_icon_radius"
             android:layout_marginStart="10dp"
             android:layout_marginEnd="12dp"
-            android:contentDescription="@string/app_icon_text"
-            android:importantForAccessibility="no"/>
+            android:contentDescription="@string/app_icon_text" />
 
         <com.android.wm.shell.windowdecor.MarqueedTextView
             android:id="@+id/application_name"
@@ -142,7 +141,6 @@
             android:contentDescription="@string/screenshot_text"
             android:text="@string/screenshot_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_screenshot"
-            android:importantForAccessibility="no"
             style="@style/DesktopModeHandleMenuActionButton"/>
 
         <com.android.wm.shell.windowdecor.HandleMenuActionButton
@@ -150,7 +148,6 @@
             android:contentDescription="@string/new_window_text"
             android:text="@string/new_window_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_new_window"
-            android:importantForAccessibility="no"
             style="@style/DesktopModeHandleMenuActionButton"/>
 
         <com.android.wm.shell.windowdecor.HandleMenuActionButton
@@ -158,7 +155,6 @@
             android:contentDescription="@string/manage_windows_text"
             android:text="@string/manage_windows_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_manage_windows"
-            android:importantForAccessibility="no"
             style="@style/DesktopModeHandleMenuActionButton"/>
 
         <com.android.wm.shell.windowdecor.HandleMenuActionButton
@@ -166,7 +162,6 @@
             android:contentDescription="@string/change_aspect_ratio_text"
             android:text="@string/change_aspect_ratio_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_change_aspect_ratio"
-            android:importantForAccessibility="no"
             style="@style/DesktopModeHandleMenuActionButton"/>
     </LinearLayout>
 
@@ -186,7 +181,6 @@
             android:text="@string/open_in_browser_text"
             android:src="@drawable/desktop_mode_ic_handle_menu_open_in_browser"
             style="@style/DesktopModeHandleMenuActionButton"
-            android:importantForAccessibility="no"
             android:layout_width="0dp"
             android:layout_weight="1"/>
 
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml
index de38e6f..35e7de0 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor_handle_menu_action_button.xml
@@ -22,8 +22,7 @@
     android:layout_height="match_parent"
     android:gravity="start|center_vertical"
     android:paddingHorizontal="16dp"
-    android:clickable="true"
-    android:focusable="true"
+    android:importantForAccessibility="yes"
     android:orientation="horizontal"
     android:background="?android:attr/selectableItemBackground">
 
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 1491c70..05c4c56 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nie opgelos nie?\nTik om terug te stel"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen kamerakwessies nie? Tik om toe te maak."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Die appkieslys kan hier gevind word"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Maak werkskermvensters oop om verskeie apps terselfdertyd oop te maak"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Keer enige tyd terug na volskerm vanaf die appkieslys"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Sien en doen meer"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Sleep ’n ander app in vir verdeelde skerm"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Apphandvatsel"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Appikoon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Volskerm"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Werkskermvensters"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Verdeelde skerm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Meer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Sweef"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Verander aspekverhouding"</string>
     <string name="close_text" msgid="4986518933445178928">"Maak toe"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Maak kieslys toe"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (werkskermvensters)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimeer skerm"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Verander grootte"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App kan nie hierheen geskuif word nie"</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 8bd602c..450419d 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"አልተስተካከለም?\nለማህደር መታ ያድርጉ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ምንም የካሜራ ችግሮች የሉም? ለማሰናበት መታ ያድርጉ።"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"የመተግበሪያ ምናሌው እዚህ መገኘት ይችላል"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"በርካታ መተግበሪያዎችን በአንድ ላይ ለመክፈት ወደ የዴስክቶፕ መስኮት ይግቡ"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"በማንኛውም ጊዜ ከመተግበሪያ ምናሌው ላይ ወደ ሙሉ ገጽ እይታ ይመለሱ"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ተጨማሪ ይመልከቱ እና ያድርጉ"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ለተከፈለ ማያ ገፅ ሌላ መተግበሪያ ይጎትቱ"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"የመተግበሪያ መያዣ"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"የመተግበሪያ አዶ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ሙሉ ማያ"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ዴስክቶፕ መስኮት"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"የተከፈለ ማያ ገፅ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ተጨማሪ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ተንሳፋፊ"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ምጥጥነ ገፅታ ለውጥ"</string>
     <string name="close_text" msgid="4986518933445178928">"ዝጋ"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"ምናሌ ዝጋ"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ዴስክቶፕ መስኮት)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"የማያ ገጹ መጠን አሳድግ"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"መጠን ቀይር"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"መተግበሪያ ወደዚህ መንቀሳቀስ አይችልም"</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 6872df6..b1826db 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"এইটো সমাধান কৰা নাই নেকি?\nপূৰ্বাৱস্থালৈ নিবলৈ টিপক"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"কেমেৰাৰ কোনো সমস্যা নাই নেকি? অগ্ৰাহ্য কৰিবলৈ টিপক।"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"এপৰ মেনু ইয়াত বিচাৰি পোৱা যাব"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"একেলগে একাধিক এপ্‌ খুলিবলৈ ডেস্কটপ ৱিণ্ড’ৱিঙলৈ যাওক"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"এপৰ মেনুৰ পৰা যিকোনো সময়তে পূৰ্ণ স্ক্ৰীনলৈ উভতি যাওক"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"চাওক আৰু অধিক কৰক"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"বিভাজিত স্ক্ৰীনৰ বাবে অন্য এটা এপ্‌ টানি আনি এৰক"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"এপৰ হেণ্ডেল"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"এপৰ চিহ্ন"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"সম্পূৰ্ণ স্ক্ৰীন"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ডেস্কটপ ৱিণ্ড’ৱিং"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"বিভাজিত স্ক্ৰীন"</string>
     <string name="more_button_text" msgid="3655388105592893530">"অধিক"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ওপঙা"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"আকাৰৰ অনুপাত সলনি কৰক"</string>
     <string name="close_text" msgid="4986518933445178928">"বন্ধ কৰক"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"মেনু বন্ধ কৰক"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ডেস্কটপ ৱিণ্ড’ৱিং)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"স্ক্ৰীন মেক্সিমাইজ কৰক"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"আকাৰ সলনি কৰক"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ইয়ালৈ এপ্‌টো আনিব নোৱাৰি"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 4630941..c5493b5 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Düzəltməmisiniz?\nGeri qaytarmaq üçün toxunun"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera problemi yoxdur? Qapatmaq üçün toxunun."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Tətbiq menyusunu burada tapa bilərsiniz"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Bir neçə tətbiqi birlikdə açmaq üçün masaüstü pəncərə rejiminə daxil olun"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"İstənilən vaxt tətbiq menyusundan tam ekrana qayıdın"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Ardını görün və edin"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Bölünmüş ekran üçün başqa tətbiq sürüşdürün"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Tətbiq ləqəbi"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Tətbiq ikonası"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Masaüstü pəncərə rejimi"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Ardı"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Üzən pəncərə"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tərəflər nisbətini dəyişin"</string>
     <string name="close_text" msgid="4986518933445178928">"Bağlayın"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menyunu bağlayın"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Masaüstü pəncərə rejimi)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı maksimum böyüdün"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ölçüsünü dəyişin"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Tətbiqi bura köçürmək mümkün deyil"</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 4af5648..307c47a 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije rešen?\nDodirnite da biste vratili"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema sa kamerom? Dodirnite da biste odbacili."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Meni aplikacije možete da pronađete ovde"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Uđite u prozorski prikaz za računare da biste istovremeno otvorili više aplikacija"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Vratite se na ceo ekran bilo kada iz menija aplikacije"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vidite i uradite više"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Prevucite drugu aplikaciju da biste koristili podeljeni ekran"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Preko celog ekrana"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Prozorski prikaz za računare"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Podeljeni ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Još"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Plutajuće"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promeni razmeru"</string>
     <string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite meni"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prozorski prikaz za računare)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Povećaj ekran"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Prilagodi"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija ne može da se premesti ovde"</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index 7719396..c53e37c 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не ўдалося выправіць?\nНацісніце, каб аднавіць"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ніякіх праблем з камерай? Націсніце, каб адхіліць."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Меню праграмы шукайце тут"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Каб адкрыць некалькі праграм адначасова, увайдзіце ў рэжым вокнаў працоўнага стала"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Вы можаце вярнуцца ў поўнаэкранны рэжым у любы час з меню праграмы"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Адначасова выконвайце розныя задачы"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Перацягніце іншую праграму, каб выкарыстоўваць падзелены экран"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Маркер праграмы"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Значок праграмы"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"На ўвесь экран"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Рэжым вокнаў працоўнага стала"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Падзяліць экран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Яшчэ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Зрабіць рухомым акном"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Змяніць суадносіны бакоў"</string>
     <string name="close_text" msgid="4986518933445178928">"Закрыць"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Закрыць меню"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (рэжым вокнаў працоўнага стала)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Разгарнуць на ўвесь экран"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Змяніць памер"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Нельга перамясціць сюды праграму"</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 514556e..29af2ed 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблемът не се отстрани?\nДокоснете за връщане в предишното състояние"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нямате проблеми с камерата? Докоснете, за да отхвърлите."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Можете да намерите менюто на приложението тук"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Активирайте режима за настолни компютри, за да отворите няколко приложения едновременно"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Преминете към цял екран по всяко време от менюто на приложението"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Преглеждайте и правете повече неща"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Преместете друго приложение с плъзгане, за да преминете в режим за разделен екран"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Манипулатор за приложението"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Икона на приложението"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Цял екран"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Режим за настолни компютри"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Разделяне на екрана"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Още"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Плаващо"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промяна на съотношението"</string>
     <string name="close_text" msgid="4986518933445178928">"Затваряне"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Затваряне на менюто"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим за настолни компютри)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Увеличаване на екрана"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Нов размер"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложението не може да бъде преместено тук"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 23c467c..537afdc 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nije popravljeno?\nDodirnite da vratite"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nema problema s kamerom? Dodirnite da odbacite."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Ovdje možete pronaći meni aplikacije"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Otvorite prikaz u prozorima na računalu da biste otvorili više aplikacija zajedno"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Povratak na prikaz preko cijelog ekrana bilo kada putem menija aplikacije"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Pogledajte i učinite više"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Prevucite još jednu aplikaciju za podijeljeni ekran"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Ručica aplikacije"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Cijeli ekran"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Prikaz u prozorima na računalu"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Podijeljeni ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Više"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Lebdeći"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promjena formata slike"</string>
     <string name="close_text" msgid="4986518933445178928">"Zatvaranje"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvaranje menija"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz u prozorima na računalu)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiziraj ekran"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promijeni veličinu"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ne možete premjestiti aplikaciju ovdje"</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index 893d16e..42b07ef 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"El problema no s\'ha resolt?\nToca per desfer els canvis"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No tens cap problema amb la càmera? Toca per ignorar."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Pots trobar el menú de l\'aplicació aquí"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Accedeix a l\'enfinestrament d\'escriptori per obrir diverses aplicacions alhora"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Torna a la pantalla completa en qualsevol moment des del menú de l\'aplicació"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Consulta i fes més coses"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arrossega una altra aplicació per utilitzar la pantalla dividida"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Identificador de l\'aplicació"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Icona de l\'aplicació"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Enfinestrament d\'escriptori"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Més"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flotant"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Canvia la relació d\'aspecte"</string>
     <string name="close_text" msgid="4986518933445178928">"Tanca"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Tanca el menú"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (enfinestrament d\'escriptori)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximitza la pantalla"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Canvia la mida"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"L\'aplicació no es pot moure aquí"</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index a96344a..4454868 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepomohlo to?\nKlepnutím se vrátíte"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Žádné problémy s fotoaparátem? Klepnutím zavřete."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Najdete tu nabídku aplikace"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Pokud chcete otevřít několik aplikací současně, přejděte do režimu s okny na ploše"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Na celou obrazovku se můžete kdykoli vrátit z nabídky aplikace"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lepší zobrazení a více možností"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Přetáhnutím druhé aplikace použijete rozdělenou obrazovku"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Popisovač aplikace"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikace"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Okna na ploše"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Rozdělená obrazovka"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Více"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Plovoucí"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Změnit poměr stran"</string>
     <string name="close_text" msgid="4986518933445178928">"Zavřít"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zavřít nabídku"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (okna na ploše)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovat obrazovku"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Změnit velikost"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikaci sem nelze přesunout"</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index 7d28fc8..4d14f93 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Løste det ikke problemet?\nTryk for at fortryde"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen problemer med dit kamera? Tryk for at afvise."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Appmenuen kan findes her"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Brug vinduer på skrivebordet for at åbne flere apps på én gang"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Gå tilbage til fuld skærm når som helst via appmenuen"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se og gør mere"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Træk en anden app hertil for at bruge opdelt skærm"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Apphåndtag"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Fuld skærm"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Vinduer på skrivebordet"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Opdelt skærm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mere"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Svævende"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Skift billedformat"</string>
     <string name="close_text" msgid="4986518933445178928">"Luk"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Luk menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (vinduer på skrivebordet)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimér skærm"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Tilpas størrelse"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apps kan ikke flyttes hertil"</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 4cc1124..82bbfc4 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Das Problem ist nicht behoben?\nZum Rückgängigmachen tippen."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Keine Probleme mit der Kamera? Zum Schließen tippen."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Das App-Menü findest du hier"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Über ein Desktop-Freiform-Fenster kannst du mehrere Apps gleichzeitig öffnen"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Über das App-Menü kannst du jederzeit zum Vollbildmodus zurückkehren"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Mehr sehen und erledigen"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Für Splitscreen-Modus weitere App hineinziehen"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"App-Ziehpunkt"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"App-Symbol"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Vollbild"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Desktop-Freiform-Fenster"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Splitscreen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mehr"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Frei schwebend"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Seitenverhältnis ändern"</string>
     <string name="close_text" msgid="4986518933445178928">"Schließen"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menü schließen"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop-Freiform-Fenster)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Bildschirm maximieren"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Größe ändern"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Die App kann nicht hierher verschoben werden"</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 0fb17ec..a8696af 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Δεν διορθώθηκε;\nΠατήστε για επαναφορά."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Δεν αντιμετωπίζετε προβλήματα με την κάμερα; Πατήστε για παράβλεψη."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Μπορείτε να βρείτε το μενού εφαρμογών εδώ"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Μεταβείτε στην προσαρμογή σε παράθυρο στην επιφάνεια εργασίας, για να ανοίξετε πολλές εφαρμογές μαζί"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Επιστρέψτε στην πλήρη οθόνη ανά πάσα στιγμή από το μενού της εφαρμογής"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Δείτε και κάντε περισσότερα"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Σύρετε σε μια άλλη εφαρμογή για διαχωρισμό οθόνης."</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Λαβή εφαρμογής"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Εικονίδιο εφαρμογής"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Πλήρης οθόνη"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Προσαρμογή σε παράθυρο στην επιφάνεια εργασίας"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Διαχωρισμός οθόνης"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Περισσότερα"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Κινούμενο"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Αλλαγή λόγου διαστάσεων"</string>
     <string name="close_text" msgid="4986518933445178928">"Κλείσιμο"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Κλείσιμο μενού"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Προσαρμογή σε παράθυρο στην επιφάνεια εργασίας)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Μεγιστοποίηση οθόνης"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Αλλαγή μεγέθους"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Δεν είναι δυνατή η μετακίνηση της εφαρμογής εδώ"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index 2087bb4..61b68a2 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"The app menu can be found here"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Enter desktop windowing to open multiple apps together"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Return to full screen at any time from the app menu"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Drag in another app for split screen"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"App handle"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"More"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
     <string name="close_text" msgid="4986518933445178928">"Close"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index 8abb9df..0802f83 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"The app menu can be found here"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Enter desktop windowing to open multiple apps together"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Return to full screen anytime from the app menu"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Drag in another app for split screen"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"App handle"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"App Icon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"More"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
     <string name="close_text" msgid="4986518933445178928">"Close"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Close Menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximize Screen"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index 2087bb4..61b68a2 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"The app menu can be found here"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Enter desktop windowing to open multiple apps together"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Return to full screen at any time from the app menu"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Drag in another app for split screen"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"App handle"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"More"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
     <string name="close_text" msgid="4986518933445178928">"Close"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index 2087bb4..61b68a2 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Didn’t fix it?\nTap to revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"No camera issues? Tap to dismiss."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"The app menu can be found here"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Enter desktop windowing to open multiple apps together"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Return to full screen at any time from the app menu"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"See and do more"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Drag in another app for split screen"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"App handle"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"App icon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Full screen"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"More"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Change aspect ratio"</string>
     <string name="close_text" msgid="4986518933445178928">"Close"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Close menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktop windowing)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximise screen"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Resize"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"App can\'t be moved here"</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 3608657..c0e4eb3 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Kas probleemi ei lahendatud?\nPuudutage ennistamiseks."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kas kaameraprobleeme pole? Puudutage loobumiseks."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Rakenduse menüü leiate siit"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Mitme rakenduse koos avamiseks kasutage töölaua aknaid"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Saate rakenduse menüüst igal ajal täisekraanile naasta"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vaadake ja tehke rohkem"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Lohistage muusse rakendusse, et jagatud ekraanikuva kasutada"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Rakenduse element"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Rakenduse ikoon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Täisekraan"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Töölaua aknad"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Jagatud ekraanikuva"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Rohkem"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Hõljuv"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Kuvasuhte muutmine"</string>
     <string name="close_text" msgid="4986518933445178928">"Sule"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Sule menüü"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (töölaua aknad)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Kuva täisekraanil"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Suuruse muutmine"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Rakendust ei saa siia teisaldada"</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index bf5c8f9..4879965 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"مشکل برطرف نشد؟\nبرای برگرداندن تک‌ضرب بزنید"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"دوربین مشکلی ندارد؟ برای بستن تک‌ضرب بزنید."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"منو برنامه را می‌توانید اینجا ببینید"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"برای باز کردن هم‌زمان چند برنامه، وارد پردازش پنجره‌ای رایانه شوید"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"هروقت خواستید از منو برنامه به حالت تمام‌صفحه برگردید"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"از چندین برنامه به‌طور هم‌زمان استفاده کنید"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"برای حالت صفحهٔ دونیمه، در برنامه‌ای دیگر بکشید"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"دستگیره برنامه"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"نماد برنامه"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"تمام‌صفحه"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"پردازش پنجره‌ای رایانه"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"صفحهٔ دونیمه"</string>
     <string name="more_button_text" msgid="3655388105592893530">"بیشتر"</string>
     <string name="float_button_text" msgid="9221657008391364581">"شناور"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"تغییر نسبت ابعادی"</string>
     <string name="close_text" msgid="4986518933445178928">"بستن"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"بستن منو"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (پردازش پنجره‌ای رایانه)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"بزرگ کردن صفحه"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"تغییر اندازه"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"برنامه را نمی‌توان به اینجا منتقل کرد"</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index a32e4fa..8fd6b1b 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Eikö ongelma ratkennut?\nKumoa napauttamalla"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ei ongelmia kameran kanssa? Hylkää napauttamalla."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Sovellusvalikko löytyy täältä"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Siirry työpöydän ikkunointiin, niin voit avata useita sovelluksia kerralla"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Voit palata koko näytön tilaan milloin tahansa sovellusvalikosta"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Näe ja tee enemmän"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Käytä jaettua näyttöä vetämällä tähän toinen sovellus"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Sovelluksen tunnus"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Sovelluskuvake"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Koko näyttö"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Työpöydän ikkunointi"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Jaettu näyttö"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Lisää"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Kelluva ikkuna"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Vaihda kuvasuhdetta"</string>
     <string name="close_text" msgid="4986518933445178928">"Sulje"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Sulje valikko"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (työpöydän ikkunointi)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Suurenna näyttö"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Muuta kokoa"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Sovellusta ei voi siirtää tänne"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index 7037377..b729ece 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu?\nTouchez pour rétablir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo? Touchez pour ignorer."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Le menu de l\'appli se trouve ici"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Accéder au fenêtrage du bureau pour ouvrir plusieurs applis simultanément"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Revenir au mode Plein écran à tout moment à partir du menu de l\'appli"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Voir et en faire plus"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Faites glisser une autre appli pour utiliser l\'écran partagé"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Icône de l\'appli"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Fenêtrage du bureau"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Écran divisé"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Plus"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flottant"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier les proportions"</string>
     <string name="close_text" msgid="4986518933445178928">"Fermer"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fenêtrage du bureau)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Agrandir l\'écran"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionner"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index fb2ebfd..ed87a13 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problème non résolu ?\nAppuyez pour rétablir"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Aucun problème d\'appareil photo ? Appuyez pour ignorer."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Le menu de l\'application se trouve ici"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Utiliser le fenêtrage de bureau pour ouvrir plusieurs applications simultanément"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Revenir en plein écran à tout moment depuis le menu de l\'application"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Voir et interagir plus"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Faites glisser une autre appli pour utiliser l\'écran partagé"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Poignée de l\'appli"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Icône d\'application"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Plein écran"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Fenêtrage de bureau"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Écran partagé"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Plus"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flottante"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Modifier le format"</string>
     <string name="close_text" msgid="4986518933445178928">"Fermer"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Fermer le menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fenêtrage de bureau)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mettre en plein écran"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionner"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossible de déplacer l\'appli ici"</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 895cf47..a2b87112 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Non se solucionaron os problemas?\nToca para reverter o seu tratamento"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Non hai problemas coa cámara? Tocar para ignorar."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Aquí podes ver o menú da aplicación"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Vai ao escritorio baseado en ventás se queres abrir varias aplicacións á vez"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Volve á pantalla completa en calquera momento desde o menú da aplicación"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Ver e facer máis"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arrastra outra aplicación para usar a pantalla dividida"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Controlador da aplicación"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Icona de aplicación"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pantalla completa"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Escritorio baseado en ventás"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Pantalla dividida"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Máis"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flotante"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambiar a proporción"</string>
     <string name="close_text" msgid="4986518933445178928">"Pechar"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Pechar o menú"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (escritorio baseado en ventás)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar pantalla"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Cambiar tamaño"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Non se pode mover aquí a aplicación"</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index 9c8cf96..ddef9e1 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -43,10 +43,8 @@
     <string name="accessibility_action_divider_left_50" msgid="3488317024557521561">"ડાબે 50%"</string>
     <string name="accessibility_action_divider_left_30" msgid="6023611335723838727">"ડાબે 30%"</string>
     <string name="accessibility_action_divider_right_full" msgid="3408505054325944903">"જમણી સ્ક્રીન સ્ક્રીન"</string>
-    <!-- no translation found for accessibility_action_divider_swap_vertical (3644891227133372072) -->
-    <skip />
-    <!-- no translation found for accessibility_action_divider_swap_horizontal (2722197605446631628) -->
-    <skip />
+    <string name="accessibility_action_divider_swap_vertical" msgid="3644891227133372072">"એકદમ ઉપરની ઍપને એકદમ નીચેની સાથે સ્વૉપ કરો"</string>
+    <string name="accessibility_action_divider_swap_horizontal" msgid="2722197605446631628">"ડાબી ઍપને જમણી સાથે સ્વૉપ કરો"</string>
     <string name="accessibility_action_divider_top_full" msgid="3495871951082107594">"શીર્ષ પૂર્ણ સ્ક્રીન"</string>
     <string name="accessibility_action_divider_top_70" msgid="1779164068887875474">"શીર્ષ 70%"</string>
     <string name="accessibility_action_divider_top_50" msgid="8649582798829048946">"શીર્ષ 50%"</string>
@@ -102,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"સુધારો નથી થયો?\nપહેલાંના પર પાછું ફેરવવા માટે ટૅપ કરો"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"કૅમેરામાં કોઈ સમસ્યા નથી? છોડી દેવા માટે ટૅપ કરો."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ઍપ મેનૂ અહીં જોવા મળી શકે છે"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"એકથી વધુ ઍપ એકસાથે ખોલવા માટે ડેસ્કટૉપ વિન્ડોઇંગ દાખલ કરો"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ઍપ મેનૂમાંથી કોઈપણ સમયે પૂર્ણ સ્ક્રીન પર પાછા ફરો"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"જુઓ અને બીજું ઘણું કરો"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"વિભાજિત સ્ક્રીન માટે કોઈ અન્ય ઍપમાં ખેંચો"</string>
@@ -116,20 +113,15 @@
     <string name="letterbox_restart_restart" msgid="8529976234412442973">"ફરી શરૂ કરો"</string>
     <string name="letterbox_restart_dialog_checkbox_title" msgid="5252918008140768386">"ફરીથી બતાવશો નહીં"</string>
     <string name="letterbox_reachability_reposition_text" msgid="3522042240665748268">"આ ઍપને ખસેડવા માટે\nબે વાર ટૅપ કરો"</string>
-    <!-- no translation found for maximize_button_text (8106849394538234709) -->
-    <skip />
-    <!-- no translation found for restore_button_text (5377571986086775288) -->
-    <skip />
-    <!-- no translation found for minimize_button_text (5213953162664451152) -->
-    <skip />
-    <!-- no translation found for close_button_text (4544839489310949894) -->
-    <skip />
+    <string name="maximize_button_text" msgid="8106849394538234709">"<xliff:g id="APP_NAME">%1$s</xliff:g>નું કદ મહત્તમ કરો"</string>
+    <string name="restore_button_text" msgid="5377571986086775288">"<xliff:g id="APP_NAME">%1$s</xliff:g>ને રિસ્ટોર કરો"</string>
+    <string name="minimize_button_text" msgid="5213953162664451152">"<xliff:g id="APP_NAME">%1$s</xliff:g>નું કદ ન્યૂનતમ કરો"</string>
+    <string name="close_button_text" msgid="4544839489310949894">"<xliff:g id="APP_NAME">%1$s</xliff:g> બંધ કરો"</string>
     <string name="back_button_text" msgid="1469718707134137085">"પાછળ"</string>
     <string name="handle_text" msgid="4419667835599523257">"ઍપનું હૅન્ડલ"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"ઍપનું આઇકન"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"પૂર્ણસ્ક્રીન"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ડેસ્કટૉપ વિન્ડોઇંગ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"સ્ક્રીનને વિભાજિત કરો"</string>
     <string name="more_button_text" msgid="3655388105592893530">"વધુ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ફ્લોટિંગ વિન્ડો"</string>
@@ -142,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"સાપેક્ષ ગુણોત્તર બદલો"</string>
     <string name="close_text" msgid="4986518933445178928">"બંધ કરો"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"મેનૂ બંધ કરો"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ડેસ્કટૉપ વિન્ડોઇંગ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"સ્ક્રીન કરો મોટી કરો"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"કદ બદલો"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ઍપ અહીં ખસેડી શકાતી નથી"</string>
@@ -161,14 +152,10 @@
     <string name="maximize_menu_talkback_action_snap_left_text" msgid="500309467459084564">"ડાબી બાજુ વિન્ડોનું કદ બદલો"</string>
     <string name="maximize_menu_talkback_action_snap_right_text" msgid="7010831426654467163">"જમણી બાજુ વિન્ડોનું કદ બદલો"</string>
     <string name="maximize_menu_talkback_action_maximize_restore_text" msgid="4942610897847934859">"વિન્ડોનું કદ મહત્તમ કરો અથવા રિસ્ટોર કરો"</string>
-    <!-- no translation found for app_header_talkback_action_maximize_button_text (8776156791095878638) -->
-    <skip />
-    <!-- no translation found for app_header_talkback_action_restore_button_text (2153022340772980863) -->
-    <skip />
-    <!-- no translation found for app_header_talkback_action_minimize_button_text (7491054416186901764) -->
-    <skip />
-    <!-- no translation found for app_header_talkback_action_close_button_text (5159612596378268926) -->
-    <skip />
+    <string name="app_header_talkback_action_maximize_button_text" msgid="8776156791095878638">"ઍપની વિન્ડોનું કદ મહત્તમ કરો"</string>
+    <string name="app_header_talkback_action_restore_button_text" msgid="2153022340772980863">"વિન્ડોનું કદ રિસ્ટોર કરો"</string>
+    <string name="app_header_talkback_action_minimize_button_text" msgid="7491054416186901764">"ઍપની વિન્ડોનું કદ ન્યૂનતમ કરો"</string>
+    <string name="app_header_talkback_action_close_button_text" msgid="5159612596378268926">"ઍપની વિન્ડો બંધ કરો"</string>
     <string name="open_by_default_settings_text" msgid="2526548548598185500">"\'ડિફૉલ્ટ તરીકે ખોલો\' સેટિંગ"</string>
     <string name="open_by_default_dialog_subheader_text" msgid="1729599730664063881">"આ ઍપ માટે વેબ લિંક ખોલવાની રીત પસંદ કરો"</string>
     <string name="open_by_default_dialog_in_app_text" msgid="6978022419634199806">"ઍપમાં"</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index 985daff..bbe43a1 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"क्या समस्या ठीक नहीं हुई?\nपहले जैसा करने के लिए टैप करें"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्या कैमरे से जुड़ी कोई समस्या नहीं है? खारिज करने के लिए टैप करें."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ऐप्लिकेशन मेन्यू यहां पाया जा सकता है"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"एक साथ कई ऐप्लिकेशन खोलने के लिए, डेस्कटॉप विंडोविंग का इस्तेमाल करें"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ऐप्लिकेशन मेन्यू से फ़ुल स्क्रीन मोड पर किसी भी समय वापस जाएं"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"पूरी जानकारी लेकर, बेहतर तरीके से काम करें"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"स्प्लिट स्क्रीन का इस्तेमाल करने के लिए, किसी अन्य ऐप्लिकेशन को खींचें और छोड़ें"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"ऐप्लिकेशन का हैंडल"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"ऐप्लिकेशन आइकॉन"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"फ़ुलस्क्रीन"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"डेस्कटॉप विंडोविंग"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन मोड"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ज़्यादा देखें"</string>
     <string name="float_button_text" msgid="9221657008391364581">"फ़्लोट"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"आसपेक्ट रेशियो (लंबाई-चौड़ाई का अनुपात) बदलें"</string>
     <string name="close_text" msgid="4986518933445178928">"बंद करें"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"मेन्यू बंद करें"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटॉप विंडोविंग)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन को बड़ा करें"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"साइज़ बदलें"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ऐप्लिकेशन को यहां मूव नहीं किया जा सकता"</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 4640bf3..80ee561 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Problem nije riješen?\nDodirnite za vraćanje"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemate problema s fotoaparatom? Dodirnite za odbacivanje."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Izbornik aplikacije možete pronaći ovdje"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Otvorite prikaz u prozorima na računalu da biste otvorili više aplikacija zajedno"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Vratite se na cijeli zaslon bilo kad iz izbornika aplikacije"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Gledajte i učinite više"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Povucite drugu aplikaciju unutra da biste podijelili zaslon"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Pokazivač aplikacije"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Puni zaslon"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Prikaz u prozorima na računalu"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Razdvojeni zaslon"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Više"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Plutajući"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Promijeni omjer slike"</string>
     <string name="close_text" msgid="4986518933445178928">"Zatvorite"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zatvorite izbornik"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (prikaz u prozorima na računalu)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimalno povećaj zaslon"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Promijeni veličinu"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacija se ne može premjestiti ovdje"</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index 711e2f0..d24e4da 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nem sikerült a hiba kijavítása?\nKoppintson a visszaállításhoz."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nincsenek problémái kamerával? Koppintson az elvetéshez."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Az alkalmazásmenü itt található"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Asztali ablakkezelési módba lépve több alkalmazást nyithat meg egyidejűleg"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Az alkalmazásmenüből bármikor visszatérhet a teljes képernyőre"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Több mindent láthat és tehet"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Húzzon ide egy másik alkalmazást az osztott képernyő használatához"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"App fogópontja"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Alkalmazásikon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Teljes képernyő"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Asztali ablakkezelési mód"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Osztott képernyő"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Továbbiak"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Lebegő"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Méretarány módosítása"</string>
     <string name="close_text" msgid="4986518933445178928">"Bezárás"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menü bezárása"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Asztali ablakkezelési mód)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Képernyő méretének maximalizálása"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Átméretezés"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Az alkalmazás nem helyezhető át ide"</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index d7b1b07..6bc3c37 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Չհաջողվե՞ց շտկել։\nՀպեք՝ փոփոխությունները չեղարկելու համար։"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Տեսախցիկի հետ կապված խնդիրներ չկա՞ն։ Փակելու համար հպեք։"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Հավելվածի ընտրացանկն այստեղ է"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Անցեք համակարգչային պատուհաններին՝ միաժամանակ մի քանի հավելված բացելու համար"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Ցանկացած ժամանակ հավելվածի ընտրացանկից վերադարձեք լիաէկրան ռեժիմ"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Միաժամանակ կատարեք մի քանի առաջադրանք"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Քաշեք մյուս հավելվածի մեջ՝ էկրանի տրոհումն օգտագործելու համար"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Հավելվածի կեղծանուն"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Հավելվածի պատկերակ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Լիաէկրան"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Համակարգչային պատուհաններ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Տրոհված էկրան"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Ավելին"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Լողացող պատուհան"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Փոխել կողմերի հարաբերակցությունը"</string>
     <string name="close_text" msgid="4986518933445178928">"Փակել"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Փակել ընտրացանկը"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (համակարգչային պատուհաններ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ծավալել էկրանը"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Փոխել չափը"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Հավելվածը հնարավոր չէ տեղափոխել այստեղ"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index 1d1927f..c15c2ea 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tidak dapat diperbaiki?\nKetuk untuk mengembalikan"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tidak ada masalah kamera? Ketuk untuk menutup."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Menu aplikasi dapat ditemukan di sini"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Masuk ke mode jendela desktop untuk membuka beberapa aplikasi secara bersamaan"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Kembali ke layar penuh kapan saja dari menu aplikasi"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lihat dan lakukan lebih banyak hal"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Tarik aplikasi lain untuk menggunakan layar terpisah"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Penanganan aplikasi"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikon Aplikasi"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Layar Penuh"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Mode jendela desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Layar Terpisah"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Lainnya"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Mengambang"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ubah rasio aspek"</string>
     <string name="close_text" msgid="4986518933445178928">"Tutup"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Mode jendela desktop)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Perbesar Layar"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ubah ukuran"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikasi tidak dapat dipindahkan ke sini"</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index e94a4c8..7d98d3b 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ennþá vesen?\nÝttu til að afturkalla"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Ekkert myndavélavesen? Ýttu til að hunsa."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Hér finnurðu forritavalmyndina"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Kveiktu á gluggastillingu í tölvu til að opna mörg forrit samtímis"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Þú getur skipt aftur í allan skjáinn hvenær sem er af forritavalmyndinni"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Sjáðu og gerðu meira"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Dragðu annað forrit inn til að nota skjáskiptingu"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Handfang forrits"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Tákn forrits"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Allur skjárinn"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Gluggastilling í tölvu"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Skjáskipting"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Meira"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Reikult"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Breyta myndhlutfalli"</string>
     <string name="close_text" msgid="4986518933445178928">"Loka"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Loka valmynd"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (gluggastilling í tölvu)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Stækka skjá"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Breyta stærð"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ekki er hægt að færa forritið hingað"</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 5f8334f..72f80569 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Il problema non si è risolto?\nTocca per ripristinare"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nessun problema con la fotocamera? Tocca per ignorare."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Il menu dell\'app si trova qui"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Attiva il windowing del desktop per aprire più app contemporaneamente"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Torna allo schermo intero in qualsiasi momento dal menu dell\'app"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Visualizza più contenuti e fai di più"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Trascina in un\'altra app per usare lo schermo diviso"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Punto di manipolazione app"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Icona dell\'app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Schermo intero"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Windowing del desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Schermo diviso"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Altro"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Mobile"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Cambia proporzioni"</string>
     <string name="close_text" msgid="4986518933445178928">"Chiudi"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Chiudi il menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (windowing del desktop)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Massimizza schermo"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ridimensiona"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Impossibile spostare l\'app qui"</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index 1a73dd3..c95ec4e 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"修正されなかった場合は、\nタップすると元に戻ります"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"カメラに関する問題でない場合は、タップすると閉じます。"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"アプリメニューはここにあります"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"デスクトップ ウィンドウに切り替えて複数のアプリを同時に開けます"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"アプリメニューからいつでも全画面表示に戻れます"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"表示を拡大して機能を強化"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"分割画面にするにはもう 1 つのアプリをドラッグしてください"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"アプリハンドル"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"アプリのアイコン"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"全画面表示"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"デスクトップ ウィンドウ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"分割画面"</string>
     <string name="more_button_text" msgid="3655388105592893530">"その他"</string>
     <string name="float_button_text" msgid="9221657008391364581">"フローティング"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"アスペクト比を変更"</string>
     <string name="close_text" msgid="4986518933445178928">"閉じる"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"メニューを閉じる"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g>(デスクトップ ウィンドウ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"画面の最大化"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"サイズ変更"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"アプリはここに移動できません"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 4bbfaef..0c7264c 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"არ გამოსწორდა?\nშეეხეთ წინა ვერსიის დასაბრუნებლად"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"კამერას პრობლემები არ აქვს? შეეხეთ უარყოფისთვის."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"აპის მენიუ შეგიძლიათ იხილოთ აქ"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"რამდენიმე აპის ერთდროულად გასახსნელად შედით დესკტოპის ფანჯრის რეჟიმში"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"სრულ ეკრანზე ნებისმიერ დროს შეგიძლიათ დაბრუნდეთ აპის მენიუდან"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"მეტის ნახვა და გაკეთება"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ეკრანის გასაყოფად ჩავლებით გადაიტანეთ სხვა აპში"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"აპის იდენტიფიკატორი"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"აპის ხატულა"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"სრულ ეკრანზე"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"დესკტოპის ფანჯრის რეჟიმი"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ეკრანის გაყოფა"</string>
     <string name="more_button_text" msgid="3655388105592893530">"სხვა"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ფარფატი"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"თანაფარდობის შეცვლა"</string>
     <string name="close_text" msgid="4986518933445178928">"დახურვა"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"მენიუს დახურვა"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (დესკტოპის ფანჯრის რეჟიმი)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"აპლიკაციის გაშლა სრულ ეკრანზე"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ზომის შეცვლა"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"აპის აქ გადატანა შეუძლებელია"</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 2f6404d..c1085db 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Жөнделмеді ме?\nҚайтару үшін түртіңіз."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада қателер шықпады ма? Жабу үшін түртіңіз."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Қолданба мәзірін осы жерден табуға болады."</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Бірнеше қолданбаны бірге ашу үшін жұмыс үстелі көрінісіне кіріңіз."</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Қолданба мәзірінен кез келген уақытта толық экранға оралыңыз."</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Қосымша ақпаратты қарап, әрекеттер жасау"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Экранды бөлу үшін басқа қолданбаға өтіңіз."</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Қолданба идентификаторы"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Қолданба белгішесі"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Толық экран"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Жұмыс үстелі көрінісі"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлу"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Қосымша"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Қалқыма"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Арақатынасты өзгерту"</string>
     <string name="close_text" msgid="4986518933445178928">"Жабу"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Мәзірді жабу"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (жұмыс үстелі көрінісі)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды ұлғайту"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Өлшемін өзгерту"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Қолданба бұл жерге қойылмайды."</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index d3942fd..afbd9e0 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"មិនបាន​ដោះស្រាយ​បញ្ហានេះទេឬ?\nចុចដើម្បី​ត្រឡប់"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"មិនមាន​បញ្ហាពាក់ព័ន្ធនឹង​កាមេរ៉ាទេឬ? ចុចដើម្បី​ច្រានចោល។"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"អាចរកឃើញម៉ឺនុយកម្មវិធីនៅទីនេះ"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ចូលមុខងារវិនដូកុំព្យូទ័រ ដើម្បីបើកកម្មវិធីច្រើនជាមួយគ្នា"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ត្រឡប់ទៅអេក្រង់ពេញវិញនៅពេលណាក៏បានពីម៉ឺនុយកម្មវិធី"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"មើលឃើញ និងធ្វើបានកាន់តែច្រើន"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"អូស​កម្មវិធី​មួយ​ទៀត​ចូល ដើម្បី​ប្រើ​មុខងារ​បំបែកអេក្រង់"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"ឈ្មោះអ្នកប្រើប្រាស់កម្មវិធី"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"រូប​កម្មវិធី"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"អេក្រង់​ពេញ"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"មុខងារវិនដូកុំព្យូទ័រ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"មុខងារ​បំបែក​អេក្រង់"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ច្រើនទៀត"</string>
     <string name="float_button_text" msgid="9221657008391364581">"អណ្ដែត"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ប្ដូរ​​សមាមាត្រ"</string>
     <string name="close_text" msgid="4986518933445178928">"បិទ"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"បិទ​ម៉ឺនុយ"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (មុខងារវិនដូកុំព្យូទ័រ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ពង្រីកអេក្រង់"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ប្ដូរ​ទំហំ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"មិនអាចផ្លាស់ទីកម្មវិធីមកទីនេះបានទេ"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index fb15e34..34076e8 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ಅದನ್ನು ಸರಿಪಡಿಸಲಿಲ್ಲವೇ?\nಹಿಂತಿರುಗಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ಕ್ಯಾಮರಾ ಸಮಸ್ಯೆಗಳಿಲ್ಲವೇ? ವಜಾಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ಆ್ಯಪ್ ಮೆನುವನ್ನು ಇಲ್ಲಿ ಕಾಣಬಹುದು"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ಹಲವು ಆ್ಯಪ್‌ಗಳನ್ನು ಒಟ್ಟಿಗೆ ತೆರೆಯಲು ಡೆಸ್ಕ್‌ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್ ಅನ್ನು ನಮೂದಿಸಿ"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ಆ್ಯಪ್ ಮೆನುವಿನಿಂದ ಯಾವಾಗ ಬೇಕಾದರೂ ಫುಲ್‌ಸ್ಕ್ರೀನ್‌ಗೆ ಹಿಂತಿರುಗಿ"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ನೋಡಿ ಮತ್ತು ಹೆಚ್ಚಿನದನ್ನು ಮಾಡಿ"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ಸ್ಪ್ಲಿಟ್‌ ಸ್ಕ್ರೀನ್‌ಗಾಗಿ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ನಲ್ಲಿ ಡ್ರ್ಯಾಗ್ ಮಾಡಿ"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"ಆ್ಯಪ್ ಹ್ಯಾಂಡಲ್"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"ಆ್ಯಪ್ ಐಕಾನ್"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ಫುಲ್‌ಸ್ಕ್ರೀನ್"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ಡೆಸ್ಕ್‌ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ಇನ್ನಷ್ಟು"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ಫ್ಲೋಟ್"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ದೃಶ್ಯಾನುಪಾತವನ್ನು ಬದಲಾಯಿಸಿ"</string>
     <string name="close_text" msgid="4986518933445178928">"ಮುಚ್ಚಿ"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"ಮೆನು ಮುಚ್ಚಿ"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ಡೆಸ್ಕ್‌ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ಸ್ಕ್ರೀನ್ ಅನ್ನು ಮ್ಯಾಕ್ಸಿಮೈಸ್ ಮಾಡಿ"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ಮರುಗಾತ್ರಗೊಳಿಸಿ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ಆ್ಯಪ್ ಅನ್ನು ಇಲ್ಲಿಗೆ ಸರಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ"</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index dbfd32a..a0fa7e4 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"해결되지 않았나요?\n되돌리려면 탭하세요."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"카메라에 문제가 없나요? 닫으려면 탭하세요."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"앱 메뉴는 여기에서 찾을 수 있습니다."</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"데스크톱 윈도윙을 실행하여 여러 앱을 함께 열 수 있습니다."</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"언제든지 앱 메뉴에서 전체 화면으로 돌아갈 수 있습니다."</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"더 많은 정보를 보고 더 많은 작업을 처리하세요"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"화면 분할을 사용하려면 다른 앱을 드래그해 가져옵니다."</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"앱 핸들"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"앱 아이콘"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"전체 화면"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"데스크톱 윈도잉"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"화면 분할"</string>
     <string name="more_button_text" msgid="3655388105592893530">"더보기"</string>
     <string name="float_button_text" msgid="9221657008391364581">"플로팅"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"가로세로 비율 변경"</string>
     <string name="close_text" msgid="4986518933445178928">"닫기"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"메뉴 닫기"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g>(데스크톱 윈도윙)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"화면 최대화"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"크기 조절"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"앱을 여기로 이동할 수 없음"</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 36194cd..629070c 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Оңдолгон жокпу?\nАртка кайтаруу үчүн таптаңыз"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерада маселе жокпу? Этибарга албоо үчүн таптаңыз."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Колдонмонун менюсун ушул жерден таба аласыз"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Бир убакта бир нече колдонмону ачуу үчүн иш тактанын терезелери режимине өтүңүз"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Каалаган убакта колдонмонун менюсунан толук экранга кайта аласыз"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Көрүп, көбүрөөк нерселерди жасаңыз"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Экранды бөлүү үчүн башка колдонмону сүйрөңүз"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Колдонмонун маркери"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Колдонмонун сүрөтчөсү"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Толук экран"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Иш тактанын терезелери"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Экранды бөлүү"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Дагы"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Калкыма"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Тараптардын катнашын өзгөртүү"</string>
     <string name="close_text" msgid="4986518933445178928">"Жабуу"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Менюну жабуу"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Иш тактанын терезелери)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Экранды чоңойтуу"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Өлчөмүн өзгөртүү"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Колдонмону бул жерге жылдырууга болбойт"</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 671f924..f2d0e6b 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ບໍ່ໄດ້ແກ້ໄຂມັນບໍ?\nແຕະເພື່ອແປງກັບຄືນ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ບໍ່ມີບັນຫາກ້ອງຖ່າຍຮູບບໍ? ແຕະເພື່ອ​ປິດ​ໄວ້."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ສາມາດເບິ່ງເມນູແອັບໄດ້ບ່ອນນີ້"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ເຂົ້າສູ່ໜ້າຈໍເດັສທັອບເພື່ອເປີດຫຼາຍແອັບພ້ອມກັນ"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ກັບຄືນໄປຫາໂໝດເຕັມຈໍໄດ້ທຸກເວລາຈາກເມນູແອັບ"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ເບິ່ງ ແລະ ເຮັດຫຼາຍຂຶ້ນ"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ລາກໄປໄວ້ໃນແອັບອື່ນເພື່ອແບ່ງໜ້າຈໍ"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"ຊື່ຜູ້ໃຊ້ແອັບ"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"ໄອຄອນແອັບ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ເຕັມຈໍ"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ໜ້າຈໍເດັສທັອບ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ແບ່ງໜ້າຈໍ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ເພີ່ມເຕີມ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ລອຍ"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ປ່ຽນອັດຕາສ່ວນຮູບ"</string>
     <string name="close_text" msgid="4986518933445178928">"ປິດ"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"ປິດເມນູ"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ໜ້າຈໍເດັສທັອບ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ປັບຈໍໃຫຍ່ສຸດ"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ປັບຂະໜາດ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ບໍ່ສາມາດຍ້າຍແອັບມາບ່ອນນີ້ໄດ້"</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index 794c5ab..ed4b14c 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nepavyko pataisyti?\nPalieskite, kad grąžintumėte"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nėra jokių problemų dėl kameros? Palieskite, kad atsisakytumėte."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Programos meniu rasite čia"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Įjunkite versijos staliniams kompiuteriams rodinį, kad galėtumėte vienu metu atidaryti kelias programas"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Bet kada iš programos meniu grįžkite į viso ekrano režimą"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Daugiau turinio ir funkcijų"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Vilkite kitoje programoje, kad galėtumėte naudoti išskaidyto ekrano režimą"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Programos kreipinys"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Programos piktograma"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Visas ekranas"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Versijos staliniams kompiuteriams rodinys"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Išskaidyto ekrano režimas"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Daugiau"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Slankusis langas"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Keisti kraštinių santykį"</string>
     <string name="close_text" msgid="4986518933445178928">"Uždaryti"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Uždaryti meniu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ (versijos staliniams kompiuteriams rodinys)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Išskleisti ekraną"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Pakeisti dydį"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Programos negalima perkelti čia"</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 5b44112..c24b43a 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Vai problēma netika novērsta?\nPieskarieties, lai atjaunotu."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Vai nav problēmu ar kameru? Pieskarieties, lai nerādītu."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Šeit ir pieejama lietotņu izvēlne"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Lai atvērtu vairākas lietotnes vienlaikus, pārejiet uz darbvirsmas logošanu"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"No lietotnes izvēlnes varat jebkurā brīdī atgriezties pilnekrāna režīmā."</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Uzziniet un paveiciet vairāk"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Lai izmantotu sadalītu ekrānu, ievelciet vēl vienu lietotni"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Lietotnes turis"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Lietotnes ikona"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Pilnekrāna režīms"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Darbvirsmas logošana"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Sadalīt ekrānu"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Vairāk"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Peldošs"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Mainīt malu attiecību"</string>
     <string name="close_text" msgid="4986518933445178928">"Aizvērt"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Aizvērt izvēlni"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (darbvirsmas logošana)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizēt ekrānu"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Mainīt lielumu"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Lietotni nevar pārvietot šeit."</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index 96bf9b6..06ed323 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не се поправи?\nДопрете за враќање"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нема проблеми со камерата? Допрете за отфрлање."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Менито со апликации може да го најдете овде"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Влезете во режимот со прозорци на работната површина за да отворите повеќе апликации заедно"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Вратете се на цел екран од менито со апликации кога сакате"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Погледнете и направете повеќе"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Повлечете друга апликација за поделен екран"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Прекар на апликацијата"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Икона на апликацијата"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Цел екран"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Режим со прозорци на работната површина"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Поделен екран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Повеќе"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Лебдечко"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени го соодносот"</string>
     <string name="close_text" msgid="4986518933445178928">"Затворете"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Затворете го менито"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим со прозорци на работната површина)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Максимизирај го екранот"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Смени големина"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликацијата не може да се премести овде"</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index 8085601..dd4ec1b 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"അത് പരിഹരിച്ചില്ലേ?\nപുനഃസ്ഥാപിക്കാൻ ടാപ്പ് ചെയ്യുക"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ക്യാമറാ പ്രശ്നങ്ങളൊന്നുമില്ലേ? നിരസിക്കാൻ ടാപ്പ് ചെയ്യുക."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ആപ്പ് മെനു ഇവിടെ കണ്ടെത്താനാകും"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ഒന്നിലധികം ആപ്പുകൾ ഒരുമിച്ച് തുറക്കാൻ ഡെസ്‌ക്‌‌ടോപ്പ് വിൻഡോയിംഗിൽ പ്രവേശിക്കുക"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ആപ്പ് മെനുവിൽ നിന്ന് ഏതുസമയത്തും പൂർണ്ണ സ്‌ക്രീനിലേക്ക് മടങ്ങുക"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"കൂടുതൽ കാണുക, ചെയ്യുക"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"സ്‌ക്രീൻ വിഭജന മോഡിന്, മറ്റൊരു ആപ്പ് വലിച്ചിടുക"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"ആപ്പ് ഹാൻഡിൽ"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"ആപ്പ് ഐക്കൺ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"പൂർണ്ണസ്ക്രീൻ"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ഡെസ്ക്ടോപ്പ് വിൻഡോയിംഗ്"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"സ്‌ക്രീൻ വിഭജനം"</string>
     <string name="more_button_text" msgid="3655388105592893530">"കൂടുതൽ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ഫ്ലോട്ട്"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"വീക്ഷണ അനുപാതം മാറ്റുക"</string>
     <string name="close_text" msgid="4986518933445178928">"അടയ്ക്കുക"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"മെനു അടയ്ക്കുക"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ഡെസ്ക്ടോപ്പ് വിൻഡോയിംഗ്)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"സ്‌ക്രീൻ വലുതാക്കുക"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"വലുപ്പം മാറ്റുക"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ആപ്പ് ഇവിടേക്ക് നീക്കാനാകില്ല"</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 5efe62d..8683827 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Үүнийг засаагүй юу?\nБуцаахын тулд товшино уу"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Камерын асуудал байхгүй юу? Хаахын тулд товшино уу."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Аппын цэсийг эндээс олох боломжтой"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Олон аппыг хамтад нь нээхийн тулд дэлгэцийн цонх үүсгэх гэж орно уу"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Аппын цэсээс бүтэн дэлгэц рүү хүссэн үедээ буцна уу"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Харж илүү ихийг хий"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Дэлгэц хуваах горимд ашиглахын тулд өөр аппыг чирнэ үү"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Аппын бариул"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Aппын дүрс тэмдэг"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Бүтэн дэлгэц"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Дэлгэцийн цонх үүсгэх онцлог"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Дэлгэцийг хуваах"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Бусад"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Хөвөгч"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Аспектын харьцааг өөрчлөх"</string>
     <string name="close_text" msgid="4986518933445178928">"Хаах"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Цэсийг хаах"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Дэлгэцийн цонх үүсгэх онцлог)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Дэлгэцийг томруулах"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Хэмжээг өөрчлөх"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Аппыг ийш зөөх боломжгүй"</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index e10c8d8..b7b3fb6 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"निराकरण झाले नाही?\nरिव्हर्ट करण्यासाठी कृपया टॅप करा"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"कॅमेराशी संबंधित कोणत्याही समस्या नाहीत का? डिसमिस करण्‍यासाठी टॅप करा."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ॲप मेनू इथे आढळू शकतो"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"एकाहून अधिक ॲप्स एकत्र उघडण्यासाठी डेस्कटॉप विंडोइंग एंटर करा"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ॲप मेनूमधून कधीही फुल स्क्रीनवर परत या"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"पहा आणि आणखी बरेच काही करा"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"स्प्लिट स्क्रीन वापरण्यासाठी दुसरे ॲप ड्रॅग करा"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"अ‍ॅपचे हँडल"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"अ‍ॅप आयकन"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"फुलस्‍क्रीन"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"डेस्कटॉप विंडोइंग"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रीन"</string>
     <string name="more_button_text" msgid="3655388105592893530">"आणखी"</string>
     <string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"आस्पेक्ट रेशो बदला"</string>
     <string name="close_text" msgid="4986518933445178928">"बंद करा"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"मेनू बंद करा"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटॉप विंडोइंग)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रीन मोठी करा"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"आकार बदला"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"अ‍ॅप इथे हलवू शकत नाही"</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index e18e7ec..0896b5e 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Isu tidak dibetulkan?\nKetik untuk kembali"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Tiada isu kamera? Ketik untuk mengetepikan."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Menu apl boleh ditemukan di sini"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Masuki tetingkap desktop untuk membuka berbilang apl serentak"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Kembali kepada skrin penuh pada bila-bila masa daripada menu apl"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Lihat dan lakukan lebih"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Seret masuk apl lain untuk menggunakan skrin pisah"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Pengendalian apl"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikon Apl"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Skrin penuh"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Tetingkap desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Skrin Pisah"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Lagi"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Terapung"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tukar nisbah bidang"</string>
     <string name="close_text" msgid="4986518933445178928">"Tutup"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Tutup Menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Tetingkap desktop)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimumkan Skrin"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ubah saiz"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Apl tidak boleh dialihkan ke sini"</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 334a797..0f336e8 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ကောင်းမသွားဘူးလား။\nပြန်ပြောင်းရန် တို့ပါ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ကင်မရာပြဿနာ မရှိဘူးလား။ ပယ်ရန် တို့ပါ။"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"အက်ပ်မီနူးကို ဤနေရာတွင် တွေ့နိုင်သည်"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"အက်ပ်များစွာကို အတူတကွဖွင့်ရန်အတွက် ဒက်စ်တော့ဝင်းဒိုးမုဒ်သို့ ဝင်ရောက်နိုင်သည်"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"အက်ပ်မီနူးမှ ဖန်သားပြင်အပြည့်သို့ အချိန်မရွေး ပြန်သွားနိုင်သည်"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ကြည့်ပြီး ပိုမိုလုပ်ဆောင်ပါ"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းအတွက် အက်ပ်နောက်တစ်ခုကို ဖိဆွဲပါ"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"အက်ပ်သုံးသူအမည်"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"အက်ပ်သင်္ကေတ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ဖန်သားပြင်အပြည့်"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ဒက်စ်တော့ဝင်းဒိုးမုဒ်"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"မျက်နှာပြင် ခွဲ၍ပြသရန်"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ပိုပြပါ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"မျှောရန်"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"အချိုးအစား ပြောင်းရန်"</string>
     <string name="close_text" msgid="4986518933445178928">"ပိတ်ရန်"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"မီနူး ပိတ်ရန်"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ဒက်စ်တော့ဝင်းဒိုးမုဒ်)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"စခရင်ကို ချဲ့မည်"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"အရွယ်ပြင်ရန်"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"အက်ပ်ကို ဤနေရာသို့ ရွှေ့၍မရပါ"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 7e21b47..3207614 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Ble ikke problemet løst?\nTrykk for å gå tilbake"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Har du ingen kameraproblemer? Trykk for å lukke."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Her finner du appmenyen"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Start datamaskin-vindusvisning for å åpne flere apper samtidig"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Du kan gå tilbake til fullskjermmodusen når som helst fra appmenyen"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se og gjør mer"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Dra inn en annen app for å bruke delt skjerm"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Apphåndtak"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Fullskjerm"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Datamaskin-vindusvisning"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Delt skjerm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Svevende"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Endre høyde/bredde-forholdet"</string>
     <string name="close_text" msgid="4986518933445178928">"Lukk"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Lukk menyen"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (datamaskin-vindusvisning)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimer skjermen"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Endre størrelse"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Appen kan ikke flyttes hit"</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 976f837..2c7be99 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"समस्या हल भएन?\nपहिलेको जस्तै बनाउन ट्याप गर्नुहोस्"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"क्यामेरासम्बन्धी कुनै पनि समस्या छैन? खारेज गर्न ट्याप गर्नुहोस्।"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"एपको मेनु यहाँ भेट्टाउन सकिन्छ"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"एकभन्दा बढी एपहरू सँगै देखाउन डेस्कटप विन्डोइङ हाल्नुहोस्"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"जुनसुकै बेला एपको मेनुबाट फुल स्क्रिनमा फर्कनुहोस्"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"थप कुरा हेर्नुहोस् र गर्नुहोस्"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"स्प्लिट स्क्रिन मोड प्रयोग गर्न अर्को एप ड्रयाग एन्ड ड्रप गर्नुहोस्"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"एपको ह्यान्डल"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"एपको आइकन"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"फुल स्क्रिन"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"डेस्कटप विन्डोइङ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"स्प्लिट स्क्रिन"</string>
     <string name="more_button_text" msgid="3655388105592893530">"थप"</string>
     <string name="float_button_text" msgid="9221657008391364581">"फ्लोट"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"एस्पेक्ट रेसियो परिवर्तन गर्नुहोस्"</string>
     <string name="close_text" msgid="4986518933445178928">"बन्द गर्नुहोस्"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"मेनु बन्द गर्नुहोस्"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (डेस्कटप विन्डोइङ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"स्क्रिन ठुलो बनाउनुहोस्"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"आकार बदल्नुहोस्"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"एप सारेर यहाँ ल्याउन सकिएन"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 7178e41..099f875 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Is dit geen oplossing?\nTik om terug te zetten."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Geen cameraproblemen? Tik om te sluiten."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Het app-menu vind je hier"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Ga naar de desktopvensterfunctie om meerdere apps tegelijk te openen"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Ga wanneer je wilt terug naar volledig scherm vanuit het app-menu"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Zie en doe meer"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Sleep een andere app hier naartoe om het scherm te splitsen"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"App-handgreep"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"App-icoon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Volledig scherm"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Desktopvensterfunctie"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Gesplitst scherm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Meer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Zwevend"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Beeldverhouding wijzigen"</string>
     <string name="close_text" msgid="4986518933445178928">"Sluiten"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menu sluiten"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (desktopvensterfunctie)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Scherm maximaliseren"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Formaat aanpassen"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Kan de app niet hierheen verplaatsen"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 7e89290..50e3cd6 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"ਕੀ ਇਹ ਠੀਕ ਨਹੀਂ ਹੋਈ?\nਵਾਪਸ ਉਹੀ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"ਕੀ ਕੈਮਰੇ ਸੰਬੰਧੀ ਕੋਈ ਸਮੱਸਿਆ ਨਹੀਂ ਹੈ? ਖਾਰਜ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ।"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ਐਪ ਮੀਨੂ ਇੱਥੇ ਮਿਲ ਸਕਦਾ ਹੈ"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"ਕਈ ਐਪਾਂ ਨੂੰ ਇਕੱਠੇ ਖੋਲ੍ਹਣ ਲਈ ਡੈਸਕਟਾਪ ਵਿੰਡੋ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ਐਪ ਮੀਨੂ ਤੋਂ ਕਿਸੇ ਵੀ ਸਮੇਂ ਪੂਰੀ ਸਕ੍ਰੀਨ \'ਤੇ ਵਾਪਸ ਜਾਓ"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"ਦੇਖੋ ਅਤੇ ਹੋਰ ਬਹੁਤ ਕੁਝ ਕਰੋ"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੇ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ ਵਿੱਚ ਘਸੀਟੋ"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"ਐਪ ਹੈਂਡਲ"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"ਐਪ ਪ੍ਰਤੀਕ"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ਪੂਰੀ-ਸਕ੍ਰੀਨ"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ਡੈਸਕਟਾਪ ਵਿੰਡੋ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ"</string>
     <string name="more_button_text" msgid="3655388105592893530">"ਹੋਰ"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ਫ਼ਲੋਟ"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ਆਕਾਰ ਅਨੁਪਾਤ ਬਦਲੋ"</string>
     <string name="close_text" msgid="4986518933445178928">"ਬੰਦ ਕਰੋ"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"ਮੀਨੂ ਬੰਦ ਕਰੋ"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ਡੈਸਕਟਾਪ ਵਿੰਡੋ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"ਸਕ੍ਰੀਨ ਦਾ ਆਕਾਰ ਵਧਾਓ"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ਆਕਾਰ ਬਦਲੋ"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ਐਪ ਨੂੰ ਇੱਥੇ ਨਹੀਂ ਲਿਜਾਇਆ ਜਾ ਸਕਦਾ"</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 765a207..d553518 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Não foi corrigido?\nToque para reverter"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nenhum problema com a câmara? Toque para ignorar."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"O menu da app pode ser encontrado aqui"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Entre no modo de janelas de computador para abrir várias apps em conjunto"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Regresse ao ecrã inteiro em qualquer altura a partir do menu da app"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Veja e faça mais"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Arraste outra app para usar o ecrã dividido"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Indicador da app"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ícone da app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Ecrã inteiro"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Janelas de computador"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Ecrã dividido"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mais"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flutuar"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Alterar formato"</string>
     <string name="close_text" msgid="4986518933445178928">"Fechar"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Fechar menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (janelas de computador)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizar ecrã"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionar"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Não é possível mover a app para aqui"</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 68d045f..286443c 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nu ai remediat problema?\nAtinge pentru a reveni"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nu ai probleme cu camera foto? Atinge pentru a închide."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Meniul aplicației poate fi găsit aici"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Accesează afișarea în ferestre pe desktop pentru a deschide mai multe aplicații simultan"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Revino oricând la ecranul complet din meniul aplicației"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Vezi și fă mai multe"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Trage în altă aplicație pentru a folosi ecranul împărțit"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Handle de aplicație"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Pictograma aplicației"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Ecran complet"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Ferestre pe desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Ecran împărțit"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mai multe"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Flotantă"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Schimbă raportul de dimensiuni"</string>
     <string name="close_text" msgid="4986518933445178928">"Închide"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Închide meniul"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ferestre pe desktop)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximizează fereastra"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Redimensionează"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplicația nu poate fi mutată aici"</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index 8e683b8..472a239 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Не помогло?\nНажмите, чтобы отменить изменения."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Нет проблем с камерой? Нажмите, чтобы закрыть."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Здесь вы найдете меню приложения"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Чтобы открыть сразу несколько приложений, перейдите в режим компьютерных окон"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Вернуться в полноэкранный режим можно из меню приложения"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Выполняйте несколько задач одновременно"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Перетащите сюда другое приложение, чтобы использовать разделение экрана."</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Обозначение приложения"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Значок приложения"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Полноэкранный режим"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Режим компьютерных окон"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Разделить экран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Ещё"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Плавающее окно"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Изменить соотношение сторон"</string>
     <string name="close_text" msgid="4986518933445178928">"Закрыть"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Закрыть меню"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (режим компьютерных окон)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Развернуть на весь экран"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Изменить размер"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Приложение нельзя сюда переместить"</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 6d54839..6c91955 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"එය විසඳුවේ නැතිද?\nප්‍රතිවර්තනය කිරීමට තට්ටු කරන්න"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"කැමරා ගැටලු නොමැතිද? ඉවත දැමීමට තට්ටු කරන්න"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"යෙදුම් මෙනුව මෙතැනින් සොයා ගත හැක"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"බහු යෙදුම් එකවර විවෘත කිරීමට ඩෙස්ක්ටොප් කවුළුවට ඇතුළු වන්න"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"යෙදුම් මෙනුවෙන් ඕනෑම වේලාවක පූර්ණ තිරය වෙත ආපසු යන්න"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"බලන්න සහ තවත් දේ කරන්න"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"බෙදුම් තිරය සඳහා වෙනත් යෙදුමකට අදින්න"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"යෙදුම් හසුරුව"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"යෙදුම් නිරූපකය"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"පූර්ණ තිරය"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ඩෙස්ක්ටොප් කවුළුකරණය"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"බෙදුම් තිරය"</string>
     <string name="more_button_text" msgid="3655388105592893530">"තව"</string>
     <string name="float_button_text" msgid="9221657008391364581">"පාවෙන"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"දර්ශන අනුපාතය වෙනස් කරන්න"</string>
     <string name="close_text" msgid="4986518933445178928">"වසන්න"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"මෙනුව වසන්න"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ඩෙස්ක්ටොප් කවුළුකරණය)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"තිරය උපරිම කරන්න"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"ප්‍රතිප්‍රමාණය කරන්න"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"යෙදුම මෙතැනට ගෙන යා නොහැක"</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index c04b038..08404d0 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nevyriešilo sa to?\nKlepnutím sa vráťte."</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nemáte problémy s kamerou? Klepnutím zatvoríte."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Ponuku aplikácie nájdete tu"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Aktivujte windowing na pracovnej ploche a otvorte viac aplikácií naraz"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Z ponuky aplikácie sa môžete kedykoľvek vrátiť na celú obrazovku"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Zobrazte si a zvládnite toho viac"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Rozdelenú obrazovku môžete použiť presunutím do inej aplikácie"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Rukoväť aplikácie"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikácie"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Celá obrazovka"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Windowing na pracovnej ploche"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Rozdelená obrazovka"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Viac"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Plávajúce"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Zmeniť pomer strán"</string>
     <string name="close_text" msgid="4986518933445178928">"Zavrieť"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zavrieť ponuku"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (windowing na pracovnej ploche)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximalizovať obrazovku"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Zmeniť veľkosť"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikácia sa sem nedá presunúť"</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 22d7bfe..deed0e0 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"To ni odpravilo težave?\nDotaknite se za povrnitev"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nimate težav s fotoaparatom? Dotaknite se za opustitev."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Meni aplikacije najdete tukaj"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Preklopite v namizni način prikaza več oken hkrati, če želite odpreti več aplikacij hkrati"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"V meniju aplikacije se lahko kadar koli vrnete v celozaslonski način"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Oglejte si in naredite več"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Za razdeljeni zaslon povlecite sem še eno aplikacijo."</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Identifikator aplikacije"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikona aplikacije"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Celozaslonsko"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Namizni način prikaza več oken hkrati"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Razdeljen zaslon"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Več"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Lebdeče"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Sprememba razmerja stranic"</string>
     <string name="close_text" msgid="4986518933445178928">"Zapri"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Zapri meni"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (namizni način prikaza več oken hkrati)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimiraj zaslon"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Spremeni velikost"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacije ni mogoče premakniti sem"</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 9330ec3..c6b8c6d 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Nuk u rregullua?\nTrokit për ta rikthyer"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Nuk ka probleme me kamerën? Trokit për ta shpërfillur."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Menyja e aplikacioneve mund të gjendet këtu"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Kalo te ndërfaqja me dritare në desktop për të hapur disa aplikacione së bashku"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Kthehu tek ekrani i plotë në çdo kohë nga menyja e aplikacioneve"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Shiko dhe bëj më shumë"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Zvarrite në një aplikacion tjetër për ekranin e ndarë"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Emërtimi i aplikacionit"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ikona e aplikacionit"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Ekrani i plotë"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Ndërfaqja me dritare në desktop"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Ekrani i ndarë"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Më shumë"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Pluskuese"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ndrysho raportin e pamjes"</string>
     <string name="close_text" msgid="4986518933445178928">"Mbyll"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Mbyll menynë"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ndërfaqja me dritare në desktop)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maksimizo ekranin"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ndrysho përmasat"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Aplikacioni nuk mund të zhvendoset këtu"</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 5bdad15..3fe25f9 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Проблем није решен?\nДодирните да бисте вратили"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Немате проблема са камером? Додирните да бисте одбацили."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Мени апликације можете да пронађете овде"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Уђите у прозорски приказ за рачунаре да бисте истовремено отворили више апликација"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Вратите се на цео екран било када из менија апликације"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Видите и урадите више"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Превуците другу апликацију да бисте користили подељени екран"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Идентификатор апликације"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Икона апликације"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Преко целог екрана"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Прозорски приказ за рачунаре"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Подељени екран"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Још"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Плутајуће"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Промени размеру"</string>
     <string name="close_text" msgid="4986518933445178928">"Затворите"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Затворите мени"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (прозорски приказ за рачунаре)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Повећај екран"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Прилагоди"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Апликација не може да се премести овде"</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 40a0a5a..404bdaf 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Löstes inte problemet?\nTryck för att återställa"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Inga problem med kameran? Tryck för att ignorera."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Appmenyn finns här"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Använd fönsterstapling för att öppna flera appar samtidigt"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Återgå till helskärm när som helst från appmenyn"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Se och gör mer"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Dra till en annan app för att dela upp skärmen"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Apphandtag"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Appikon"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Helskärm"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Fönsterstapling"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Delad skärm"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Mer"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Svävande"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Ändra bildformat"</string>
     <string name="close_text" msgid="4986518933445178928">"Stäng"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Stäng menyn"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (fönsterstapling)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Maximera skärmen"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Ändra storlek"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Det går inte att flytta appen hit"</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 20429e1..3bd7988 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Umeshindwa kurekebisha?\nGusa ili urejeshe nakala ya awali"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Je, hakuna hitilafu za kamera? Gusa ili uondoe."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Unaweza kupata menyu ya programu hapa"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Tumia hali ya kupanga madirisha ya kompyuta ya mezani ili ufungue programu nyingi pamoja"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Rudi kwenye skrini nzima wakati wowote ukitumia menyu ya programu"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Angalia na ufanye zaidi"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Buruta katika programu nyingine ili utumie skrini iliyogawanywa"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Utambulisho wa programu"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Aikoni ya Programu"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Skrini nzima"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Kupanga madirisha ya kompyuta ya mezani"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Gawa Skrini"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Zaidi"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Inayoelea"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Badilisha uwiano"</string>
     <string name="close_text" msgid="4986518933445178928">"Funga"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Funga Menyu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Kupanga madirisha ya kompyuta ya mezani)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Panua Dirisha kwenye Skrini"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Badilisha ukubwa"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Imeshindwa kuhamishia programu hapa"</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index 74ecfdc..12780df 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"சிக்கல்கள் சரிசெய்யப்படவில்லையா?\nமாற்றியமைக்க தட்டவும்"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"கேமரா தொடர்பான சிக்கல்கள் எதுவும் இல்லையா? நிராகரிக்க தட்டவும்."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ஆப்ஸ் மெனுவை இங்கே பார்க்கலாம்"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"பல ஆப்ஸை ஒன்றாகத் திறக்க டெஸ்க்டாப் சாளரமாக்குதலுக்குச் செல்லலாம்"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ஆப்ஸ் மெனுவிலிருந்து எப்போது வேண்டுமானாலும் முழுத்திரைக்குத் திரும்பலாம்"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"பலவற்றைப் பார்த்தல் மற்றும் செய்தல்"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"திரைப் பிரிப்புக்கு மற்றொரு ஆப்ஸை இழுக்கலாம்"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"ஆப்ஸ் ஹேண்டில்"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"ஆப்ஸ் ஐகான்"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"முழுத்திரை"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"டெஸ்க்டாப் சாளரமாக்குதல்"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"திரையைப் பிரிக்கும்"</string>
     <string name="more_button_text" msgid="3655388105592893530">"கூடுதல் விருப்பத்தேர்வுகள்"</string>
     <string name="float_button_text" msgid="9221657008391364581">"மிதக்கும் சாளரம்"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"தோற்ற விகிதத்தை மாற்று"</string>
     <string name="close_text" msgid="4986518933445178928">"மூடும்"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"மெனுவை மூடும்"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (டெஸ்க்டாப் சாளரமாக்குதல்)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"திரையைப் பெரிதாக்கு"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"அளவை மாற்று"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ஆப்ஸை இங்கே நகர்த்த முடியாது"</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index f46c9b6..2044fe7 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"దాని సమస్యను పరిష్కరించలేదా?\nపూర్వస్థితికి మార్చడానికి ట్యాప్ చేయండి"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"కెమెరా సమస్యలు లేవా? తీసివేయడానికి ట్యాప్ చేయండి."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"యాప్ మెనూను ఇక్కడ పొందవచ్చు"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"పలు యాప్‌లను ఒకేసారి తెరవడానికి డెస్క్‌టాప్ వీక్షణకు ఎంటర్ అవ్వండి"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"యాప్ మెనూ నుండి ఏ సమయంలోనైనా ఫుల్ స్క్రీన్‌కు తిరిగి రండి"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"చూసి, మరిన్ని చేయండి"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"స్ప్లిట్ స్క్రీన్ కోసం మరొక యాప్‌లోకి లాగండి"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"యాప్ హ్యాండిల్"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"యాప్ చిహ్నం"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"ఫుల్-స్క్రీన్"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"డెస్క్‌టాప్ వీక్షణ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"స్ప్లిట్ స్క్రీన్"</string>
     <string name="more_button_text" msgid="3655388105592893530">"మరిన్ని"</string>
     <string name="float_button_text" msgid="9221657008391364581">"ఫ్లోట్"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"ఆకార నిష్పత్తిని మార్చండి"</string>
     <string name="close_text" msgid="4986518933445178928">"మూసివేయండి"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"మెనూను మూసివేయండి"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (డెస్క్‌టాప్ వీక్షణ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"స్క్రీన్ సైజ్‌ను పెంచండి"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"సైజ్ మార్చండి"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"యాప్‌ను ఇక్కడకి తరలించడం సాధ్యం కాదు"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index ae6df04..586d655 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Hindi ito naayos?\nI-tap para i-revert"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Walang isyu sa camera? I-tap para i-dismiss."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Makikita rito ang menu ng app"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Pumunta sa desktop windowing para magbukas ng maraming app nang sabay-sabay"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Bumalik sa full screen anumang oras mula sa menu ng app"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Tumingin at gumawa ng higit pa"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Mag-drag ng isa pang app para sa split screen"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Handle ng app"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Icon ng App"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Fullscreen"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Desktop windowing"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Split Screen"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Higit pa"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Float"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Baguhin ang aspect ratio"</string>
     <string name="close_text" msgid="4986518933445178928">"Isara"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Isara ang Menu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop windowing)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"I-maximize ang Screen"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"I-resize"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Hindi mailipat dito ang app"</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 116740e..9605acf 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bu işlem sorunu düzeltmedi mi?\nİşlemi geri almak için dokunun"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kameranızda sorun yok mu? Kapatmak için dokunun."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Uygulama menüsünü burada bulabilirsiniz"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Birden fazla uygulamayı birlikte açmak için masaüstü pencerelemeye geçin"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Uygulama menüsünden dilediğiniz zaman tam ekrana dönebilirsiniz"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Daha fazlasını görün ve yapın"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Bölünmüş ekran için başka bir uygulamayı sürükleyin"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Uygulama tanıtıcısı"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Uygulama Simgesi"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Tam Ekran"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Masaüstü pencereleme"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Bölünmüş Ekran"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Daha Fazla"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Havada Süzülen"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"En boy oranını değiştir"</string>
     <string name="close_text" msgid="4986518933445178928">"Kapat"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menüyü kapat"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (masaüstü pencereleme)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranı Büyüt"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Yeniden boyutlandır"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Uygulama buraya taşınamıyor"</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 635bc40..9614ce9 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"یہ حل نہیں ہوا؟\nلوٹانے کیلئے تھپتھپائیں"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"کوئی کیمرے کا مسئلہ نہیں ہے؟ برخاست کرنے کیلئے تھپتھپائیں۔"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"ایپ کا مینو یہاں پایا جا سکتا ہے"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"متعدد ایپس کو ایک ساتھ کھولنے کے لیے ڈیسک ٹاپ ونڈوئنگ میں داخل ہوں"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"ایپ مینو سے کسی بھی وقت فُل اسکرین پر واپس جائیں"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"دیکھیں اور بہت کچھ کریں"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"اسپلٹ اسکرین کے ليے دوسری ایپ میں گھسیٹیں"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"ایپ ہینڈل"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"ایپ کا آئیکن"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"مکمل اسکرین"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"ڈیسک ٹاپ ونڈوئنگ"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"اسپلٹ اسکرین"</string>
     <string name="more_button_text" msgid="3655388105592893530">"مزید"</string>
     <string name="float_button_text" msgid="9221657008391364581">"فلوٹ"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"تناسبی شرح کو تبدیل کریں"</string>
     <string name="close_text" msgid="4986518933445178928">"بند کریں"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"مینیو بند کریں"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (ڈیسک ٹاپ ونڈوئنگ)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"اسکرین کو بڑا کریں"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"سائز تبدیل کریں"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"ایپ کو یہاں منتقل نہیں کیا جا سکتا"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 6ce2bd8..6025467 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Tuzatilmadimi?\nQaytarish uchun bosing"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Kamera muammosizmi? Yopish uchun bosing."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Ilova menyusi shu yerda chiqadi"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Bir nechta ilovani birga ochish uchun oynalarni desktop rejimida chiqarish"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Ilova menyusi orqali istalganda butun ekranga qaytish mumkin"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Yana boshqa amallar"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Ekranni ikkiga ajratish uchun boshqa ilovani bu yerga torting"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Ilova identifikatori"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Ilova belgisi"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Butun ekran"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Desktop rejimidagi oynalar"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Ekranni ikkiga ajratish"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Yana"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Pufakli"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Tomonlar nisbatini oʻzgartirish"</string>
     <string name="close_text" msgid="4986518933445178928">"Yopish"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Menyuni yopish"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Desktop rejimidagi oynalar)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Ekranni yoyish"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Oʻlchamini oʻzgartirish"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Ilova bu yerga surilmaydi"</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 67f80c1..4c394b2 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Bạn chưa khắc phục vấn đề?\nHãy nhấn để hủy bỏ"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Không có vấn đề với máy ảnh? Hãy nhấn để đóng."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Bạn có thể tìm thấy trình đơn ứng dụng tại đây"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Chuyển sang chế độ cửa sổ trên máy tính để mở nhiều ứng dụng cùng lúc"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Trở về chế độ toàn màn hình bất cứ lúc nào từ trình đơn ứng dụng"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Xem và làm được nhiều việc hơn"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Kéo một ứng dụng khác vào để chia đôi màn hình"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Ô điều khiển ứng dụng"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Biểu tượng ứng dụng"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Toàn màn hình"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Cửa sổ trên máy tính"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Chia đôi màn hình"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Tuỳ chọn khác"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Nổi"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Thay đổi tỷ lệ khung hình"</string>
     <string name="close_text" msgid="4986518933445178928">"Đóng"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Đóng trình đơn"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Chế độ cửa sổ trên máy tính)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Mở rộng màn hình"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Đổi kích thước"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"Không di chuyển được ứng dụng đến đây"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index 74e6b5c..fda5c74 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未能修正問題?\n輕按即可還原"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機冇問題?㩒一下就可以即可閂咗佢。"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"你可在這裡找到應用程式選單"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"進入電腦分割視窗模式可同時開啟多個應用程式"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"你可隨時從應用程式選單返回全螢幕"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"瀏覽更多內容及執行更多操作"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"拖入另一個應用程式即可分割螢幕"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"應用程式控點"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"電腦分割視窗"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"分割螢幕"</string>
     <string name="more_button_text" msgid="3655388105592893530">"更多"</string>
     <string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更長寬比"</string>
     <string name="close_text" msgid="4986518933445178928">"關閉"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (電腦分割視窗)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"調整大小"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至這裡"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 575b217..e83c647 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"未修正問題嗎?\n輕觸即可還原"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"相機沒問題嗎?輕觸即可關閉。"</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"你可以在這裡查看應用程式選單"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"進入電腦分割視窗模式可同時開啟多個應用程式"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"你隨時可以從應用程式選單返回全螢幕模式"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"瀏覽更多內容及執行更多操作"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"拖進另一個應用程式即可使用分割畫面模式"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"應用程式控制代碼"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"應用程式圖示"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"全螢幕"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"電腦分割視窗"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"分割畫面"</string>
     <string name="more_button_text" msgid="3655388105592893530">"更多"</string>
     <string name="float_button_text" msgid="9221657008391364581">"浮動"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"變更顯示比例"</string>
     <string name="close_text" msgid="4986518933445178928">"關閉"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"關閉選單"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (電腦分割視窗)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"畫面最大化"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"調整大小"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"應用程式無法移至此處"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index 30403cd..4d658f2 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -100,8 +100,7 @@
     <string name="camera_compat_treatment_applied_button_description" msgid="2944157113330703897">"Akuyilungisanga?\nThepha ukuze ubuyele"</string>
     <string name="camera_compat_dismiss_button_description" msgid="2795364433503817511">"Azikho izinkinga zekhamera? Thepha ukuze ucashise."</string>
     <string name="windowing_app_handle_education_tooltip" msgid="2929643449849791854">"Imenyu ye-app ingatholakala lapha"</string>
-    <!-- no translation found for windowing_desktop_mode_image_button_education_tooltip (7171915734817051666) -->
-    <skip />
+    <string name="windowing_desktop_mode_image_button_education_tooltip" msgid="7171915734817051666">"Faka ukwenziwa kwamawindi amaningi kwedeskithophu ukuze uvule ama-app amaningi ndawonye"</string>
     <string name="windowing_desktop_mode_exit_education_tooltip" msgid="5225660258192054132">"Buyela esikrinini esigcwele noma nini ukusuka kumenyu ye-app"</string>
     <string name="letterbox_education_dialog_title" msgid="7739895354143295358">"Bona futhi wenze okuningi"</string>
     <string name="letterbox_education_split_screen_text" msgid="449233070804658627">"Hudula kwenye i-app mayelana nokuhlukanisa isikrini"</string>
@@ -122,8 +121,7 @@
     <string name="handle_text" msgid="4419667835599523257">"Inkomba ye-App"</string>
     <string name="app_icon_text" msgid="2823268023931811747">"Isithonjana Se-app"</string>
     <string name="fullscreen_text" msgid="1162316685217676079">"Isikrini esigcwele"</string>
-    <!-- no translation found for desktop_text (9058641752519570266) -->
-    <skip />
+    <string name="desktop_text" msgid="9058641752519570266">"Ukwenziwa kwamawindi amaningi kwedeskithophu"</string>
     <string name="split_screen_text" msgid="1396336058129570886">"Hlukanisa isikrini"</string>
     <string name="more_button_text" msgid="3655388105592893530">"Okwengeziwe"</string>
     <string name="float_button_text" msgid="9221657008391364581">"Iflowuthi"</string>
@@ -136,8 +134,7 @@
     <string name="change_aspect_ratio_text" msgid="9104456064548212806">"Shintsha ukubukeka kwesilinganiselo"</string>
     <string name="close_text" msgid="4986518933445178928">"Vala"</string>
     <string name="collapse_menu_text" msgid="7515008122450342029">"Vala Imenyu"</string>
-    <!-- no translation found for desktop_mode_app_header_chip_text (7617377295944971651) -->
-    <skip />
+    <string name="desktop_mode_app_header_chip_text" msgid="7617377295944971651">"<xliff:g id="APP_NAME">%1$s</xliff:g> (Ukwenziwa kwamawindi amaningi kwedeskithophu)"</string>
     <string name="desktop_mode_maximize_menu_maximize_text" msgid="3275717276171114411">"Khulisa Isikrini Sifike Ekugcineni"</string>
     <string name="desktop_mode_maximize_menu_snap_text" msgid="5673738963174074006">"Shintsha usayizi"</string>
     <string name="desktop_mode_non_resizable_snap_text" msgid="3771776422751387878">"I-app ayikwazi ukuhanjiswa lapha"</string>
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 2a8c88ed..e1bf663 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -291,6 +291,9 @@
     <!-- Corner radius for expanded view drop target -->
     <dimen name="bubble_bar_expanded_view_drop_target_corner">28dp</dimen>
     <dimen name="bubble_bar_expanded_view_drop_target_padding">24dp</dimen>
+    <dimen name="bubble_bar_expanded_view_drop_target_padding_top">60dp</dimen>
+    <dimen name="bubble_bar_expanded_view_drop_target_padding_bottom">24dp</dimen>
+    <dimen name="bubble_bar_expanded_view_drop_target_padding_horizontal">48dp</dimen>
     <!-- Width of the box around bottom center of the screen where drag only leads to dismiss -->
     <dimen name="bubble_bar_dismiss_zone_width">192dp</dimen>
     <!-- Height of the box around bottom center of the screen where drag only leads to dismiss -->
diff --git a/libs/WindowManager/Shell/res/values/styles.xml b/libs/WindowManager/Shell/res/values/styles.xml
index 637b47a..5f1db83 100644
--- a/libs/WindowManager/Shell/res/values/styles.xml
+++ b/libs/WindowManager/Shell/res/values/styles.xml
@@ -45,6 +45,7 @@
         <item name="android:layout_height">52dp</item>
         <item name="android:textColor">@androidprv:color/materialColorOnSurface</item>
         <item name="android:drawableTint">@androidprv:color/materialColorOnSurface</item>
+        <item name="android:importantForAccessibility">no</item>
     </style>
 
     <style name="DesktopModeHandleMenuActionButtonImage">
diff --git a/libs/WindowManager/Shell/shared/res/values/dimen.xml b/libs/WindowManager/Shell/shared/res/values/dimen.xml
index f6a176f..3b504cf 100644
--- a/libs/WindowManager/Shell/shared/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/shared/res/values/dimen.xml
@@ -31,6 +31,7 @@
     <dimen name="drag_zone_desktop_window_expanded_view_height">350dp</dimen>
     <dimen name="drag_zone_split_from_bubble_height">100dp</dimen>
     <dimen name="drag_zone_split_from_bubble_width">60dp</dimen>
+    <dimen name="drag_zone_h_split_from_app_width_fold">140dp</dimen>
     <dimen name="drag_zone_h_split_from_expanded_view_width">60dp</dimen>
     <dimen name="drag_zone_v_split_from_expanded_view_width">200dp</dimen>
     <dimen name="drag_zone_v_split_from_expanded_view_height_tablet">285dp</dimen>
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
index 25b9f8c..f68afea 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/GroupedTaskInfo.java
@@ -18,6 +18,7 @@
 
 import static android.app.WindowConfiguration.windowingModeToString;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
+import static android.view.Display.INVALID_DISPLAY;
 
 import android.annotation.IntDef;
 import android.app.ActivityManager.RecentTaskInfo;
@@ -65,6 +66,11 @@
     private final int mDeskId;
 
     /**
+     * The ID of the display that desk with [mDeskId] is in.
+     */
+    private final int mDeskDisplayId;
+
+    /**
      * The type of this particular task info, can be one of TYPE_FULLSCREEN, TYPE_SPLIT or
      * TYPE_DESK.
      */
@@ -109,17 +115,19 @@
      * Create new for a stack of fullscreen tasks
      */
     public static GroupedTaskInfo forFullscreenTasks(@NonNull TaskInfo task) {
-        return new GroupedTaskInfo(/* deskId = */ -1, List.of(task), null, TYPE_FULLSCREEN,
-                /* minimizedFreeformTaskIds = */ null);
+        return new GroupedTaskInfo(/* deskId = */ -1, /* displayId = */ INVALID_DISPLAY,
+                List.of(task), null,
+                TYPE_FULLSCREEN, /* minimizedFreeformTaskIds = */ null);
     }
 
     /**
      * Create new for a pair of tasks in split screen
      */
     public static GroupedTaskInfo forSplitTasks(@NonNull TaskInfo task1,
-                    @NonNull TaskInfo task2, @NonNull SplitBounds splitBounds) {
-        return new GroupedTaskInfo(/* deskId = */ -1, List.of(task1, task2), splitBounds,
-                TYPE_SPLIT, /* minimizedFreeformTaskIds = */ null);
+            @NonNull TaskInfo task2, @NonNull SplitBounds splitBounds) {
+        return new GroupedTaskInfo(/* deskId = */ -1, /* displayId = */ INVALID_DISPLAY,
+                List.of(task1, task2),
+                splitBounds, TYPE_SPLIT, /* minimizedFreeformTaskIds = */ null);
     }
 
     /**
@@ -127,9 +135,11 @@
      */
     public static GroupedTaskInfo forDeskTasks(
             int deskId,
+            int deskDisplayId,
             @NonNull List<TaskInfo> tasks,
             @NonNull Set<Integer> minimizedFreeformTaskIds) {
-        return new GroupedTaskInfo(deskId, tasks, /* splitBounds = */ null, TYPE_DESK,
+        return new GroupedTaskInfo(deskId, deskDisplayId, tasks, /* splitBounds = */ null,
+                TYPE_DESK,
                 minimizedFreeformTaskIds.stream().mapToInt(i -> i).toArray());
     }
 
@@ -149,11 +159,13 @@
 
     private GroupedTaskInfo(
             int deskId,
+            int deskDisplayId,
             @NonNull List<TaskInfo> tasks,
             @Nullable SplitBounds splitBounds,
             @GroupType int type,
             @Nullable int[] minimizedFreeformTaskIds) {
         mDeskId = deskId;
+        mDeskDisplayId = deskDisplayId;
         mTasks = tasks;
         mGroupedTasks = null;
         mSplitBounds = splitBounds;
@@ -164,6 +176,7 @@
 
     private GroupedTaskInfo(@NonNull List<GroupedTaskInfo> groupedTasks) {
         mDeskId = -1;
+        mDeskDisplayId = INVALID_DISPLAY;
         mTasks = null;
         mGroupedTasks = groupedTasks;
         mSplitBounds = null;
@@ -185,6 +198,7 @@
 
     protected GroupedTaskInfo(@NonNull Parcel parcel) {
         mDeskId = parcel.readInt();
+        mDeskDisplayId = parcel.readInt();
         mTasks = new ArrayList();
         final int numTasks = parcel.readInt();
         for (int i = 0; i < numTasks; i++) {
@@ -295,6 +309,16 @@
     }
 
     /**
+     * Returns the ID of the display that hosts the desk represented by [mDeskId].
+     */
+    public int getDeskDisplayId() {
+        if (mType != TYPE_DESK) {
+            throw new IllegalStateException("No display ID for non desktop task");
+        }
+        return mDeskDisplayId;
+    }
+
+    /**
      * Get type of this recents entry. One of {@link GroupType}.
      * Note: This is deprecated, callers should use `isBaseType()` and not make assumptions about
      *       specific group types
@@ -323,6 +347,7 @@
         }
         GroupedTaskInfo other = (GroupedTaskInfo) obj;
         return mDeskId == other.mDeskId
+                && mDeskDisplayId == other.mDeskDisplayId
                 && mType == other.mType
                 && Objects.equals(mTasks, other.mTasks)
                 && Objects.equals(mGroupedTasks, other.mGroupedTasks)
@@ -332,7 +357,7 @@
 
     @Override
     public int hashCode() {
-        return Objects.hash(mDeskId, mType, mTasks, mGroupedTasks, mSplitBounds,
+        return Objects.hash(mDeskId, mDeskDisplayId, mType, mTasks, mGroupedTasks, mSplitBounds,
                 Arrays.hashCode(mMinimizedTaskIds));
     }
 
@@ -345,6 +370,7 @@
                     .collect(Collectors.joining(",\n\t", "[\n\t", "\n]")));
         } else {
             taskString.append("Desk ID= ").append(mDeskId).append(", ");
+            taskString.append("Desk Display ID=").append(mDeskDisplayId).append(", ");
             taskString.append("Tasks=" + mTasks.stream()
                     .map(taskInfo -> getTaskInfoDumpString(taskInfo))
                     .collect(Collectors.joining(", ", "[", "]")));
@@ -377,6 +403,7 @@
     @Override
     public void writeToParcel(Parcel parcel, int flags) {
         parcel.writeInt(mDeskId);
+        parcel.writeInt(mDeskDisplayId);
         // We don't use the parcel list methods because we want to only write the TaskInfo state
         // and not the subclasses (Recents/RunningTaskInfo) whose fields are all deprecated
         final int tasksSize = mTasks != null ? mTasks.size() : 0;
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TypefaceUtils.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TypefaceUtils.kt
index 9bf56b0..f4efcca 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TypefaceUtils.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/TypefaceUtils.kt
@@ -80,7 +80,7 @@
             fontStyle: Int = Typeface.NORMAL,
         ) {
             if (!Flags.enableGsf()) return
-            textView?.typeface = Typeface.create(fontFamily.name, fontStyle)
+            textView?.typeface = Typeface.create(fontFamily.value, fontStyle)
         }
     }
 }
diff --git a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicy.kt b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicy.kt
index b87c205..529203f 100644
--- a/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicy.kt
+++ b/libs/WindowManager/Shell/shared/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicy.kt
@@ -23,6 +23,7 @@
 import android.window.DesktopModeFlags
 import com.android.internal.R
 import com.android.internal.policy.DesktopModeCompatUtils
+import java.util.function.Supplier
 
 /**
  * Class to decide whether to apply app compat policies in desktop mode.
@@ -34,9 +35,11 @@
     private val pkgManager: PackageManager
         get() = context.getPackageManager()
     private val defaultHomePackage: String?
-        get() = pkgManager.getHomeActivities(ArrayList())?.packageName
+        get() = defaultHomePackageSupplier?.get()
+            ?: pkgManager.getHomeActivities(ArrayList())?.packageName
     private val packageInfoCache = mutableMapOf<String, Boolean>()
 
+    var defaultHomePackageSupplier: Supplier<String?>? = null
 
     /**
      * If the top activity should be exempt from desktop windowing and forced back to fullscreen.
@@ -46,15 +49,21 @@
      */
     fun isTopActivityExemptFromDesktopWindowing(task: TaskInfo) =
         isTopActivityExemptFromDesktopWindowing(task.baseActivity?.packageName,
-            task.numActivities, task.isTopActivityNoDisplay, task.isActivityStackTransparent)
+            task.numActivities, task.isTopActivityNoDisplay, task.isActivityStackTransparent,
+            task.userId)
 
-    fun isTopActivityExemptFromDesktopWindowing(packageName: String?,
-        numActivities: Int, isTopActivityNoDisplay: Boolean, isActivityStackTransparent: Boolean) =
+    fun isTopActivityExemptFromDesktopWindowing(
+        packageName: String?,
+        numActivities: Int,
+        isTopActivityNoDisplay: Boolean,
+        isActivityStackTransparent: Boolean,
+        userId: Int
+    ) =
         DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_MODALS_POLICY.isTrue &&
                 ((isSystemUiTask(packageName) ||
                         isPartOfDefaultHomePackageOrNoHomeAvailable(packageName) ||
                         (isTransparentTask(isActivityStackTransparent, numActivities) &&
-                                hasFullscreenTransparentPermission(packageName))) &&
+                                hasFullscreenTransparentPermission(packageName, userId))) &&
                         !isTopActivityNoDisplay)
 
     /** @see DesktopModeCompatUtils.shouldExcludeCaptionFromAppBounds */
@@ -77,16 +86,17 @@
     private fun isSystemUiTask(packageName: String?) = packageName == systemUiPackage
 
     // Checks if the app for the given package has the SYSTEM_ALERT_WINDOW permission.
-    private fun hasFullscreenTransparentPermission(packageName: String?): Boolean {
+    private fun hasFullscreenTransparentPermission(packageName: String?, userId: Int): Boolean {
         if (DesktopModeFlags.ENABLE_MODALS_FULLSCREEN_WITH_PERMISSIONS.isTrue) {
             if (packageName == null) {
                 return false
             }
-            return packageInfoCache.getOrPut(packageName) {
+            return packageInfoCache.getOrPut("$userId@$packageName") {
                 try {
-                    val packageInfo = pkgManager.getPackageInfo(
+                    val packageInfo = pkgManager.getPackageInfoAsUser(
                         packageName,
-                        PackageManager.GET_PERMISSIONS
+                        PackageManager.GET_PERMISSIONS,
+                        userId
                     )
                     packageInfo?.requestedPermissions?.contains(SYSTEM_ALERT_WINDOW) == true
                 } catch (e: PackageManager.NameNotFoundException) {
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 53dede6..5d59af9 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
@@ -332,7 +332,11 @@
 
         @Override
         public void onThresholdCrossed() {
-            BackAnimationController.this.onThresholdCrossed();
+            if (predictiveBackDelayWmTransition()) {
+                mShellExecutor.execute(BackAnimationController.this::onThresholdCrossed);
+            } else {
+                BackAnimationController.this.onThresholdCrossed();
+            }
         }
 
         @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index 912de81..81eff6f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -1306,7 +1306,11 @@
                 // TODO b/392893178: Merge the unfold and the task view transition so that we don't
                 //  have to post a delayed runnable to the looper to update the bounds
                 if (mStackView.isExpanded()) {
-                    mStackView.postDelayed(() -> mStackView.updateExpandedView(), 500);
+                    mStackView.postDelayed(() -> {
+                        if (mStackView != null) {
+                            mStackView.updateExpandedView();
+                        }
+                    } , 500);
                 }
             }
             if (newConfig.fontScale != mFontScale) {
@@ -2643,9 +2647,9 @@
         mBubbleData.setSelectedBubbleAndExpandStack(bubbleToSelect);
     }
 
-    private void moveBubbleToFullscreen(String key) {
+    private void moveDraggedBubbleToFullscreen(String key, Point dropLocation) {
         Bubble b = mBubbleData.getBubbleInStackWithKey(key);
-        mBubbleTransitions.startDraggedBubbleIconToFullscreen(b);
+        mBubbleTransitions.startDraggedBubbleIconToFullscreen(b, dropLocation);
     }
 
     private boolean isDeviceLocked() {
@@ -2936,8 +2940,9 @@
         }
 
         @Override
-        public void moveBubbleToFullscreen(String key) {
-            mMainExecutor.execute(() -> mController.moveBubbleToFullscreen(key));
+        public void moveDraggedBubbleToFullscreen(String key, Point dropLocation) {
+            mMainExecutor.execute(
+                    () -> mController.moveDraggedBubbleToFullscreen(key, dropLocation));
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 8ac9230..290ef16 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -27,6 +27,7 @@
 import static com.android.wm.shell.bubbles.BubbleDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.wm.shell.bubbles.BubblePositioner.MAX_HEIGHT;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_BUBBLES;
+import static com.android.wm.shell.shared.TypefaceUtils.setTypeface;
 
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
@@ -71,6 +72,7 @@
 import com.android.wm.shell.R;
 import com.android.wm.shell.common.AlphaOptimizedButton;
 import com.android.wm.shell.shared.TriangleShape;
+import com.android.wm.shell.shared.TypefaceUtils;
 import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
 import com.android.wm.shell.taskview.TaskView;
 
@@ -468,9 +470,12 @@
                             public void onTaskCreated() {
                                 // The taskId is saved to use for removeTask,
                                 // preventing appearance in recent tasks.
-                                mTaskId = ((BubbleTaskViewListener) mCurrentTaskViewListener)
-                                    .getTaskId();
-
+                                BubbleTaskViewListener listener = mCurrentTaskViewListener != null
+                                        ? ((BubbleTaskViewListener) mCurrentTaskViewListener)
+                                        : null;
+                                mTaskId = listener != null
+                                        ? listener.getTaskId()
+                                        : bubbleTaskView.getTaskId();
                                 setContentVisibility(true);
                             }
 
@@ -548,6 +553,7 @@
         mManageButton = (AlphaOptimizedButton) LayoutInflater.from(ctw).inflate(
                 R.layout.bubble_manage_button, this /* parent */, false /* attach */);
         addView(mManageButton);
+        setTypeface(mManageButton, TypefaceUtils.FontFamily.GSF_LABEL_LARGE);
         mManageButton.setVisibility(visibility);
         setManageClickListener();
         post(() -> {
@@ -606,6 +612,10 @@
         updateManageButtonIfExists();
     }
 
+    public float getCornerRadius() {
+        return mCornerRadius;
+    }
+
     /**
      * Updates the size and visuals of the pointer if {@link #mPointerView} is initialized.
      * Does nothing otherwise.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
index da6948d..92007a4 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleFlyoutView.java
@@ -50,6 +50,7 @@
 
 import com.android.wm.shell.R;
 import com.android.wm.shell.shared.TriangleShape;
+import com.android.wm.shell.shared.TypefaceUtils;
 
 /**
  * Flyout view that appears as a 'chat bubble' alongside the bubble stack. The flyout can visually
@@ -165,8 +166,10 @@
         LayoutInflater.from(context).inflate(R.layout.bubble_flyout, this, true);
         mFlyoutTextContainer = findViewById(R.id.bubble_flyout_text_container);
         mSenderText = findViewById(R.id.bubble_flyout_name);
+        TypefaceUtils.setTypeface(mSenderText, TypefaceUtils.FontFamily.GSF_LABEL_LARGE);
         mSenderAvatar = findViewById(R.id.bubble_flyout_avatar);
         mMessageText = mFlyoutTextContainer.findViewById(R.id.bubble_flyout_text);
+        TypefaceUtils.setTypeface(mMessageText, TypefaceUtils.FontFamily.GSF_BODY_MEDIUM);
 
         final Resources res = getResources();
         mFlyoutPadding = res.getDimensionPixelSize(R.dimen.bubble_flyout_padding_x);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
index 64f54b8..e901e0c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflowContainerView.java
@@ -46,6 +46,7 @@
 import com.android.internal.util.ContrastColorUtil;
 import com.android.wm.shell.Flags;
 import com.android.wm.shell.R;
+import com.android.wm.shell.shared.TypefaceUtils;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -234,6 +235,10 @@
         setBackgroundColor(bgColor);
         mEmptyStateTitle.setTextColor(textColor);
         mEmptyStateSubtitle.setTextColor(textColor);
+        TypefaceUtils.setTypeface(mEmptyStateTitle,
+                TypefaceUtils.FontFamily.GSF_BODY_MEDIUM_EMPHASIZED);
+        TypefaceUtils.setTypeface(mEmptyStateSubtitle, TypefaceUtils.FontFamily.GSF_BODY_MEDIUM);
+
     }
 
     public void updateFontSize() {
@@ -322,6 +327,7 @@
 
         TextView viewName = overflowView.findViewById(R.id.bubble_view_name);
         viewName.setTextColor(textColor);
+        TypefaceUtils.setTypeface(viewName, TypefaceUtils.FontFamily.GSF_LABEL_LARGE);
 
         return new ViewHolder(overflowView, mPositioner);
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
index 70340d7..03d6b0a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubblePositioner.java
@@ -103,7 +103,9 @@
     private int mManageButtonHeight;
     private int mOverflowHeight;
     private int mMinimumFlyoutWidthLargeScreen;
-    private int mBubbleBarExpandedViewDropTargetPadding;
+    private int mBarExpViewDropTargetPaddingTop;
+    private int mBarExpViewDropTargetPaddingBottom;
+    private int mBarExpViewDropTargetPaddingHorizontal;
 
     private PointF mRestingStackPosition;
 
@@ -173,8 +175,12 @@
                 res.getDimensionPixelSize(R.dimen.bubble_bar_expanded_view_width),
                 mPositionRect.width() - 2 * mExpandedViewPadding
         );
-        mBubbleBarExpandedViewDropTargetPadding = res.getDimensionPixelSize(
-                R.dimen.bubble_bar_expanded_view_drop_target_padding);
+        mBarExpViewDropTargetPaddingTop = res.getDimensionPixelSize(
+                R.dimen.bubble_bar_expanded_view_drop_target_padding_top);
+        mBarExpViewDropTargetPaddingBottom = res.getDimensionPixelSize(
+                R.dimen.bubble_bar_expanded_view_drop_target_padding_bottom);
+        mBarExpViewDropTargetPaddingHorizontal = res.getDimensionPixelSize(
+                R.dimen.bubble_bar_expanded_view_drop_target_padding_horizontal);
 
         if (mShowingInBubbleBar) {
             mExpandedViewLargeScreenWidth = mExpandedViewBubbleBarWidth;
@@ -986,8 +992,15 @@
     public Rect getBubbleBarExpandedViewDropTargetBounds(boolean onLeft) {
         Rect bounds = new Rect();
         getBubbleBarExpandedViewBounds(onLeft, false, bounds);
-        bounds.inset(mBubbleBarExpandedViewDropTargetPadding,
-                mBubbleBarExpandedViewDropTargetPadding);
+        // Drop target bounds are based on expanded view bounds with some padding added
+        int leftPadding = onLeft ? 0 : mBarExpViewDropTargetPaddingHorizontal;
+        int rightPadding = onLeft ? mBarExpViewDropTargetPaddingHorizontal : 0;
+        bounds.inset(
+                leftPadding,
+                mBarExpViewDropTargetPaddingTop,
+                rightPadding,
+                mBarExpViewDropTargetPaddingBottom
+        );
         return bounds;
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index 9272417..3dce456 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -89,8 +89,11 @@
 import com.android.wm.shell.bubbles.animation.StackAnimationController;
 import com.android.wm.shell.common.FloatingContentCoordinator;
 import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.shared.TypefaceUtils;
+import com.android.wm.shell.shared.TypefaceUtils.FontFamily;
 import com.android.wm.shell.shared.animation.Interpolators;
 import com.android.wm.shell.shared.animation.PhysicsAnimator;
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
 import com.android.wm.shell.shared.bubbles.DeviceConfig;
 import com.android.wm.shell.shared.bubbles.DismissView;
 import com.android.wm.shell.shared.bubbles.RelativeTouchListener;
@@ -1319,7 +1322,7 @@
         mBubbleContainer.bringToFront();
     }
 
-    // TODO: Create ManageMenuView and move setup / animations there
+    // TODO (b/402196554) : Create ManageMenuView and move setup / animations there
     private void setUpManageMenu() {
         if (mManageMenu != null) {
             removeView(mManageMenu);
@@ -1377,9 +1380,33 @@
         mManageSettingsIcon = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_icon);
         mManageSettingsText = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_name);
 
+        View fullscreenView = mManageMenu.findViewById(
+                R.id.bubble_manage_menu_fullscreen_container);
+        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+            fullscreenView.setVisibility(VISIBLE);
+            fullscreenView.setOnClickListener(
+                    view -> {
+                        showManageMenu(false /* show */);
+                        BubbleExpandedView expandedView = getExpandedView();
+                        if (expandedView != null && expandedView.getTaskView() != null) {
+                            expandedView.getTaskView().moveToFullscreen();
+                        }
+                    });
+        } else {
+            fullscreenView.setVisibility(GONE);
+        }
+
         // The menu itself should respect locale direction so the icons are on the correct side.
         mManageMenu.setLayoutDirection(LAYOUT_DIRECTION_LOCALE);
         addView(mManageMenu);
+
+        // Doesn't seem to work unless view is added; so set font after.
+        TypefaceUtils.setTypeface(findViewById(R.id.manage_dismiss), FontFamily.GSF_LABEL_LARGE);
+        TypefaceUtils.setTypeface(findViewById(R.id.manage_dont_bubble),
+                FontFamily.GSF_LABEL_LARGE);
+        TypefaceUtils.setTypeface(mManageSettingsText, FontFamily.GSF_LABEL_LARGE);
+        TypefaceUtils.setTypeface(findViewById(R.id.bubble_manage_menu_fullscreen_title),
+                FontFamily.GSF_LABEL_LARGE);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
index 8cd6ce0..728975e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleTransitions.java
@@ -30,6 +30,7 @@
 import android.app.ActivityManager;
 import android.app.TaskInfo;
 import android.content.Context;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.IBinder;
@@ -42,6 +43,11 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
+import androidx.core.animation.Animator;
+import androidx.core.animation.Animator.AnimatorUpdateListener;
+import androidx.core.animation.AnimatorListenerAdapter;
+import androidx.core.animation.ValueAnimator;
+
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.launcher3.icons.BubbleIconFactory;
 import com.android.wm.shell.ShellTaskOrganizer;
@@ -114,8 +120,8 @@
     }
 
     /** Starts a transition that converts a dragged bubble icon to a full screen task. */
-    public BubbleTransition startDraggedBubbleIconToFullscreen(Bubble bubble) {
-        return new DraggedBubbleIconToFullscreen(bubble);
+    public BubbleTransition startDraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation) {
+        return new DraggedBubbleIconToFullscreen(bubble, dropLocation);
     }
 
     /**
@@ -612,8 +618,7 @@
             mTaskLeash = taskChg.getLeash();
             mRootLeash = info.getRoot(0).getLeash();
 
-            SurfaceControl dest =
-                    mBubble.getBubbleBarExpandedView().getViewRootImpl().getSurfaceControl();
+            SurfaceControl dest = getExpandedView(mBubble).getViewRootImpl().getSurfaceControl();
             final Runnable onPlucked = () -> {
                 // Need to remove the taskview AFTER applying the startTransaction because
                 // it isn't synchronized.
@@ -623,12 +628,12 @@
                 mBubbleData.setExpanded(false /* expanded */);
             };
             if (dest != null) {
-                pluck(mTaskLeash, mBubble.getBubbleBarExpandedView(), dest,
+                pluck(mTaskLeash, getExpandedView(mBubble), dest,
                         taskChg.getStartAbsBounds().left - info.getRoot(0).getOffset().x,
                         taskChg.getStartAbsBounds().top - info.getRoot(0).getOffset().y,
-                        mBubble.getBubbleBarExpandedView().getCornerRadius(), startTransaction,
+                        getCornerRadius(mBubble), startTransaction,
                         onPlucked);
-                mBubble.getBubbleBarExpandedView().post(() -> mTransitions.dispatchTransition(
+                getExpandedView(mBubble).post(() -> mTransitions.dispatchTransition(
                         mTransition, info, startTransaction, finishTransaction, finishCallback,
                         null));
             } else {
@@ -649,6 +654,20 @@
             t.reparent(mTaskLeash, mRootLeash);
             t.apply();
         }
+
+        private View getExpandedView(@NonNull Bubble bubble) {
+            if (bubble.getBubbleBarExpandedView() != null) {
+                return bubble.getBubbleBarExpandedView();
+            }
+            return bubble.getExpandedView();
+        }
+
+        private float getCornerRadius(@NonNull Bubble bubble) {
+            if (bubble.getBubbleBarExpandedView() != null) {
+                return bubble.getBubbleBarExpandedView().getCornerRadius();
+            }
+            return bubble.getExpandedView().getCornerRadius();
+        }
     }
 
     /**
@@ -660,9 +679,19 @@
 
         IBinder mTransition;
         final Bubble mBubble;
+        final Point mDropLocation;
+        final TransactionProvider mTransactionProvider;
 
-        DraggedBubbleIconToFullscreen(Bubble bubble) {
+        DraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation) {
+            this(bubble, dropLocation, SurfaceControl.Transaction::new);
+        }
+
+        @VisibleForTesting
+        DraggedBubbleIconToFullscreen(Bubble bubble, Point dropLocation,
+                TransactionProvider transactionProvider) {
             mBubble = bubble;
+            mDropLocation = dropLocation;
+            mTransactionProvider = transactionProvider;
             bubble.setPreparingTransition(this);
             WindowContainerToken token = bubble.getTaskView().getTaskInfo().getToken();
             WindowContainerTransaction wct = new WindowContainerTransaction();
@@ -710,8 +739,34 @@
             }
             mRepository.remove(taskViewTaskController);
 
+            final SurfaceControl taskLeash = change.getLeash();
+            // set the initial position of the task with 0 scale
+            startTransaction.setPosition(taskLeash, mDropLocation.x, mDropLocation.y);
+            startTransaction.setScale(taskLeash, 0, 0);
             startTransaction.apply();
-            finishCallback.onTransitionFinished(null);
+
+            final SurfaceControl.Transaction animT = mTransactionProvider.get();
+            ValueAnimator animator = ValueAnimator.ofFloat(0, 1);
+            animator.setDuration(250);
+            animator.addUpdateListener(new AnimatorUpdateListener() {
+                @Override
+                public void onAnimationUpdate(@NonNull Animator animation) {
+                    float progress = animator.getAnimatedFraction();
+                    float x = mDropLocation.x * (1 - progress);
+                    float y = mDropLocation.y * (1 - progress);
+                    animT.setPosition(taskLeash, x, y);
+                    animT.setScale(taskLeash, progress, progress);
+                    animT.apply();
+                }
+            });
+            animator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(@NonNull Animator animation) {
+                    animT.close();
+                    finishCallback.onTransitionFinished(null);
+                }
+            });
+            animator.start();
             taskViewTaskController.notifyTaskRemovalStarted(mBubble.getTaskView().getTaskInfo());
             mTaskViewTransitions.onExternalDone(transition);
             return true;
@@ -761,4 +816,8 @@
             mTaskViewTransitions.onExternalDone(transition);
         }
     }
+
+    interface TransactionProvider {
+        SurfaceControl.Transaction get();
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
index 079edb3..e2d5d78 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/IBubbles.aidl
@@ -18,6 +18,7 @@
 
 import android.content.Intent;
 import android.content.pm.ShortcutInfo;
+import android.graphics.Point;
 import android.graphics.Rect;
 import android.os.UserHandle;
 import com.android.wm.shell.bubbles.IBubblesListener;
@@ -59,5 +60,5 @@
 
     oneway void showDropTarget(in boolean show, in @nullable BubbleBarLocation location) = 15;
 
-    oneway void moveBubbleToFullscreen(in String key) = 16;
+    oneway void moveDraggedBubbleToFullscreen(in String key, in Point dropLocation) = 16;
 }
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
index 39a2a7b..d2ad708 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/ManageEducationView.kt
@@ -27,6 +27,7 @@
 import android.widget.LinearLayout
 import com.android.internal.R.color.system_neutral1_900
 import com.android.wm.shell.R
+import com.android.wm.shell.shared.TypefaceUtils
 import com.android.wm.shell.shared.animation.Interpolators
 
 /**
@@ -53,6 +54,12 @@
 
     init {
         LayoutInflater.from(context).inflate(R.layout.bubbles_manage_button_education, this)
+        TypefaceUtils.setTypeface(findViewById(R.id.user_education_title),
+            TypefaceUtils.FontFamily.GSF_HEADLINE_SMALL_EMPHASIZED)
+        TypefaceUtils.setTypeface(findViewById(R.id.user_education_description),
+            TypefaceUtils.FontFamily.GSF_BODY_MEDIUM)
+        TypefaceUtils.setTypeface(manageButton, TypefaceUtils.FontFamily.GSF_LABEL_LARGE_EMPHASIZED)
+        TypefaceUtils.setTypeface(gotItButton, TypefaceUtils.FontFamily.GSF_LABEL_LARGE_EMPHASIZED)
         visibility = View.GONE
         elevation = resources.getDimensionPixelSize(R.dimen.bubble_elevation).toFloat()
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
index 1660619..9ac05989 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/StackEducationView.kt
@@ -26,6 +26,7 @@
 import android.widget.TextView
 import com.android.internal.util.ContrastColorUtil
 import com.android.wm.shell.R
+import com.android.wm.shell.shared.TypefaceUtils
 import com.android.wm.shell.shared.animation.Interpolators
 
 /**
@@ -59,6 +60,9 @@
 
     init {
         LayoutInflater.from(context).inflate(R.layout.bubble_stack_user_education, this)
+        TypefaceUtils.setTypeface(titleTextView,
+            TypefaceUtils.FontFamily.GSF_HEADLINE_SMALL_EMPHASIZED)
+        TypefaceUtils.setTypeface(descTextView, TypefaceUtils.FontFamily.GSF_BODY_MEDIUM)
 
         visibility = View.GONE
         elevation = resources.getDimensionPixelSize(R.dimen.bubble_elevation).toFloat()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
index 9d4f904..3543556 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarExpandedViewDragController.kt
@@ -203,7 +203,11 @@
             draggedObject: MagnetizedObject<*>,
         ) {
             dragListener.onReleased(inDismiss = true)
-            pinController.onDragEnd()
+            if (dropTargetManager != null) {
+                dropTargetManager.onDragEnded()
+            } else {
+                pinController.onDragEnd()
+            }
             dismissView.hide()
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
index 3997412..2cc9387 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarLayerView.java
@@ -147,15 +147,23 @@
                                 Log.w(TAG, "dropped invalid bubble: " + mExpandedBubble);
                                 return;
                             }
+
+                            final boolean isBubbleLeft = zone instanceof DragZone.Bubble.Left;
+                            final boolean isBubbleRight = zone instanceof DragZone.Bubble.Right;
+                            if (!isBubbleLeft && !isBubbleRight) {
+                                // If we didn't finish the "change" animation make sure to animate
+                                // it back to the right spot
+                                locationChangeListener.onChange(mInitialLocation);
+                            }
                             if (zone instanceof DragZone.FullScreen) {
                                 ((Bubble) mExpandedBubble).getTaskView().moveToFullscreen();
                                 // Make sure location change listener is updated with the initial
                                 // location -- even if we "switched sides" during the drag, since
                                 // we've ended up in fullscreen, the location shouldn't change.
                                 locationChangeListener.onRelease(mInitialLocation);
-                            } else if (zone instanceof DragZone.Bubble.Left) {
+                            } else if (isBubbleLeft) {
                                 locationChangeListener.onRelease(BubbleBarLocation.LEFT);
-                            } else if (zone instanceof DragZone.Bubble.Right) {
+                            } else if (isBubbleRight) {
                                 locationChangeListener.onRelease(BubbleBarLocation.RIGHT);
                             }
                         }
@@ -189,7 +197,7 @@
                         @NonNull
                         @Override
                         public SplitScreenMode getSplitScreenMode() {
-                            return SplitScreenMode.NONE;
+                            return SplitScreenMode.UNSUPPORTED;
                         }
                     },
                     new DragZoneFactory.DesktopWindowModeChecker() {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
index 6c14d83..bccc6dc 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuItemView.java
@@ -25,6 +25,7 @@
 import android.widget.TextView;
 
 import com.android.wm.shell.R;
+import com.android.wm.shell.shared.TypefaceUtils;
 
 /**
  * Bubble bar expanded view menu item view to display menu action details
@@ -55,6 +56,7 @@
         super.onFinishInflate();
         mImageView = findViewById(R.id.bubble_bar_menu_item_icon);
         mTextView = findViewById(R.id.bubble_bar_menu_item_title);
+        TypefaceUtils.setTypeface(mTextView, TypefaceUtils.FontFamily.GSF_TITLE_MEDIUM);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
index dfbf655..7c0f8e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuView.java
@@ -33,6 +33,7 @@
 
 import com.android.wm.shell.R;
 import com.android.wm.shell.bubbles.Bubble;
+import com.android.wm.shell.shared.TypefaceUtils;
 
 import java.util.ArrayList;
 
@@ -75,6 +76,7 @@
         mActionsSectionView = findViewById(R.id.bubble_bar_manage_menu_actions_section);
         mBubbleIconView = findViewById(R.id.bubble_bar_manage_menu_bubble_icon);
         mBubbleTitleView = findViewById(R.id.bubble_bar_manage_menu_bubble_title);
+        TypefaceUtils.setTypeface(mBubbleTitleView, TypefaceUtils.FontFamily.GSF_TITLE_MEDIUM);
         mBubbleDismissIconView = findViewById(R.id.bubble_bar_manage_menu_dismiss_icon);
         updateThemeColors();
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
index b7761ec..69009fd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleBarMenuViewController.java
@@ -28,9 +28,9 @@
 import android.view.ViewGroup;
 
 import com.android.app.animation.Interpolators;
-import com.android.wm.shell.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.bubbles.Bubble;
+import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
 
 import java.util.ArrayList;
 
@@ -263,7 +263,7 @@
                 }
         ));
 
-        if (Flags.enableBubbleAnything() || Flags.enableBubbleToFullscreen()) {
+        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
             menuActions.add(new BubbleBarMenuView.MenuAction(
                     Icon.createWithResource(resources,
                             R.drawable.desktop_mode_ic_handle_menu_fullscreen),
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt
index 7adec39..0bd3a54 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/bar/BubbleEducationViewController.kt
@@ -35,6 +35,7 @@
 import com.android.wm.shell.bubbles.BubbleEducationController
 import com.android.wm.shell.bubbles.BubbleViewProvider
 import com.android.wm.shell.bubbles.setup
+import com.android.wm.shell.shared.TypefaceUtils
 import com.android.wm.shell.shared.animation.PhysicsAnimator
 import com.android.wm.shell.shared.bubbles.BubblePopupDrawable
 import com.android.wm.shell.shared.bubbles.BubblePopupView
@@ -108,6 +109,10 @@
         root.getBoundsOnScreen(rootBounds)
         educationView =
             createEducationView(R.layout.bubble_bar_stack_education, root).apply {
+                TypefaceUtils.setTypeface(findViewById(R.id.education_title),
+                    TypefaceUtils.FontFamily.GSF_HEADLINE_SMALL_EMPHASIZED)
+                TypefaceUtils.setTypeface(findViewById(R.id.education_text),
+                    TypefaceUtils.FontFamily.GSF_BODY_MEDIUM)
                 setArrowDirection(BubblePopupDrawable.ArrowDirection.DOWN)
                 updateEducationPosition(view = this, position, rootBounds)
                 val arrowToEdgeOffset = popupDrawable?.config?.cornerRadius ?: 0f
@@ -153,6 +158,10 @@
 
         educationView =
             createEducationView(R.layout.bubble_bar_manage_education, root).apply {
+                TypefaceUtils.setTypeface(findViewById(R.id.education_manage_title),
+                    TypefaceUtils.FontFamily.GSF_HEADLINE_SMALL_EMPHASIZED)
+                TypefaceUtils.setTypeface(findViewById(R.id.education_manage_text),
+                    TypefaceUtils.FontFamily.GSF_BODY_MEDIUM)
                 pivotY = 0f
                 doOnLayout { it.pivotX = it.width / 2f }
                 setOnClickListener { hideEducation(animated = true) }
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 f737884..bc76a87 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
@@ -468,10 +468,12 @@
             }
         }
 
-        private void setAnimating(boolean imeAnimationOngoing) {
+        private void setAnimating(boolean imeAnimationOngoing,
+                @Nullable ImeTracker.Token statsToken) {
             int animatingTypes = imeAnimationOngoing ? WindowInsets.Type.ime() : 0;
             try {
-                mWmService.updateDisplayWindowAnimatingTypes(mDisplayId, animatingTypes);
+                mWmService.updateDisplayWindowAnimatingTypes(mDisplayId, animatingTypes,
+                        statsToken);
             } catch (RemoteException e) {
             }
         }
@@ -635,7 +637,9 @@
                                 + " showing:" + (mAnimationDirection == DIRECTION_SHOW));
                     }
                     if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) {
-                        setAnimating(true /* imeAnimationOngoing */);
+                        // Updating the animatingTypes when starting the animation is not the
+                        // trigger to show the IME. Thus, not sending the statsToken here.
+                        setAnimating(true /* imeAnimationOngoing */, null /* statsToken */);
                     }
                     int flags = dispatchStartPositioning(mDisplayId, imeTop(hiddenY, defaultY),
                             imeTop(shownY, defaultY), mAnimationDirection == DIRECTION_SHOW,
@@ -685,7 +689,8 @@
                     if (!android.view.inputmethod.Flags.refactorInsetsController()) {
                         dispatchEndPositioning(mDisplayId, mCancelled, t);
                     } else if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) {
-                        setAnimating(false /* imeAnimationOngoing */);
+                        setAnimating(false /* imeAnimationOngoing */,
+                                mAnimationDirection == DIRECTION_HIDE ? statsToken : null);
                     }
                     if (mAnimationDirection == DIRECTION_HIDE && !mCancelled) {
                         ImeTracker.forLogging().onProgress(mStatsToken,
@@ -695,7 +700,12 @@
                             removeImeSurface(mDisplayId);
                         }
                         if (android.view.inputmethod.Flags.refactorInsetsController()) {
-                            setVisibleDirectly(false /* visible */, statsToken);
+                            // Updating the client visibility will not hide the IME, unless it is
+                            // not animating anymore. Thus, not sending a statsToken here, but
+                            // only later when we're updating the animatingTypes.
+                            setVisibleDirectly(false /* visible */,
+                                    !android.view.inputmethod.Flags.reportAnimatingInsetsTypes()
+                                            ? statsToken : null);
                         }
                         if (!android.view.inputmethod.Flags.refactorInsetsController()) {
                             ImeTracker.forLogging().onHidden(mStatsToken);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
index c4696d5..a8e6b59 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/SyncTransactionQueue.java
@@ -20,17 +20,14 @@
 
 import android.annotation.BinderThread;
 import android.annotation.NonNull;
-import android.os.RemoteException;
 import android.util.Slog;
 import android.view.SurfaceControl;
-import android.view.WindowManager;
 import android.window.WindowContainerTransaction;
 import android.window.WindowContainerTransactionCallback;
 import android.window.WindowOrganizer;
 
 import com.android.internal.protolog.ProtoLog;
 import com.android.wm.shell.shared.TransactionPool;
-import com.android.wm.shell.transition.LegacyTransitions;
 
 import java.util.ArrayList;
 
@@ -87,25 +84,6 @@
     }
 
     /**
-     * Queues a legacy transition to be sent serially to WM
-     */
-    public void queue(LegacyTransitions.ILegacyTransition transition,
-            @WindowManager.TransitionType int type, WindowContainerTransaction wct) {
-        if (wct.isEmpty()) {
-            if (DEBUG) Slog.d(TAG, "Skip queue due to transaction change is empty");
-            return;
-        }
-        SyncCallback cb = new SyncCallback(transition, type, wct);
-        synchronized (mQueue) {
-            if (DEBUG) Slog.d(TAG, "Queueing up legacy transition " + wct);
-            mQueue.add(cb);
-            if (mQueue.size() == 1) {
-                cb.send();
-            }
-        }
-    }
-
-    /**
      * Queues a sync transaction only if there are already sync transaction(s) queued or in flight.
      * Otherwise just returns without queueing.
      * @return {@code true} if queued, {@code false} if not.
@@ -168,17 +146,9 @@
     private class SyncCallback extends WindowContainerTransactionCallback {
         int mId = -1;
         final WindowContainerTransaction mWCT;
-        final LegacyTransitions.LegacyTransition mLegacyTransition;
 
         SyncCallback(WindowContainerTransaction wct) {
             mWCT = wct;
-            mLegacyTransition = null;
-        }
-
-        SyncCallback(LegacyTransitions.ILegacyTransition legacyTransition,
-                @WindowManager.TransitionType int type, WindowContainerTransaction wct) {
-            mWCT = wct;
-            mLegacyTransition = new LegacyTransitions.LegacyTransition(type, legacyTransition);
         }
 
         // Must be sychronized on mQueue
@@ -194,12 +164,7 @@
             }
             if (DEBUG) Slog.d(TAG, "Sending sync transaction: " + mWCT);
             try {
-                if (mLegacyTransition != null) {
-                    mId = new WindowOrganizer().startLegacyTransition(mLegacyTransition.getType(),
-                            mLegacyTransition.getAdapter(), this, mWCT);
-                } else {
-                    mId = new WindowOrganizer().applySyncTransaction(mWCT, this);
-                }
+                mId = new WindowOrganizer().applySyncTransaction(mWCT, this);
             } catch (RuntimeException e) {
                 Slog.e(TAG, "Send failed", e);
                 // Finish current sync callback immediately.
@@ -228,18 +193,10 @@
                     if (DEBUG) Slog.d(TAG, "onTransactionReady id=" + mId);
                     mQueue.remove(this);
                     onTransactionReceived(t);
-                    if (mLegacyTransition != null) {
-                        try {
-                            mLegacyTransition.getSyncCallback().onTransactionReady(mId, t);
-                        } catch (RemoteException e) {
-                            Slog.e(TAG, "Error sending callback to legacy transition: " + mId, e);
-                        }
-                    } else {
-                        ProtoLog.v(WM_SHELL,
-                                "SyncTransactionQueue.onTransactionReady(): syncId=%d apply", id);
-                        t.apply();
-                        t.close();
-                    }
+                    ProtoLog.v(WM_SHELL,
+                            "SyncTransactionQueue.onTransactionReady(): syncId=%d apply", id);
+                    t.apply();
+                    t.close();
                     if (!mQueue.isEmpty()) {
                         mQueue.get(0).send();
                     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index fec1f56..2b0885e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -559,7 +559,12 @@
                 true /* setEffectBounds */);
     }
 
-    /** Updates recording bounds of divider window and both of the splits. */
+    /**
+     * Updates the bounds of the divider window and both split apps.
+     * @param position The left/top edge of the visual divider, where the edge of app A meets the
+     *                 divider. Not to be confused with the actual divider surface, which is larger
+     *                 and overlaps the apps a bit.
+     */
     private void updateBounds(int position, Rect bounds1, Rect bounds2, Rect dividerBounds,
             boolean setEffectBounds) {
         dividerBounds.set(mRootBounds);
@@ -574,10 +579,11 @@
 
             // For flexible split, expand app offscreen as well
             if (mDividerSnapAlgorithm.areOffscreenRatiosSupported()) {
-                if (position <= mDividerSnapAlgorithm.getMiddleTarget().position) {
-                    bounds1.left = bounds1.right - bounds2.width();
+                int distanceToCenter = position - mDividerSnapAlgorithm.getMiddleTarget().position;
+                if (position < mDividerSnapAlgorithm.getMiddleTarget().position) {
+                    bounds1.left += distanceToCenter * 2;
                 } else {
-                    bounds2.right = bounds2.left + bounds1.width();
+                    bounds2.right += distanceToCenter * 2;
                 }
             }
 
@@ -590,10 +596,11 @@
 
             // For flexible split, expand app offscreen as well
             if (mDividerSnapAlgorithm.areOffscreenRatiosSupported()) {
-                if (position <= mDividerSnapAlgorithm.getMiddleTarget().position) {
-                    bounds1.top = bounds1.bottom - bounds2.height();
+                int distanceToCenter = position - mDividerSnapAlgorithm.getMiddleTarget().position;
+                if (position < mDividerSnapAlgorithm.getMiddleTarget().position) {
+                    bounds1.top += distanceToCenter * 2;
                 } else {
-                    bounds2.bottom = bounds2.top + bounds1.height();
+                    bounds2.bottom += distanceToCenter * 2;
                 }
             }
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt
index 812cc01..bcbe123 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterbox/LetterboxInputDetector.kt
@@ -167,6 +167,7 @@
 
                 windowSession.updateInputChannel(
                     inputChannel.token,
+                    null /* hostInputTransferToken */,
                     displayId,
                     inputSurface,
                     WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 318cdee..f62fd819 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -95,6 +95,7 @@
 import com.android.wm.shell.desktopmode.DesktopMode;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.desktopmode.DesktopUserRepositories;
+import com.android.wm.shell.desktopmode.common.DefaultHomePackageSupplier;
 import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelper;
 import com.android.wm.shell.displayareahelper.DisplayAreaHelperController;
@@ -260,8 +261,14 @@
 
     @WMSingleton
     @Provides
-    static DesktopModeCompatPolicy provideDesktopModeCompatPolicy(Context context) {
-        return new DesktopModeCompatPolicy(context);
+    static DesktopModeCompatPolicy provideDesktopModeCompatPolicy(
+            Context context,
+            ShellInit shellInit,
+            @ShellMainThread Handler mainHandler) {
+        final DesktopModeCompatPolicy policy = new DesktopModeCompatPolicy(context);
+        policy.setDefaultHomePackageSupplier(new DefaultHomePackageSupplier(
+                context, shellInit, mainHandler));
+        return policy;
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index bc2ed3f..2cf671b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -98,6 +98,7 @@
 import com.android.wm.shell.desktopmode.DesktopModeLoggerTransitionObserver;
 import com.android.wm.shell.desktopmode.DesktopModeMoveToDisplayTransitionHandler;
 import com.android.wm.shell.desktopmode.DesktopModeUiEventLogger;
+import com.android.wm.shell.desktopmode.DesktopPipTransitionObserver;
 import com.android.wm.shell.desktopmode.DesktopTaskChangeListener;
 import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.desktopmode.DesktopTasksLimiter;
@@ -780,6 +781,7 @@
             OverviewToDesktopTransitionObserver overviewToDesktopTransitionObserver,
             DesksOrganizer desksOrganizer,
             Optional<DesksTransitionObserver> desksTransitionObserver,
+            Optional<DesktopPipTransitionObserver> desktopPipTransitionObserver,
             UserProfileContexts userProfileContexts,
             DesktopModeCompatPolicy desktopModeCompatPolicy,
             DragToDisplayTransitionHandler dragToDisplayTransitionHandler,
@@ -823,6 +825,7 @@
                 overviewToDesktopTransitionObserver,
                 desksOrganizer,
                 desksTransitionObserver.get(),
+                desktopPipTransitionObserver,
                 userProfileContexts,
                 desktopModeCompatPolicy,
                 dragToDisplayTransitionHandler,
@@ -966,8 +969,15 @@
 
     @WMSingleton
     @Provides
-    static DesktopModeMoveToDisplayTransitionHandler provideMoveToDisplayTransitionHandler() {
-        return new DesktopModeMoveToDisplayTransitionHandler(new SurfaceControl.Transaction());
+    static DesktopModeMoveToDisplayTransitionHandler provideMoveToDisplayTransitionHandler(
+            InteractionJankMonitor interactionJankMonitor,
+            @ShellMainThread Handler shellMainHandler,
+            DisplayController displayController) {
+        return new DesktopModeMoveToDisplayTransitionHandler(
+                new SurfaceControl.Transaction(),
+                interactionJankMonitor,
+                shellMainHandler,
+                displayController);
     }
 
     @WMSingleton
@@ -1225,6 +1235,7 @@
             Transitions transitions,
             ShellTaskOrganizer shellTaskOrganizer,
             Optional<DesktopMixedTransitionHandler> desktopMixedTransitionHandler,
+            Optional<DesktopPipTransitionObserver> desktopPipTransitionObserver,
             Optional<BackAnimationController> backAnimationController,
             DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider,
             ShellInit shellInit) {
@@ -1237,6 +1248,7 @@
                                         transitions,
                                         shellTaskOrganizer,
                                         desktopMixedTransitionHandler.get(),
+                                        desktopPipTransitionObserver,
                                         backAnimationController.get(),
                                         desktopWallpaperActivityTokenProvider,
                                         shellInit)));
@@ -1258,6 +1270,19 @@
 
     @WMSingleton
     @Provides
+    static Optional<DesktopPipTransitionObserver> provideDesktopPipTransitionObserver(
+            Context context
+    ) {
+        if (DesktopModeStatus.canEnterDesktopMode(context)
+                && DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue()) {
+            return Optional.of(
+                    new DesktopPipTransitionObserver());
+        }
+        return Optional.empty();
+    }
+
+    @WMSingleton
+    @Provides
     static Optional<DesktopMixedTransitionHandler> provideDesktopMixedTransitionHandler(
             Context context,
             Transitions transitions,
@@ -1474,6 +1499,7 @@
             ShellTaskOrganizer shellTaskOrganizer,
             DesktopWallpaperActivityTokenProvider desktopWallpaperActivityTokenProvider,
             InputManager inputManager,
+            DisplayController displayController,
             @ShellMainThread Handler mainHandler
     ) {
         if (!DesktopModeStatus.canEnterDesktopMode(context)) {
@@ -1488,6 +1514,7 @@
                         shellTaskOrganizer,
                         desktopWallpaperActivityTokenProvider,
                         inputManager,
+                        displayController,
                         mainHandler));
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt
index 904d862..ea2fdc0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt
@@ -28,6 +28,7 @@
 import android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS
 import android.view.Display.DEFAULT_DISPLAY
 import android.view.IWindowManager
+import android.view.InputDevice
 import android.view.WindowManager.TRANSIT_CHANGE
 import android.window.DesktopExperienceFlags
 import android.window.WindowContainerTransaction
@@ -35,9 +36,11 @@
 import com.android.internal.protolog.ProtoLog
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.ShellTaskOrganizer
+import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
 import com.android.wm.shell.shared.annotations.ShellMainThread
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.transition.Transitions
 
 /** Controls the display windowing mode in desktop mode */
@@ -49,6 +52,7 @@
     private val shellTaskOrganizer: ShellTaskOrganizer,
     private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider,
     private val inputManager: InputManager,
+    private val displayController: DisplayController,
     @ShellMainThread private val mainHandler: Handler,
 ) {
 
@@ -59,12 +63,28 @@
             }
         }
 
+    private val inputDeviceListener =
+        object : InputManager.InputDeviceListener {
+            override fun onInputDeviceAdded(deviceId: Int) {
+                refreshDisplayWindowingMode()
+            }
+
+            override fun onInputDeviceChanged(deviceId: Int) {
+                refreshDisplayWindowingMode()
+            }
+
+            override fun onInputDeviceRemoved(deviceId: Int) {
+                refreshDisplayWindowingMode()
+            }
+        }
+
     init {
         if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) {
             inputManager.registerOnTabletModeChangedListener(
                 onTabletModeChangedListener,
                 mainHandler,
             )
+            inputManager.registerInputDeviceListener(inputDeviceListener, mainHandler)
         }
     }
 
@@ -111,37 +131,75 @@
         transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null)
     }
 
-    @VisibleForTesting
-    fun getTargetWindowingModeForDefaultDisplay(): Int {
-        if (isExtendedDisplayEnabled() && hasExternalDisplay()) {
-            return WINDOWING_MODE_FREEFORM
-        }
-        if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) {
-            if (isInClamshellMode()) {
-                return WINDOWING_MODE_FREEFORM
+    // Do not directly use this method to check the state of desktop-first mode. Check the display
+    // windowing mode instead.
+    private fun canDesktopFirstModeBeEnabledOnDefaultDisplay(): Boolean {
+        if (isDefaultDisplayDesktopEligible()) {
+            if (isExtendedDisplayEnabled() && hasExternalDisplay()) {
+                return true
             }
-            return WINDOWING_MODE_FULLSCREEN
+            if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) {
+                if (isInClamshellMode() || hasAnyMouseDevice()) {
+                    return true
+                }
+            }
         }
-
-        // If form factor-based desktop first switch is disabled, use the default display windowing
-        // mode here to keep the freeform mode for some form factors (e.g., FEATURE_PC).
-        return windowManager.getWindowingMode(DEFAULT_DISPLAY)
+        return false
     }
 
-    // TODO: b/375319538 - Replace the check with a DisplayManager API once it's available.
-    private fun isExtendedDisplayEnabled() =
-        0 !=
+    @VisibleForTesting
+    fun getTargetWindowingModeForDefaultDisplay(): Int {
+        if (canDesktopFirstModeBeEnabledOnDefaultDisplay()) {
+            return WINDOWING_MODE_FREEFORM
+        }
+
+        return if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) {
+            WINDOWING_MODE_FULLSCREEN
+        } else {
+            // If form factor-based desktop first switch is disabled, use the default display
+            // windowing mode here to keep the freeform mode for some form factors (e.g.,
+            // FEATURE_PC).
+            windowManager.getWindowingMode(DEFAULT_DISPLAY)
+        }
+    }
+
+    private fun isExtendedDisplayEnabled(): Boolean {
+        if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue) {
+            return rootTaskDisplayAreaOrganizer
+                .getDisplayIds()
+                .filter { it != DEFAULT_DISPLAY }
+                .any { displayId ->
+                    displayController.getDisplay(displayId)?.let { display ->
+                        DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display)
+                    } ?: false
+                }
+        }
+
+        return 0 !=
             Settings.Global.getInt(
                 context.contentResolver,
                 DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
                 0,
             )
+    }
 
     private fun hasExternalDisplay() =
         rootTaskDisplayAreaOrganizer.getDisplayIds().any { it != DEFAULT_DISPLAY }
 
+    private fun hasAnyMouseDevice() =
+        inputManager.inputDeviceIds.any {
+            inputManager.getInputDevice(it)?.supportsSource(InputDevice.SOURCE_MOUSE) == true
+        }
+
     private fun isInClamshellMode() = inputManager.isInTabletMode() == InputManager.SWITCH_STATE_OFF
 
+    private fun isDefaultDisplayDesktopEligible(): Boolean {
+        val display = requireNotNull(displayController.getDisplay(DEFAULT_DISPLAY)) {
+            "Display object of DEFAULT_DISPLAY must be non-null."
+        }
+        return DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display)
+    }
+
     private fun logV(msg: String, vararg arguments: Any?) {
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt
index 91bd3c9..844a1f8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandler.kt
@@ -19,19 +19,26 @@
 import android.animation.Animator
 import android.animation.AnimatorSet
 import android.animation.ValueAnimator
+import android.os.Handler
 import android.os.IBinder
 import android.view.Choreographer
 import android.view.SurfaceControl
 import android.window.TransitionInfo
 import android.window.TransitionRequestInfo
 import android.window.WindowContainerTransaction
+import com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY
+import com.android.internal.jank.InteractionJankMonitor
+import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.shared.animation.Interpolators
 import com.android.wm.shell.transition.Transitions
 import kotlin.time.Duration.Companion.milliseconds
 
 /** Transition handler for moving a window to a different display. */
 class DesktopModeMoveToDisplayTransitionHandler(
-    private val animationTransaction: SurfaceControl.Transaction
+    private val animationTransaction: SurfaceControl.Transaction,
+    private val interactionJankMonitor: InteractionJankMonitor,
+    private val shellMainHandler: Handler,
+    private val displayController: DisplayController,
 ) : Transitions.TransitionHandler {
 
     override fun handleRequest(
@@ -74,18 +81,31 @@
                 }
             }
         )
+
         animator.addListener(
             object : Animator.AnimatorListener {
-                override fun onAnimationStart(animation: Animator) = Unit
+                override fun onAnimationStart(animation: Animator) {
+                    val displayContext =
+                        displayController.getDisplayContext(changes[0].endDisplayId)
+                    if (displayContext == null) return
+                    interactionJankMonitor.begin(
+                        changes[0].leash,
+                        displayContext,
+                        shellMainHandler,
+                        CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY,
+                    )
+                }
 
                 override fun onAnimationEnd(animation: Animator) {
                     finishTransaction.apply()
                     finishCallback.onTransitionFinished(null)
+                    interactionJankMonitor.end(CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY)
                 }
 
                 override fun onAnimationCancel(animation: Animator) {
                     finishTransaction.apply()
                     finishCallback.onTransitionFinished(null)
+                    interactionJankMonitor.cancel(CUJ_DESKTOP_MODE_MOVE_WINDOW_TO_DISPLAY)
                 }
 
                 override fun onAnimationRepeat(animation: Animator) = Unit
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
index 1938e76..1c5138f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicator.java
@@ -21,10 +21,13 @@
 
 import static com.android.internal.policy.SystemBarUtils.getDesktopViewAppHeaderHeightPx;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR;
+import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_DESKTOP_INDICATOR;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR;
+import static com.android.wm.shell.shared.ShellSharedConstants.SMALL_TABLET_MAX_EDGE_DP;
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -33,6 +36,7 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
+import android.util.Pair;
 import android.view.Display;
 import android.view.SurfaceControl;
 import android.window.DesktopModeFlags;
@@ -46,13 +50,17 @@
 import com.android.wm.shell.common.DisplayLayout;
 import com.android.wm.shell.common.ShellExecutor;
 import com.android.wm.shell.common.SyncTransactionQueue;
+import com.android.wm.shell.common.split.SplitScreenUtils;
 import com.android.wm.shell.shared.annotations.ShellDesktopThread;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.shared.bubbles.BubbleAnythingFlagHelper;
 import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider;
-import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.windowdecor.tiling.SnapEventHandler;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * Animated visual indicator for Desktop Mode windowing transitions.
  */
@@ -116,12 +124,20 @@
     private final Context mContext;
     private final DisplayController mDisplayController;
     private final ActivityManager.RunningTaskInfo mTaskInfo;
-    private final Display mDisplay;
 
     private IndicatorType mCurrentType;
     private final DragStartState mDragStartState;
     private final SnapEventHandler mSnapEventHandler;
 
+    private final boolean mUseSmallTabletRegions;
+    /**
+     * Ordered list of {@link Rect} zones that we will match an input coordinate against.
+     * List is traversed from first to last element. The first rect that contains the input event
+     * will be used and the matching {@link IndicatorType} is returned.
+     * Empty rect matches all.
+     */
+    private final List<Pair<Rect, IndicatorType>> mSortedRegions;
+
     public DesktopModeVisualIndicator(@ShellDesktopThread ShellExecutor desktopExecutor,
             @ShellMainThread ShellExecutor mainExecutor,
             SyncTransactionQueue syncQueue,
@@ -131,6 +147,24 @@
             DragStartState dragStartState,
             @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider,
             SnapEventHandler snapEventHandler) {
+        this(desktopExecutor, mainExecutor, syncQueue, taskInfo, displayController, context,
+                taskSurface, taskDisplayAreaOrganizer, dragStartState, bubbleBoundsProvider,
+                snapEventHandler, useSmallTabletRegions(displayController, taskInfo),
+                isLeftRightSplit(context, displayController, taskInfo));
+    }
+
+    @VisibleForTesting
+    DesktopModeVisualIndicator(@ShellDesktopThread ShellExecutor desktopExecutor,
+            @ShellMainThread ShellExecutor mainExecutor,
+            SyncTransactionQueue syncQueue,
+            ActivityManager.RunningTaskInfo taskInfo, DisplayController displayController,
+            Context context, SurfaceControl taskSurface,
+            RootTaskDisplayAreaOrganizer taskDisplayAreaOrganizer,
+            DragStartState dragStartState,
+            @Nullable BubbleDropTargetBoundsProvider bubbleBoundsProvider,
+            SnapEventHandler snapEventHandler,
+            boolean useSmallTabletRegions,
+            boolean isLeftRightSplit) {
         SurfaceControl.Builder builder = new SurfaceControl.Builder();
         if (!DragStartState.isDragToDesktopStartState(dragStartState)
                 || !DesktopModeFlags.ENABLE_VISUAL_INDICATOR_IN_TRANSITION_BUGFIX.isTrue()) {
@@ -148,14 +182,46 @@
         mCurrentType = NO_INDICATOR;
         mDragStartState = dragStartState;
         mSnapEventHandler = snapEventHandler;
-        mDisplay = mDisplayController.getDisplay(mTaskInfo.displayId);
+        Display display = mDisplayController.getDisplay(mTaskInfo.displayId);
+        DisplayLayout displayLayout = mDisplayController.getDisplayLayout(mTaskInfo.displayId);
         mVisualIndicatorViewContainer.createView(
                 mContext,
-                mDisplay,
-                mDisplayController.getDisplayLayout(mTaskInfo.displayId),
+                display,
+                displayLayout,
                 mTaskInfo,
                 taskSurface
         );
+
+        mUseSmallTabletRegions = useSmallTabletRegions;
+
+        if (useSmallTabletRegions) {
+            mSortedRegions = initSmallTabletRegions(displayLayout, isLeftRightSplit);
+        } else {
+            // TODO(b/401596837): add support for initializing regions for large tablets
+            mSortedRegions = Collections.emptyList();
+        }
+    }
+
+    private static boolean useSmallTabletRegions(DisplayController displayController,
+            ActivityManager.RunningTaskInfo taskInfo) {
+        if (!BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
+            // Small tablet regions get enabled with bubbles feature
+            return false;
+        }
+        Display display = displayController.getDisplay(taskInfo.displayId);
+        DisplayLayout displayLayout = displayController.getDisplayLayout(taskInfo.displayId);
+        if (displayLayout == null) return false;
+        return displayLayout.pxToDp(display.getMaximumSizeDimension()) < SMALL_TABLET_MAX_EDGE_DP;
+    }
+
+    private static boolean isLeftRightSplit(Context context, DisplayController displayController,
+            ActivityManager.RunningTaskInfo taskInfo) {
+        DisplayLayout layout = displayController.getDisplayLayout(taskInfo.displayId);
+        boolean landscape = layout != null && layout.isLandscape();
+        boolean leftRightSplitInPortrait = SplitScreenUtils.allowLeftRightSplitInPortrait(
+                context.getResources());
+        return SplitScreenUtils.isLeftRightSplit(leftRightSplitInPortrait,
+                /* isLargeScreen= */ true, landscape);
     }
 
     /** Start the fade out animation, running the callback on the main thread once it is done. */
@@ -191,33 +257,44 @@
      */
     @NonNull
     IndicatorType updateIndicatorType(PointF inputCoordinates) {
+        final IndicatorType result;
+        if (mUseSmallTabletRegions) {
+            result = getIndicatorSmallTablet(inputCoordinates);
+        } else {
+            result = getIndicatorLargeTablet(inputCoordinates);
+        }
+        if (mDragStartState != DragStartState.DRAGGED_INTENT) {
+            mVisualIndicatorViewContainer.transitionIndicator(
+                    mTaskInfo, mDisplayController, mCurrentType, result
+            );
+            mCurrentType = result;
+        }
+        return result;
+    }
+
+    @NonNull
+    private IndicatorType getIndicatorLargeTablet(PointF inputCoordinates) {
+        // TODO(b/401596837): cache the regions to avoid recalculating on each motion event
         final DisplayLayout layout = mDisplayController.getDisplayLayout(mTaskInfo.displayId);
         // Perform a quick check first: any input off the left edge of the display should be split
         // left, and split right for the right edge. This is universal across all drag event types.
         if (inputCoordinates.x < 0) return TO_SPLIT_LEFT_INDICATOR;
         if (inputCoordinates.x > layout.width()) return TO_SPLIT_RIGHT_INDICATOR;
-        IndicatorType result;
-        if (BubbleAnythingFlagHelper.enableBubbleToFullscreen()
-                && !DesktopModeStatus.isDesktopModeSupportedOnDisplay(mContext, mDisplay)) {
-            // If desktop is not available, default to "no indicator"
-            result = NO_INDICATOR;
-        } else {
-            // If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
-            // In drags not originating on a freeform caption, we should default to a TO_DESKTOP
-            // indicator.
-            result = mDragStartState == DragStartState.FROM_FREEFORM
+        // If we are in freeform, we don't want a visible indicator in the "freeform" drag zone.
+        // In drags not originating on a freeform caption, we should default to a TO_DESKTOP
+        // indicator.
+        IndicatorType result = mDragStartState == DragStartState.FROM_FREEFORM
                     ? NO_INDICATOR
                     : TO_DESKTOP_INDICATOR;
-        }
         final int transitionAreaWidth = mContext.getResources().getDimensionPixelSize(
                 com.android.wm.shell.R.dimen.desktop_mode_transition_region_thickness);
         // Because drags in freeform use task position for indicator calculation, we need to
         // account for the possibility of the task going off the top of the screen by captionHeight
         final int captionHeight = getDesktopViewAppHeaderHeightPx(mContext);
         final Region fullscreenRegion = calculateFullscreenRegion(layout, captionHeight);
-        final Region splitLeftRegion = calculateSplitLeftRegion(layout, transitionAreaWidth,
+        final Rect splitLeftRegion = calculateSplitLeftRegion(layout, transitionAreaWidth,
                 captionHeight);
-        final Region splitRightRegion = calculateSplitRightRegion(layout, transitionAreaWidth,
+        final Rect splitRightRegion = calculateSplitRightRegion(layout, transitionAreaWidth,
                 captionHeight);
         final int x = (int) inputCoordinates.x;
         final int y = (int) inputCoordinates.y;
@@ -234,18 +311,23 @@
             if (calculateBubbleLeftRegion(layout).contains(x, y)) {
                 result = IndicatorType.TO_BUBBLE_LEFT_INDICATOR;
             } else if (calculateBubbleRightRegion(layout).contains(x, y)) {
-                result = IndicatorType.TO_BUBBLE_RIGHT_INDICATOR;
+                result = TO_BUBBLE_RIGHT_INDICATOR;
             }
         }
-        if (mDragStartState != DragStartState.DRAGGED_INTENT) {
-            mVisualIndicatorViewContainer.transitionIndicator(
-                    mTaskInfo, mDisplayController, mCurrentType, result
-            );
-            mCurrentType = result;
-        }
         return result;
     }
 
+    @NonNull
+    private IndicatorType getIndicatorSmallTablet(PointF inputCoordinates) {
+        for (Pair<Rect, IndicatorType> region : mSortedRegions) {
+            if (region.first.isEmpty()) return region.second; // empty rect matches all
+            if (region.first.contains((int) inputCoordinates.x, (int) inputCoordinates.y)) {
+                return region.second;
+            }
+        }
+        return NO_INDICATOR;
+    }
+
     /**
      * Returns the [DragStartState] of the visual indicator.
      */
@@ -284,53 +366,79 @@
     }
 
     @VisibleForTesting
-    Region calculateSplitLeftRegion(DisplayLayout layout,
+    Rect calculateSplitLeftRegion(DisplayLayout layout,
             int transitionEdgeWidth, int captionHeight) {
-        final Region region = new Region();
         // In freeform, keep the top corners clear.
         int transitionHeight = mDragStartState == DragStartState.FROM_FREEFORM
                 ? mContext.getResources().getDimensionPixelSize(
                 com.android.wm.shell.R.dimen.desktop_mode_split_from_desktop_height) :
                 -captionHeight;
-        region.union(new Rect(0, transitionHeight, transitionEdgeWidth, layout.height()));
-        return region;
+        return new Rect(0, transitionHeight, transitionEdgeWidth, layout.height());
     }
 
     @VisibleForTesting
-    Region calculateSplitRightRegion(DisplayLayout layout,
+    Rect calculateSplitRightRegion(DisplayLayout layout,
             int transitionEdgeWidth, int captionHeight) {
-        final Region region = new Region();
         // In freeform, keep the top corners clear.
         int transitionHeight = mDragStartState == DragStartState.FROM_FREEFORM
                 ? mContext.getResources().getDimensionPixelSize(
                 com.android.wm.shell.R.dimen.desktop_mode_split_from_desktop_height) :
                 -captionHeight;
-        region.union(new Rect(layout.width() - transitionEdgeWidth, transitionHeight,
-                layout.width(), layout.height()));
-        return region;
-    }
-
-    @VisibleForTesting
-    Region calculateBubbleLeftRegion(DisplayLayout layout) {
-        int regionWidth = mContext.getResources().getDimensionPixelSize(
-                com.android.wm.shell.R.dimen.bubble_transform_area_width);
-        int regionHeight = mContext.getResources().getDimensionPixelSize(
-                com.android.wm.shell.R.dimen.bubble_transform_area_height);
-        return new Region(0, layout.height() - regionHeight, regionWidth, layout.height());
-    }
-
-    @VisibleForTesting
-    Region calculateBubbleRightRegion(DisplayLayout layout) {
-        int regionWidth = mContext.getResources().getDimensionPixelSize(
-                com.android.wm.shell.R.dimen.bubble_transform_area_width);
-        int regionHeight = mContext.getResources().getDimensionPixelSize(
-                com.android.wm.shell.R.dimen.bubble_transform_area_height);
-        return new Region(layout.width() - regionWidth, layout.height() - regionHeight,
+        return new Rect(layout.width() - transitionEdgeWidth, transitionHeight,
                 layout.width(), layout.height());
     }
 
     @VisibleForTesting
+    Rect calculateBubbleLeftRegion(DisplayLayout layout) {
+        int regionSize = getBubbleRegionSize();
+        return new Rect(0, layout.height() - regionSize, regionSize, layout.height());
+    }
+
+    @VisibleForTesting
+    Rect calculateBubbleRightRegion(DisplayLayout layout) {
+        int regionSize = getBubbleRegionSize();
+        return new Rect(layout.width() - regionSize, layout.height() - regionSize,
+                layout.width(), layout.height());
+    }
+
+    private int getBubbleRegionSize() {
+        int resId = mUseSmallTabletRegions
+                ? com.android.wm.shell.shared.R.dimen.drag_zone_bubble_fold
+                : com.android.wm.shell.shared.R.dimen.drag_zone_bubble_tablet;
+        return mContext.getResources().getDimensionPixelSize(resId);
+    }
+
+    @VisibleForTesting
     Rect getIndicatorBounds() {
         return mVisualIndicatorViewContainer.getIndicatorBounds();
     }
+
+    private List<Pair<Rect, IndicatorType>> initSmallTabletRegions(DisplayLayout layout,
+            boolean isLeftRightSplit) {
+        boolean dragFromFullscreen = mDragStartState == DragStartState.FROM_FULLSCREEN;
+        boolean dragFromSplit = mDragStartState == DragStartState.FROM_SPLIT;
+        if (isLeftRightSplit && (dragFromFullscreen || dragFromSplit)) {
+            int splitRegionWidth = mContext.getResources().getDimensionPixelSize(
+                    com.android.wm.shell.shared.R.dimen.drag_zone_h_split_from_app_width_fold);
+            return Arrays.asList(
+                    new Pair<>(calculateBubbleLeftRegion(layout), TO_BUBBLE_LEFT_INDICATOR),
+                    new Pair<>(calculateBubbleRightRegion(layout), TO_BUBBLE_RIGHT_INDICATOR),
+                    new Pair<>(calculateSplitLeftRegion(layout, splitRegionWidth,
+                            /* captionHeight= */ 0), TO_SPLIT_LEFT_INDICATOR),
+                    new Pair<>(calculateSplitRightRegion(layout, splitRegionWidth,
+                            /* captionHeight= */ 0), TO_SPLIT_RIGHT_INDICATOR),
+                    new Pair<>(new Rect(), TO_FULLSCREEN_INDICATOR) // default to fullscreen
+            );
+        }
+        if (dragFromFullscreen) {
+            // If left/right split is not available, we can only drag fullscreen tasks
+            // TODO(b/401352409): add support for top/bottom split zones
+            return Arrays.asList(
+                    new Pair<>(calculateBubbleLeftRegion(layout), TO_BUBBLE_LEFT_INDICATOR),
+                    new Pair<>(calculateBubbleRightRegion(layout), TO_BUBBLE_RIGHT_INDICATOR),
+                    new Pair<>(new Rect(), TO_FULLSCREEN_INDICATOR) // default to fullscreen
+            );
+        }
+        return Collections.emptyList();
+    }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt
new file mode 100644
index 0000000..efd3866
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserver.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.desktopmode
+
+import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
+import android.os.IBinder
+import android.window.DesktopModeFlags
+import android.window.TransitionInfo
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
+
+/**
+ * Observer of PiP in Desktop Mode transitions. At the moment, this is specifically tracking a PiP
+ * transition for a task that is entering PiP via the minimize button on the caption bar.
+ */
+class DesktopPipTransitionObserver {
+    private val pendingPipTransitions = mutableMapOf<IBinder, PendingPipTransition>()
+
+    /** Adds a pending PiP transition to be tracked. */
+    fun addPendingPipTransition(transition: PendingPipTransition) {
+        if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue) return
+        pendingPipTransitions[transition.token] = transition
+    }
+
+    /**
+     * Called when any transition is ready, which may include transitions not tracked by this
+     * observer.
+     */
+    fun onTransitionReady(transition: IBinder, info: TransitionInfo) {
+        if (!DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue) return
+        val pipTransition = pendingPipTransitions.remove(transition) ?: return
+
+        logD("Desktop PiP transition ready: %s", transition)
+        for (change in info.changes) {
+            val taskInfo = change.taskInfo
+            if (taskInfo == null || taskInfo.taskId == -1) {
+                continue
+            }
+
+            if (
+                taskInfo.taskId == pipTransition.taskId &&
+                    taskInfo.windowingMode == WINDOWING_MODE_PINNED
+            ) {
+                logD("Desktop PiP transition was successful")
+                pipTransition.onSuccess()
+                return
+            }
+        }
+        logD("Change with PiP task not found in Desktop PiP transition; likely failed")
+    }
+
+    /**
+     * Data tracked for a pending PiP transition.
+     *
+     * @property token the PiP transition that is started.
+     * @property taskId task id of the task entering PiP.
+     * @property onSuccess callback to be invoked if the PiP transition is successful.
+     */
+    data class PendingPipTransition(val token: IBinder, val taskId: Int, val onSuccess: () -> Unit)
+
+    private fun logD(msg: String, vararg arguments: Any?) {
+        ProtoLog.d(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+    }
+
+    private companion object {
+        private const val TAG = "DesktopPipTransitionObserver"
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
index a4e9c52..e77acfb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopRepository.kt
@@ -68,7 +68,8 @@
      * @property topTransparentFullscreenTaskId the task id of any current top transparent
      *   fullscreen task launched on top of the desk. Cleared when the transparent task is closed or
      *   sent to back. (top is at index 0).
-     * @property pipTaskId the task id of PiP task entered while in Desktop Mode.
+     * @property leftTiledTaskId task id of the task tiled on the left.
+     * @property rightTiledTaskId task id of the task tiled on the right.
      */
     private data class Desk(
         val deskId: Int,
@@ -81,7 +82,8 @@
         val freeformTasksInZOrder: ArrayList<Int> = ArrayList(),
         var fullImmersiveTaskId: Int? = null,
         var topTransparentFullscreenTaskId: Int? = null,
-        var pipTaskId: Int? = null,
+        var leftTiledTaskId: Int? = null,
+        var rightTiledTaskId: Int? = null,
     ) {
         fun deepCopy(): Desk =
             Desk(
@@ -94,7 +96,8 @@
                 freeformTasksInZOrder = ArrayList(freeformTasksInZOrder),
                 fullImmersiveTaskId = fullImmersiveTaskId,
                 topTransparentFullscreenTaskId = topTransparentFullscreenTaskId,
-                pipTaskId = pipTaskId,
+                leftTiledTaskId = leftTiledTaskId,
+                rightTiledTaskId = rightTiledTaskId,
             )
 
         // TODO: b/362720497 - remove when multi-desktops is enabled where instances aren't
@@ -107,7 +110,8 @@
             freeformTasksInZOrder.clear()
             fullImmersiveTaskId = null
             topTransparentFullscreenTaskId = null
-            pipTaskId = null
+            leftTiledTaskId = null
+            rightTiledTaskId = null
         }
     }
 
@@ -127,9 +131,6 @@
     /* Tracks last bounds of task before toggled to immersive state. */
     private val boundsBeforeFullImmersiveByTaskId = SparseArray<Rect>()
 
-    /* Callback for when a pending PiP transition has been aborted. */
-    private var onPipAbortedCallback: ((Int, Int) -> Unit)? = null
-
     private var desktopGestureExclusionListener: Consumer<Region>? = null
     private var desktopGestureExclusionExecutor: Executor? = null
 
@@ -275,6 +276,106 @@
         }
     }
 
+    /** Register a left tiled task to desktop state. */
+    fun addLeftTiledTask(displayId: Int, taskId: Int) {
+        logD("addLeftTiledTask for displayId=%d, taskId=%d", displayId, taskId)
+        val activeDesk =
+            checkNotNull(desktopData.getDefaultDesk(displayId)) {
+                "Expected desk in display: $displayId"
+            }
+        addLeftTiledTaskToDesk(displayId, taskId, activeDesk.deskId)
+    }
+
+    private fun addLeftTiledTaskToDesk(displayId: Int, taskId: Int, deskId: Int) {
+        logD("addLeftTiledTaskToDesk for displayId=%d, taskId=%d", displayId, taskId)
+        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
+        desk.leftTiledTaskId = taskId
+        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
+            updatePersistentRepository(displayId)
+        }
+    }
+
+    /** Register a right tiled task to desktop state. */
+    fun addRightTiledTask(displayId: Int, taskId: Int) {
+        logD("addRightTiledTask for displayId=%d, taskId=%d", displayId, taskId)
+        val activeDesk =
+            checkNotNull(desktopData.getDefaultDesk(displayId)) {
+                "Expected desk in display: $displayId"
+            }
+        addRightTiledTaskToDesk(displayId, taskId, activeDesk.deskId)
+    }
+
+    private fun addRightTiledTaskToDesk(displayId: Int, taskId: Int, deskId: Int) {
+        logD("addRightTiledTaskToDesk for displayId=%d, taskId=%d", displayId, taskId)
+        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
+        desk.rightTiledTaskId = taskId
+        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
+            updatePersistentRepository(displayId)
+        }
+    }
+
+    /** Gets a registered left tiled task to desktop state or returns null. */
+    fun getLeftTiledTask(displayId: Int): Int? {
+        logD("getLeftTiledTask for displayId=%d", displayId)
+        val activeDesk =
+            checkNotNull(desktopData.getDefaultDesk(displayId)) {
+                "Expected desk in display: $displayId"
+            }
+        val deskId = activeDesk.deskId
+        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
+        return desk.leftTiledTaskId
+    }
+
+    /** gets a registered right tiled task to desktop state or returns null. */
+    fun getRightTiledTask(displayId: Int): Int? {
+        logD("getRightTiledTask for displayId=%d", displayId)
+        val activeDesk =
+            checkNotNull(desktopData.getDefaultDesk(displayId)) {
+                "Expected desk in display: $displayId"
+            }
+        val deskId = activeDesk.deskId
+        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
+        return desk.rightTiledTaskId
+    }
+
+    /* Unregisters a left tiled task from desktop state. */
+    fun removeLeftTiledTask(displayId: Int) {
+        logD("removeLeftTiledTask for displayId=%d", displayId)
+        val activeDesk =
+            checkNotNull(desktopData.getDefaultDesk(displayId)) {
+                "Expected desk in display: $displayId"
+            }
+        removeLeftTiledTaskFromDesk(displayId, activeDesk.deskId)
+    }
+
+    private fun removeLeftTiledTaskFromDesk(displayId: Int, deskId: Int) {
+        logD("removeLeftTiledTaskToDesk for displayId=%d", displayId)
+        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
+        desk.leftTiledTaskId = null
+        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
+            updatePersistentRepository(displayId)
+        }
+    }
+
+    /* Unregisters a right tiled task from desktop state. */
+    fun removeRightTiledTask(displayId: Int) {
+        logD("removeRightTiledTask for displayId=%d", displayId)
+        val activeDesk =
+            checkNotNull(desktopData.getDefaultDesk(displayId)) {
+                "Expected desk in display: $displayId"
+            }
+        removeRightTiledTaskFromDesk(displayId, activeDesk.deskId)
+    }
+
+    private fun removeRightTiledTaskFromDesk(displayId: Int, deskId: Int) {
+        logD("removeRightTiledTaskFromDesk for displayId=%d", displayId)
+        val desk = checkNotNull(desktopData.getDesk(deskId)) { "Did not find desk: $deskId" }
+        desk.rightTiledTaskId = null
+        if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PERSISTENCE.isTrue()) {
+            updatePersistentRepository(displayId)
+        }
+    }
+
     /** Returns the id of the active desk in the given display, if any. */
     fun getActiveDeskId(displayId: Int): Int? = desktopData.getActiveDesk(displayId)?.deskId
 
@@ -611,57 +712,6 @@
     }
 
     /**
-     * Set whether the given task is the Desktop-entered PiP task in this display's active desk.
-     *
-     * TODO: b/389960283 - add explicit [deskId] argument.
-     */
-    fun setTaskInPip(displayId: Int, taskId: Int, enterPip: Boolean) {
-        val activeDesk =
-            desktopData.getActiveDesk(displayId)
-                ?: error("Expected active desk in display: $displayId")
-        if (enterPip) {
-            activeDesk.pipTaskId = taskId
-        } else {
-            activeDesk.pipTaskId =
-                if (activeDesk.pipTaskId == taskId) null
-                else {
-                    logW(
-                        "setTaskInPip: taskId=%d did not match saved taskId=%d",
-                        taskId,
-                        activeDesk.pipTaskId,
-                    )
-                    activeDesk.pipTaskId
-                }
-        }
-    }
-
-    /**
-     * Returns whether the given task is the Desktop-entered PiP task in this display's active desk.
-     *
-     * TODO: b/389960283 - add explicit [deskId] argument.
-     */
-    fun isTaskMinimizedPipInDisplay(displayId: Int, taskId: Int): Boolean =
-        desktopData.getActiveDesk(displayId)?.pipTaskId == taskId
-
-    /**
-     * Saves callback to handle a pending PiP transition being aborted.
-     *
-     * TODO: b/389960283 - add explicit [deskId] argument.
-     */
-    fun setOnPipAbortedCallback(callbackIfPipAborted: ((displayId: Int, pipTaskId: Int) -> Unit)?) {
-        onPipAbortedCallback = callbackIfPipAborted
-    }
-
-    /**
-     * Invokes callback to handle a pending PiP transition with the given task id being aborted.
-     *
-     * TODO: b/389960283 - add explicit [deskId] argument.
-     */
-    fun onPipAborted(displayId: Int, pipTaskId: Int) {
-        onPipAbortedCallback?.invoke(displayId, pipTaskId)
-    }
-
-    /**
      * Set whether the given task is the full-immersive task in this display's active desk.
      *
      * TODO: b/389960283 - consider forcing callers to use [setTaskInFullImmersiveStateInDesk] with
@@ -1030,6 +1080,8 @@
                 visibleTasks = desk.visibleTasks,
                 minimizedTasks = desk.minimizedTasks,
                 freeformTasksInZOrder = desk.freeformTasksInZOrder,
+                leftTiledTask = desk.leftTiledTaskId,
+                rightTiledTask = desk.rightTiledTaskId,
             )
         } catch (exception: Exception) {
             logE(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
index 7d83a8e..093e8ef 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksController.kt
@@ -43,6 +43,7 @@
 import android.os.SystemProperties
 import android.os.UserHandle
 import android.util.Slog
+import android.view.Display
 import android.view.Display.DEFAULT_DISPLAY
 import android.view.DragEvent
 import android.view.MotionEvent
@@ -213,6 +214,7 @@
     private val overviewToDesktopTransitionObserver: OverviewToDesktopTransitionObserver,
     private val desksOrganizer: DesksOrganizer,
     private val desksTransitionObserver: DesksTransitionObserver,
+    private val desktopPipTransitionObserver: Optional<DesktopPipTransitionObserver>,
     private val userProfileContexts: UserProfileContexts,
     private val desktopModeCompatPolicy: DesktopModeCompatPolicy,
     private val dragToDisplayTransitionHandler: DragToDisplayTransitionHandler,
@@ -285,8 +287,8 @@
                 DeskRecreationFactory { deskUserId, destinationDisplayId, deskId ->
                     if (deskUserId != userId) {
                         // TODO: b/400984250 - add multi-user support for multi-desk restoration.
-                        logW("Tried to recreated desk of another user.")
-                        deskId
+                        logW("Tried to re-create desk of another user.")
+                        null
                     } else {
                         desksOrganizer.createDesk(destinationDisplayId)
                     }
@@ -304,6 +306,8 @@
             this,
         )
         shellController.addUserChangeListener(this)
+        // Update the current user id again because it might be updated between init and onInit().
+        updateCurrentUser(ActivityManager.getCurrentUser())
         transitions.addHandler(this)
         dragToDesktopTransitionHandler.dragToDesktopStateListener = dragToDesktopStateListener
         recentsTransitionHandler.addTransitionStateListener(
@@ -463,6 +467,10 @@
 
     /** Creates a new desk in the given display. */
     fun createDesk(displayId: Int) {
+        if (displayId == Display.INVALID_DISPLAY) {
+            logW("createDesk attempt with invalid displayId", displayId)
+            return
+        }
         if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
             desksOrganizer.createDesk(displayId) { deskId ->
                 taskRepository.addDesk(displayId = displayId, deskId = deskId)
@@ -788,10 +796,31 @@
 
     fun minimizeTask(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) {
         val wct = WindowContainerTransaction()
-
+        val taskId = taskInfo.taskId
+        val displayId = taskInfo.displayId
+        val deskId =
+            taskRepository.getDeskIdForTask(taskInfo.taskId)
+                ?: if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+                    logW("minimizeTask: desk not found for task: ${taskInfo.taskId}")
+                    return
+                } else {
+                    getDefaultDeskId(taskInfo.displayId)
+                }
+        val isLastTask =
+            if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+                taskRepository.isOnlyVisibleNonClosingTaskInDesk(
+                    taskId = taskId,
+                    deskId = checkNotNull(deskId) { "Expected non-null deskId" },
+                    displayId = displayId,
+                )
+            } else {
+                taskRepository.isOnlyVisibleNonClosingTask(taskId = taskId, displayId = displayId)
+            }
         val isMinimizingToPip =
             DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue &&
-                (taskInfo.pictureInPictureParams?.isAutoEnterEnabled() ?: false)
+                desktopPipTransitionObserver.isPresent &&
+                (taskInfo.pictureInPictureParams?.isAutoEnterEnabled ?: false)
+
         // If task is going to PiP, start a PiP transition instead of a minimize transition
         if (isMinimizingToPip) {
             val requestInfo =
@@ -805,75 +834,63 @@
                 )
             val requestRes = transitions.dispatchRequest(Binder(), requestInfo, /* skip= */ null)
             wct.merge(requestRes.second, true)
-            freeformTaskTransitionStarter.startPipTransition(wct)
-            taskRepository.setTaskInPip(taskInfo.displayId, taskInfo.taskId, enterPip = true)
-            taskRepository.setOnPipAbortedCallback { displayId, taskId ->
-                minimizeTaskInner(shellTaskOrganizer.getRunningTaskInfo(taskId)!!, minimizeReason)
-                taskRepository.setTaskInPip(displayId, taskId, enterPip = false)
-            }
-            return
-        }
 
-        minimizeTaskInner(taskInfo, minimizeReason)
-    }
-
-    private fun minimizeTaskInner(taskInfo: RunningTaskInfo, minimizeReason: MinimizeReason) {
-        val taskId = taskInfo.taskId
-        val deskId = taskRepository.getDeskIdForTask(taskInfo.taskId)
-        if (deskId == null && DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
-            logW("minimizeTaskInner: desk not found for task: ${taskInfo.taskId}")
-            return
-        }
-        val displayId = taskInfo.displayId
-        val wct = WindowContainerTransaction()
-
-        snapEventHandler.removeTaskIfTiled(displayId, taskId)
-        val willExitDesktop = willExitDesktop(taskId, displayId, forceExitDesktop = false)
-        val desktopExitRunnable =
-            performDesktopExitCleanUp(
-                wct = wct,
-                deskId = deskId,
-                displayId = displayId,
-                willExitDesktop = willExitDesktop,
-            )
-        // Notify immersive handler as it might need to exit immersive state.
-        val exitResult =
-            desktopImmersiveController.exitImmersiveIfApplicable(
-                wct = wct,
-                taskInfo = taskInfo,
-                reason = DesktopImmersiveController.ExitReason.MINIMIZED,
-            )
-        if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
-            desksOrganizer.minimizeTask(
-                wct = wct,
-                deskId = checkNotNull(deskId) { "Expected non-null deskId" },
-                task = taskInfo,
+            desktopPipTransitionObserver.get().addPendingPipTransition(
+                DesktopPipTransitionObserver.PendingPipTransition(
+                    token = freeformTaskTransitionStarter.startPipTransition(wct),
+                    taskId = taskInfo.taskId,
+                    onSuccess = {
+                        onDesktopTaskEnteredPip(
+                            taskId = taskId,
+                            deskId = deskId,
+                            displayId = taskInfo.displayId,
+                            taskIsLastVisibleTaskBeforePip = isLastTask,
+                        )
+                    },
+                )
             )
         } else {
-            wct.reorder(taskInfo.token, /* onTop= */ false)
-        }
-        val isLastTask =
-            if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
-                taskRepository.isOnlyVisibleNonClosingTaskInDesk(
-                    taskId = taskId,
-                    deskId = checkNotNull(deskId) { "Expected non-null deskId" },
+            snapEventHandler.removeTaskIfTiled(displayId, taskId)
+            val willExitDesktop = willExitDesktop(taskId, displayId, forceExitDesktop = false)
+            val desktopExitRunnable =
+                performDesktopExitCleanUp(
+                    wct = wct,
+                    deskId = deskId,
                     displayId = displayId,
+                    willExitDesktop = willExitDesktop,
+                )
+            // Notify immersive handler as it might need to exit immersive state.
+            val exitResult =
+                desktopImmersiveController.exitImmersiveIfApplicable(
+                    wct = wct,
+                    taskInfo = taskInfo,
+                    reason = DesktopImmersiveController.ExitReason.MINIMIZED,
+                )
+            if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+                desksOrganizer.minimizeTask(
+                    wct = wct,
+                    deskId = checkNotNull(deskId) { "Expected non-null deskId" },
+                    task = taskInfo,
                 )
             } else {
-                taskRepository.isOnlyVisibleNonClosingTask(taskId = taskId, displayId = displayId)
+                wct.reorder(taskInfo.token, /* onTop= */ false)
             }
-        val transition =
-            freeformTaskTransitionStarter.startMinimizedModeTransition(wct, taskId, isLastTask)
-        desktopTasksLimiter.ifPresent {
-            it.addPendingMinimizeChange(
-                transition = transition,
-                displayId = displayId,
-                taskId = taskId,
-                minimizeReason = minimizeReason,
-            )
+            val transition =
+                freeformTaskTransitionStarter.startMinimizedModeTransition(wct, taskId, isLastTask)
+            desktopTasksLimiter.ifPresent {
+                it.addPendingMinimizeChange(
+                    transition = transition,
+                    displayId = displayId,
+                    taskId = taskId,
+                    minimizeReason = minimizeReason,
+                )
+            }
+            exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
+            desktopExitRunnable?.invoke(transition)
         }
-        exitResult.asExit()?.runOnTransitionStart?.invoke(transition)
-        desktopExitRunnable?.invoke(transition)
+        taskbarDesktopTaskListener?.onTaskbarCornerRoundingUpdate(
+            doesAnyTaskRequireTaskbarRounding(displayId, taskId)
+        )
     }
 
     /** Move a task with given `taskId` to fullscreen */
@@ -1319,6 +1336,9 @@
 
         val stageCoordinatorRootTaskToken =
             splitScreenController.multiDisplayProvider.getDisplayRootForDisplayId(DEFAULT_DISPLAY)
+        if (stageCoordinatorRootTaskToken == null) {
+            return
+        }
         wct.reparent(stageCoordinatorRootTaskToken, displayAreaInfo.token, true /* onTop */)
 
         val deactivationRunnable =
@@ -1840,7 +1860,11 @@
         displayId: Int,
         forceExitDesktop: Boolean,
     ): Boolean {
-        if (forceExitDesktop && DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue) {
+        if (
+            forceExitDesktop &&
+                (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue ||
+                    DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue)
+        ) {
             // |forceExitDesktop| is true when the callers knows we'll exit desktop, such as when
             // explicitly going fullscreen, so there's no point in checking the desktop state.
             return true
@@ -1857,6 +1881,33 @@
         return true
     }
 
+    /** Potentially perform Desktop cleanup after a task successfully enters PiP. */
+    @VisibleForTesting
+    fun onDesktopTaskEnteredPip(
+        taskId: Int,
+        deskId: Int,
+        displayId: Int,
+        taskIsLastVisibleTaskBeforePip: Boolean,
+    ) {
+        if (
+            !willExitDesktop(taskId, displayId, forceExitDesktop = taskIsLastVisibleTaskBeforePip)
+        ) {
+            return
+        }
+
+        val wct = WindowContainerTransaction()
+        val desktopExitRunnable =
+            performDesktopExitCleanUp(
+                wct = wct,
+                deskId = deskId,
+                displayId = displayId,
+                willExitDesktop = true,
+            )
+
+        val transition = transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null)
+        desktopExitRunnable?.invoke(transition)
+    }
+
     private fun performDesktopExitCleanupIfNeeded(
         taskId: Int,
         deskId: Int? = null,
@@ -3498,9 +3549,15 @@
     // TODO(b/366397912): Support full multi-user mode in Windowing.
     override fun onUserChanged(newUserId: Int, userContext: Context) {
         logV("onUserChanged previousUserId=%d, newUserId=%d", userId, newUserId)
+        updateCurrentUser(newUserId)
+    }
+
+    private fun updateCurrentUser(newUserId: Int) {
         userId = newUserId
         taskRepository = userRepositories.getProfile(userId)
-        snapEventHandler.onUserChange()
+        if (this::snapEventHandler.isInitialized) {
+            snapEventHandler.onUserChange()
+        }
     }
 
     /** Called when a task's info changes. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
index 7dabeb7..df4d18f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserver.kt
@@ -23,7 +23,6 @@
 import android.view.SurfaceControl
 import android.view.WindowManager.TRANSIT_CLOSE
 import android.view.WindowManager.TRANSIT_OPEN
-import android.view.WindowManager.TRANSIT_PIP
 import android.view.WindowManager.TRANSIT_TO_BACK
 import android.window.DesktopExperienceFlags
 import android.window.DesktopModeFlags
@@ -38,11 +37,12 @@
 import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
 import com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE
 import com.android.wm.shell.shared.TransitionUtil
+import com.android.wm.shell.shared.TransitionUtil.isClosingMode
+import com.android.wm.shell.shared.TransitionUtil.isOpeningMode
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP
-import com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP
+import java.util.Optional
 
 /**
  * A [Transitions.TransitionObserver] that observes shell transitions and updates the
@@ -55,6 +55,7 @@
     private val transitions: Transitions,
     private val shellTaskOrganizer: ShellTaskOrganizer,
     private val desktopMixedTransitionHandler: DesktopMixedTransitionHandler,
+    private val desktopPipTransitionObserver: Optional<DesktopPipTransitionObserver>,
     private val backAnimationController: BackAnimationController,
     private val desktopWallpaperActivityTokenProvider: DesktopWallpaperActivityTokenProvider,
     shellInit: ShellInit,
@@ -63,8 +64,6 @@
     data class CloseWallpaperTransition(val transition: IBinder, val displayId: Int)
 
     private var transitionToCloseWallpaper: CloseWallpaperTransition? = null
-    /* Pending PiP transition and its associated display id and task id. */
-    private var pendingPipTransitionAndPipTask: Triple<IBinder, Int, Int>? = null
     private var currentProfileId: Int
 
     init {
@@ -98,33 +97,7 @@
             removeTaskIfNeeded(info)
         }
         removeWallpaperOnLastTaskClosingIfNeeded(transition, info)
-
-        val desktopRepository = desktopUserRepositories.getProfile(currentProfileId)
-        info.changes.forEach { change ->
-            change.taskInfo?.let { taskInfo ->
-                if (
-                    DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_PIP.isTrue &&
-                        desktopRepository.isTaskMinimizedPipInDisplay(
-                            taskInfo.displayId,
-                            taskInfo.taskId,
-                        )
-                ) {
-                    when (info.type) {
-                        TRANSIT_PIP ->
-                            pendingPipTransitionAndPipTask =
-                                Triple(transition, taskInfo.displayId, taskInfo.taskId)
-
-                        TRANSIT_EXIT_PIP,
-                        TRANSIT_REMOVE_PIP ->
-                            desktopRepository.setTaskInPip(
-                                taskInfo.displayId,
-                                taskInfo.taskId,
-                                enterPip = false,
-                            )
-                    }
-                }
-            }
-        }
+        desktopPipTransitionObserver.ifPresent { it.onTransitionReady(transition, info) }
     }
 
     private fun removeTaskIfNeeded(info: TransitionInfo) {
@@ -299,18 +272,6 @@
                     }
                 }
             transitionToCloseWallpaper = null
-        } else if (pendingPipTransitionAndPipTask?.first == transition) {
-            val desktopRepository = desktopUserRepositories.getProfile(currentProfileId)
-            if (aborted) {
-                pendingPipTransitionAndPipTask?.let {
-                    desktopRepository.onPipAborted(
-                        /*displayId=*/ it.second,
-                        /* taskId=*/ it.third,
-                    )
-                }
-            }
-            desktopRepository.setOnPipAbortedCallback(null)
-            pendingPipTransitionAndPipTask = null
         }
     }
 
@@ -345,18 +306,29 @@
     }
 
     private fun updateTopTransparentFullscreenTaskId(info: TransitionInfo) {
-        info.changes.forEach { change ->
-            change.taskInfo?.let { task ->
-                val desktopRepository = desktopUserRepositories.getProfile(task.userId)
-                val displayId = task.displayId
-                // Clear `topTransparentFullscreenTask` information from repository if task
-                // is closed or sent to back.
-                if (
-                    TransitionUtil.isClosingMode(change.mode) &&
-                        task.taskId ==
-                            desktopRepository.getTopTransparentFullscreenTaskId(displayId)
-                ) {
-                    desktopRepository.clearTopTransparentFullscreenTaskId(displayId)
+        run forEachLoop@{
+            info.changes.forEach { change ->
+                change.taskInfo?.let { task ->
+                    val desktopRepository = desktopUserRepositories.getProfile(task.userId)
+                    val displayId = task.displayId
+                    val transparentTaskId =
+                        desktopRepository.getTopTransparentFullscreenTaskId(displayId)
+                    if (transparentTaskId == null) return@forEachLoop
+                    val changeMode = change.mode
+                    val taskId = task.taskId
+                    val isTopTransparentFullscreenTaskClosing =
+                        taskId == transparentTaskId && isClosingMode(changeMode)
+                    val isNonTopTransparentFullscreenTaskOpening =
+                        taskId != transparentTaskId && isOpeningMode(changeMode)
+                    // Clear `topTransparentFullscreenTask` information from repository if task
+                    // is closed, sent to back or if a different task is opened, brought to front.
+                    if (
+                        isTopTransparentFullscreenTaskClosing ||
+                            isNonTopTransparentFullscreenTaskOpening
+                    ) {
+                        desktopRepository.clearTopTransparentFullscreenTaskId(displayId)
+                        return@forEachLoop
+                    }
                 }
             }
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
index 95cc1e6..f382632 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/ExitDesktopTaskTransitionHandler.java
@@ -46,6 +46,7 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.Cuj;
 import com.android.internal.jank.InteractionJankMonitor;
+import com.android.internal.util.LatencyTracker;
 import com.android.wm.shell.shared.annotations.ShellMainThread;
 import com.android.wm.shell.shared.desktopmode.DesktopModeTransitionSource;
 import com.android.wm.shell.transition.Transitions;
@@ -68,6 +69,7 @@
     private final Context mContext;
     private final Transitions mTransitions;
     private final InteractionJankMonitor mInteractionJankMonitor;
+    private final LatencyTracker mLatencyTracker;
     @ShellMainThread
     private final Handler mHandler;
     private final List<IBinder> mPendingTransitionTokens = new ArrayList<>();
@@ -95,6 +97,7 @@
         mTransactionSupplier = supplier;
         mContext = context;
         mInteractionJankMonitor = interactionJankMonitor;
+        mLatencyTracker = LatencyTracker.getInstance(mContext);
         mHandler = handler;
     }
 
@@ -109,6 +112,7 @@
     public IBinder startTransition(@NonNull DesktopModeTransitionSource transitionSource,
             @NonNull WindowContainerTransaction wct, Point position,
             Function0<Unit> onAnimationEndCallback) {
+        mLatencyTracker.onActionStart(LatencyTracker.ACTION_DESKTOP_MODE_EXIT_MODE);
         mPosition = position;
         mOnAnimationFinishedCallback = onAnimationEndCallback;
         final IBinder token = mTransitions.startTransition(getExitTransitionType(transitionSource),
@@ -141,6 +145,11 @@
 
         mPendingTransitionTokens.remove(transition);
 
+
+        if (transitionHandled) {
+            mLatencyTracker.onActionEnd(LatencyTracker.ACTION_DESKTOP_MODE_EXIT_MODE);
+        }
+
         return transitionHandled;
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/DefaultHomePackageSupplier.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/DefaultHomePackageSupplier.kt
new file mode 100644
index 0000000..8ce624e
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/common/DefaultHomePackageSupplier.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.desktopmode.common
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.os.Handler
+import com.android.wm.shell.shared.annotations.ShellMainThread
+import com.android.wm.shell.sysui.ShellInit
+import java.util.function.Supplier
+
+/**
+ * This supplies the package name of default home in an efficient way. The query to package manager
+ * only executes on initialization and when the preferred activity (e.g. default home) is changed.
+ */
+class DefaultHomePackageSupplier(
+    private val context: Context,
+    shellInit: ShellInit,
+    @ShellMainThread private val mainHandler: Handler,
+) : BroadcastReceiver(), Supplier<String?> {
+
+    private var defaultHomePackage: String? = null
+
+    init {
+        shellInit.addInitCallback({ onInit() }, this)
+    }
+
+    private fun onInit() {
+        context.registerReceiver(
+            this,
+            IntentFilter(Intent.ACTION_PREFERRED_ACTIVITY_CHANGED),
+            null /* broadcastPermission */,
+            mainHandler,
+        )
+    }
+
+    private fun updateDefaultHomePackage(): String? {
+        defaultHomePackage = context.packageManager.getHomeActivities(ArrayList())?.packageName
+        return defaultHomePackage
+    }
+
+    override fun onReceive(contxt: Context?, intent: Intent?) {
+        updateDefaultHomePackage()
+    }
+
+    override fun get(): String? {
+        return defaultHomePackage ?: updateDefaultHomePackage()
+    }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
index f71eaca..e04a5cd 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepository.kt
@@ -113,6 +113,8 @@
         visibleTasks: ArraySet<Int> = ArraySet(),
         minimizedTasks: ArraySet<Int> = ArraySet(),
         freeformTasksInZOrder: ArrayList<Int> = ArrayList(),
+        leftTiledTask: Int? = null,
+        rightTiledTask: Int? = null,
     ) {
         // TODO: b/367609270 - Improve the API to support multi-user
         try {
@@ -125,7 +127,13 @@
                 val desktop =
                     getDesktop(currentRepository, desktopId)
                         .toBuilder()
-                        .updateTaskStates(visibleTasks, minimizedTasks, freeformTasksInZOrder)
+                        .updateTaskStates(
+                            visibleTasks,
+                            minimizedTasks,
+                            freeformTasksInZOrder,
+                            leftTiledTask,
+                            rightTiledTask,
+                        )
                         .updateZOrder(freeformTasksInZOrder)
 
                 persistentRepositories
@@ -222,6 +230,8 @@
             visibleTasks: ArraySet<Int>,
             minimizedTasks: ArraySet<Int>,
             freeformTasksInZOrder: ArrayList<Int>,
+            leftTiledTask: Int?,
+            rightTiledTask: Int?,
         ): Desktop.Builder {
             clearTasksByTaskId()
 
@@ -238,7 +248,11 @@
             }
             putAllTasksByTaskId(
                 visibleTasks.associateWith {
-                    createDesktopTask(it, state = DesktopTaskState.VISIBLE)
+                    createDesktopTask(
+                        it,
+                        state = DesktopTaskState.VISIBLE,
+                        getTilingStateForTask(it, leftTiledTask, rightTiledTask),
+                    )
                 }
             )
             putAllTasksByTaskId(
@@ -249,6 +263,17 @@
             return this
         }
 
+        private fun getTilingStateForTask(
+            taskId: Int,
+            leftTiledTask: Int?,
+            rightTiledTask: Int?,
+        ): DesktopTaskTilingState =
+            when (taskId) {
+                leftTiledTask -> DesktopTaskTilingState.LEFT
+                rightTiledTask -> DesktopTaskTilingState.RIGHT
+                else -> DesktopTaskTilingState.NONE
+            }
+
         private fun Desktop.Builder.updateZOrder(
             freeformTasksInZOrder: ArrayList<Int>
         ): Desktop.Builder {
@@ -260,7 +285,12 @@
         private fun createDesktopTask(
             taskId: Int,
             state: DesktopTaskState = DesktopTaskState.VISIBLE,
+            tiling_state: DesktopTaskTilingState = DesktopTaskTilingState.NONE,
         ): DesktopTask =
-            DesktopTask.newBuilder().setTaskId(taskId).setDesktopTaskState(state).build()
+            DesktopTask.newBuilder()
+                .setTaskId(taskId)
+                .setDesktopTaskState(state)
+                .setDesktopTaskTilingState(tiling_state)
+                .build()
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt
index 8191181..a2dd5db 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializer.kt
@@ -21,7 +21,7 @@
 
 /** Interface for initializing the [DesktopUserRepositories]. */
 interface DesktopRepositoryInitializer {
-    /** A factory used to recreate a desk from persistence. */
+    /** A factory used to re-create a desk from persistence. */
     var deskRecreationFactory: DeskRecreationFactory
 
     /** A flow that emits true when the repository has been initialized. */
@@ -30,9 +30,11 @@
     /** Initialize the user repositories from a persistent data store. */
     fun initialize(userRepositories: DesktopUserRepositories)
 
-    /** A factory for recreating desks. */
+    /** A factory for re-creating desks. */
     fun interface DeskRecreationFactory {
-        /** Recreates a restored desk and returns the new desk id. */
-        suspend fun recreateDesk(userId: Int, destinationDisplayId: Int, deskId: Int): Int
+        /**
+         * Re-creates a restored desk and returns the new desk id, or null if re-creation failed.
+         */
+        suspend fun recreateDesk(userId: Int, destinationDisplayId: Int, deskId: Int): Int?
     }
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
index 49cb739..3ee4807 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerImpl.kt
@@ -69,7 +69,7 @@
                         desksToRestore.map { it.desktopId },
                         userId,
                     )
-                    desksToRestore.forEach { persistentDesktop ->
+                    for (persistentDesktop in desksToRestore) {
                         val maxTasks = getTaskLimit(persistentDesktop)
                         val displayId = persistentDesktop.displayId
                         val deskId = persistentDesktop.desktopId
@@ -81,17 +81,29 @@
                                 destinationDisplayId = newDisplayId,
                                 deskId = deskId,
                             )
-                        logV(
-                            "Recreated desk=%d in display=%d using new deskId=%d and displayId=%d",
-                            deskId,
-                            displayId,
-                            newDeskId,
-                            newDisplayId,
-                        )
-                        if (newDeskId != deskId || newDisplayId != displayId) {
+                        if (newDeskId != null) {
+                            logV(
+                                "Re-created desk=%d in display=%d using new" +
+                                    " deskId=%d and displayId=%d",
+                                deskId,
+                                displayId,
+                                newDeskId,
+                                newDisplayId,
+                            )
+                        }
+                        if (newDeskId == null || newDeskId != deskId || newDisplayId != displayId) {
                             logV("Removing obsolete desk from persistence under deskId=%d", deskId)
                             persistentRepository.removeDesktop(userId, deskId)
                         }
+                        if (newDeskId == null) {
+                            logW(
+                                "Could not re-create desk=%d from display=%d in displayId=%d",
+                                deskId,
+                                displayId,
+                                newDisplayId,
+                            )
+                            continue
+                        }
 
                         // TODO: b/393961770 - [DesktopRepository] doesn't save desks to the
                         //  persistent repository until a task is added to them. Update it so that
@@ -126,6 +138,20 @@
                                         taskId = task.taskId,
                                     )
                                 }
+
+                                if (task.desktopTaskTilingState == DesktopTaskTilingState.LEFT) {
+                                    repository.addLeftTiledTask(
+                                        persistentDesktop.displayId,
+                                        task.taskId,
+                                    )
+                                } else if (
+                                    task.desktopTaskTilingState == DesktopTaskTilingState.RIGHT
+                                ) {
+                                    repository.addRightTiledTask(
+                                        persistentDesktop.displayId,
+                                        task.taskId,
+                                    )
+                                }
                             }
                     }
                 }
@@ -163,6 +189,10 @@
         ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
     }
 
+    private fun logW(msg: String, vararg arguments: Any?) {
+        ProtoLog.w(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments)
+    }
+
     /** A default implementation of [DeskRecreationFactory] that reuses the desk id. */
     private class DefaultDeskRecreationFactory : DeskRecreationFactory {
         override suspend fun recreateDesk(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto
index 0105231..86dcee8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/persistence/persistent_desktop_repositories.proto
@@ -9,9 +9,16 @@
   MINIMIZED = 1;
 }
 
+enum DesktopTaskTilingState {
+  NONE = 1;
+  LEFT = 2;
+  RIGHT = 3;
+}
+
 message DesktopTask {
   optional int32 task_id = 1;
   optional DesktopTaskState desktop_task_state= 2;
+  optional DesktopTaskTilingState desktop_task_tiling_state = 3;
 }
 
 message Desktop {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
index dd5827a..320de2a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/docs/debugging.md
@@ -142,8 +142,8 @@
 ## Tracing activity starts & finishes in the app process
 
 It's sometimes useful to know when to see a stack trace of when an activity starts in the app code
-(ie. if you are repro'ing a bug related to activity starts). You can enable this system property to
-get this trace:
+or via a `WindowContainerTransaction` (ie. if you are repro'ing a bug related to activity starts).
+You can enable this system property to get this trace:
 ```shell
 # Enabling
 adb shell setprop persist.wm.debug.start_activity true
@@ -168,6 +168,21 @@
 adb reboot
 ```
 
+## Tracing transition requests in the Shell
+
+To trace where a new WM transition is started in the Shell, you can enable this system property:
+```shell
+# Enabling
+adb shell setprop persist.wm.debug.start_shell_transition true
+adb reboot
+adb logcat -s "ShellTransitions"
+
+# Disabling
+adb shell setprop persist.wm.debug.start_shell_transition \"\"
+adb reboot
+```
+
+
 ## Dumps
 
 Because the Shell library is built as a part of SystemUI, dumping the state is currently done as a
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
index f89ba0a..0bf2ea6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskTransitionObserver.java
@@ -174,7 +174,7 @@
             SurfaceControl.Transaction finishT) {
         mTaskChangeListener.ifPresent(listener -> listener.onTaskChanging(change.getTaskInfo()));
         mWindowDecorViewModel.onTaskChanging(
-                change.getTaskInfo(), change.getLeash(), startT, finishT);
+                change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode());
     }
 
     private void onToFrontTransitionReady(
@@ -184,7 +184,7 @@
         mTaskChangeListener.ifPresent(
                 listener -> listener.onTaskMovingToFront(change.getTaskInfo()));
         mWindowDecorViewModel.onTaskChanging(
-                change.getTaskInfo(), change.getLeash(), startT, finishT);
+                change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode());
     }
 
     private void onToBackTransitionReady(
@@ -194,7 +194,7 @@
         mTaskChangeListener.ifPresent(
                 listener -> listener.onTaskMovingToBack(change.getTaskInfo()));
         mWindowDecorViewModel.onTaskChanging(
-                change.getTaskInfo(), change.getLeash(), startT, finishT);
+                change.getTaskInfo(), change.getLeash(), startT, finishT, change.getMode());
     }
 
     @Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
index cef18f5..c58bb6e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransitionController.java
@@ -40,7 +40,6 @@
 import android.view.WindowManager;
 import android.window.TransitionInfo;
 import android.window.TransitionRequestInfo;
-import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
 import androidx.annotation.NonNull;
@@ -341,23 +340,6 @@
         return false;
     }
 
-    /**
-     * @return a change representing a config-at-end activity for a given parent.
-     */
-    @Nullable
-    public TransitionInfo.Change getDeferConfigActivityChange(TransitionInfo info,
-            @android.annotation.NonNull WindowContainerToken parent) {
-        for (TransitionInfo.Change change : info.getChanges()) {
-            if (change.getTaskInfo() == null
-                    && change.hasFlags(TransitionInfo.FLAG_CONFIG_AT_END)
-                    && change.getParent() != null && change.getParent().equals(parent)) {
-                return change;
-            }
-        }
-        return null;
-    }
-
-
     /** Whether a particular package is same as current pip package. */
     public boolean isPackageActiveInPip(@Nullable String packageName) {
         // No-op, to be handled differently in PIP1 and PIP2
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
index 119763f..4e341ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipController.java
@@ -340,7 +340,8 @@
             mPipDisplayLayoutState.rotateTo(toRotation);
         }
 
-        if (!mPipTransitionState.isInPip()) {
+        if (!mPipTransitionState.isInPip()
+                && mPipTransitionState.getState() != PipTransitionState.ENTERING_PIP) {
             // Skip the PiP-relevant updates if we aren't in a valid PiP state.
             if (mPipTransitionState.isInFixedRotation()) {
                 ProtoLog.e(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
index 294ef48..92f36d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTaskListener.java
@@ -43,6 +43,7 @@
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.StringJoiner;
 
 /**
  * A Task Listener implementation used only for CUJs and trigger paths that cannot be initiated via
@@ -111,8 +112,20 @@
                 listener.onActionsChanged(params.getActions(), params.getCloseAction());
             }
         }
-        mPictureInPictureParams.copyOnlySet(params != null ? params
-                : new PictureInPictureParams.Builder().build());
+        // Set the new params but make sure mPictureInPictureParams is not null.
+        mPictureInPictureParams = params == null
+                ? new PictureInPictureParams.Builder().build() : params;
+        logRemoteActions(mPictureInPictureParams);
+    }
+
+    private void logRemoteActions(@android.annotation.NonNull PictureInPictureParams params) {
+        StringJoiner sj = new StringJoiner("|", "[", "]");
+        if (params.hasSetActions()) {
+            params.getActions().forEach((action) -> sj.add(action.getTitle()));
+        }
+
+        ProtoLog.d(ShellProtoLogGroup.WM_SHELL_PICTURE_IN_PICTURE,
+                "PIP remote actions=%s", sj.toString());
     }
 
     /** Add a PipParamsChangedCallback listener. */
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
index 9bb2e38..5d8d8b6 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/PipTransition.java
@@ -45,6 +45,7 @@
 import android.app.PictureInPictureParams;
 import android.app.TaskInfo;
 import android.content.Context;
+import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
@@ -75,6 +76,7 @@
 import com.android.wm.shell.pip2.animation.PipAlphaAnimator;
 import com.android.wm.shell.pip2.animation.PipEnterAnimator;
 import com.android.wm.shell.pip2.phone.transition.PipExpandHandler;
+import com.android.wm.shell.pip2.phone.transition.PipTransitionUtils;
 import com.android.wm.shell.shared.TransitionUtil;
 import com.android.wm.shell.splitscreen.SplitScreenController;
 import com.android.wm.shell.sysui.ShellInit;
@@ -386,8 +388,8 @@
         mFinishCallback = finishCallback;
         // We expect the PiP activity as a separate change in a config-at-end transition;
         // only flings are not using config-at-end for resize bounds changes
-        TransitionInfo.Change pipActivityChange = getDeferConfigActivityChange(info,
-                pipChange.getTaskInfo().getToken());
+        TransitionInfo.Change pipActivityChange = PipTransitionUtils.getDeferConfigActivityChange(
+                info, pipChange.getTaskInfo().getToken());
         if (pipActivityChange != null) {
             // Transform calculations use PiP params by default, so make sure they are null to
             // default to using bounds for scaling calculations instead.
@@ -426,8 +428,8 @@
         }
 
         // We expect the PiP activity as a separate change in a config-at-end transition.
-        TransitionInfo.Change pipActivityChange = getDeferConfigActivityChange(info,
-                pipChange.getTaskInfo().getToken());
+        TransitionInfo.Change pipActivityChange = PipTransitionUtils.getDeferConfigActivityChange(
+                info, pipChange.getTaskInfo().getToken());
         if (pipActivityChange == null) {
             return false;
         }
@@ -452,7 +454,7 @@
         final int delta = getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState);
         if (delta != ROTATION_0) {
             // Update transition target changes in place to prepare for fixed rotation.
-            handleBoundsEnterFixedRotation(info, pipChange, pipActivityChange);
+            updatePipChangesForFixedRotation(info, pipChange, pipActivityChange);
         }
 
         // Update the src-rect-hint in params in place, to set up initial animator transform.
@@ -496,8 +498,8 @@
         }
 
         // We expect the PiP activity as a separate change in a config-at-end transition.
-        TransitionInfo.Change pipActivityChange = getDeferConfigActivityChange(info,
-                pipChange.getTaskInfo().getToken());
+        TransitionInfo.Change pipActivityChange = PipTransitionUtils.getDeferConfigActivityChange(
+                info, pipChange.getTaskInfo().getToken());
         if (pipActivityChange == null) {
             return false;
         }
@@ -513,7 +515,7 @@
         final int delta = getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState);
         if (delta != ROTATION_0) {
             // Update transition target changes in place to prepare for fixed rotation.
-            handleBoundsEnterFixedRotation(info, pipChange, pipActivityChange);
+            updatePipChangesForFixedRotation(info, pipChange, pipActivityChange);
         }
 
         PipEnterAnimator animator = new PipEnterAnimator(mContext, pipLeash,
@@ -546,7 +548,7 @@
         return true;
     }
 
-    private void handleBoundsEnterFixedRotation(TransitionInfo info,
+    private void updatePipChangesForFixedRotation(TransitionInfo info,
             TransitionInfo.Change outPipTaskChange,
             TransitionInfo.Change outPipActivityChange) {
         final TransitionInfo.Change fixedRotationChange = findFixedRotationChange(info);
@@ -604,10 +606,33 @@
         SurfaceControl pipLeash = mPipTransitionState.getPinnedTaskLeash();
         Preconditions.checkNotNull(pipLeash, "Leash is null for alpha transition.");
 
-        // Start transition with 0 alpha at the entry bounds.
-        startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top)
-                .setWindowCrop(pipLeash, destinationBounds.width(), destinationBounds.height())
-                .setAlpha(pipLeash, 0f);
+        final int delta = getFixedRotationDelta(info, pipChange, mPipDisplayLayoutState);
+        if (delta != ROTATION_0) {
+            updatePipChangesForFixedRotation(info, pipChange,
+                    // We don't have an activity change to animate in legacy enter,
+                    // so just use a placeholder one as the outPipActivityChange.
+                    new TransitionInfo.Change(null /* container */, new SurfaceControl()));
+        }
+        startTransaction.setWindowCrop(pipLeash,
+                destinationBounds.width(), destinationBounds.height());
+        if (delta != ROTATION_0) {
+            // In a fixed rotation case, rotate PiP leash in the old orientation to its final
+            // position, but keep the bounds visually invariant until async rotation changes
+            // the display rotation after
+            int normalizedRotation = delta;
+            if (normalizedRotation == ROTATION_270) {
+                normalizedRotation = -ROTATION_90;
+            }
+            Matrix transformTensor = new Matrix();
+            final float[] matrixTmp = new float[9];
+            transformTensor.setTranslate(destinationBounds.left, destinationBounds.top);
+            transformTensor.postRotate(-normalizedRotation * 90f);
+
+            startTransaction.setMatrix(pipLeash, transformTensor, matrixTmp);
+            finishTransaction.setMatrix(pipLeash, transformTensor, matrixTmp);
+        } else {
+            startTransaction.setPosition(pipLeash, destinationBounds.left, destinationBounds.top);
+        }
 
         PipAlphaAnimator animator = new PipAlphaAnimator(mContext, pipLeash, startTransaction,
                 finishTransaction, PipAlphaAnimator.FADE_IN);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipTransitionUtils.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipTransitionUtils.java
index 01cda6c..e562f33 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipTransitionUtils.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip2/phone/transition/PipTransitionUtils.java
@@ -67,6 +67,36 @@
     }
 
     /**
+     * @return a change representing a config-at-end activity for ancestor.
+     */
+    @Nullable
+    public static TransitionInfo.Change getDeferConfigActivityChange(TransitionInfo info,
+            @NonNull WindowContainerToken ancestor) {
+        final TransitionInfo.Change ancestorChange =
+                PipTransitionUtils.getChangeByToken(info, ancestor);
+        if (ancestorChange == null) return null;
+
+        // Iterate through changes bottom-to-top, going up the parent chain starting with ancestor.
+        TransitionInfo.Change lastPipChildChange = ancestorChange;
+        for (int i = info.getChanges().size() - 1; i >= 0; --i) {
+            TransitionInfo.Change change = info.getChanges().get(i);
+            if (change == ancestorChange) continue;
+
+            if (change.getParent() != null
+                    && change.getParent().equals(lastPipChildChange.getContainer())) {
+                // Found a child of the last cached child along the ancestral chain.
+                lastPipChildChange = change;
+                if (change.getTaskInfo() == null
+                        && change.hasFlags(TransitionInfo.FLAG_CONFIG_AT_END)) {
+                    // If this is a config-at-end activity change, then we found the chain leaf.
+                    return change;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * @return the leash to interact with the container this change represents.
      * @throws NullPointerException if the leash is null.
      */
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 bb5b5ce..382fa96 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
@@ -536,17 +536,20 @@
     }
 
     /**
-     * Represents a desk whose ID is `mDeskId` and contains the tasks in `mDeskTasks`. Some of these
-     * tasks are minimized and their IDs are contained in the `mMinimizedDeskTasks` set.
+     * Represents a desk whose ID is `mDeskId` inside the display with `mDisplayId` and contains
+     * the tasks in `mDeskTasks`. Some of these tasks are minimized and their IDs are contained
+     * in the `mMinimizedDeskTasks` set.
      */
     private static class Desk {
         final int mDeskId;
+        final int mDisplayId;
         boolean mHasVisibleTasks = false;
         final ArrayList<TaskInfo> mDeskTasks = new ArrayList<>();
         final Set<Integer> mMinimizedDeskTasks = new HashSet<>();
 
-        Desk(int deskId) {
+        Desk(int deskId, int displayId) {
             mDeskId = deskId;
+            mDisplayId = displayId;
         }
 
         void addTask(TaskInfo taskInfo, boolean isMinimized, boolean isVisible) {
@@ -562,7 +565,8 @@
         }
 
         GroupedTaskInfo createDeskTaskInfo() {
-            return GroupedTaskInfo.forDeskTasks(mDeskId, mDeskTasks, mMinimizedDeskTasks);
+            return GroupedTaskInfo.forDeskTasks(mDeskId, mDisplayId, mDeskTasks,
+                    mMinimizedDeskTasks);
         }
     }
 
@@ -601,7 +605,8 @@
     private Desk getOrCreateDesk(int deskId) {
         var desk = mTmpDesks.get(deskId);
         if (desk == null) {
-            desk = new Desk(deskId);
+            desk = new Desk(deskId,
+                    mDesktopUserRepositories.get().getCurrent().getDisplayForDesk(deskId));
             mTmpDesks.put(deskId, desk);
         }
         return desk;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelper.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelper.kt
new file mode 100644
index 0000000..d99be71
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelper.kt
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.splitscreen
+import android.app.ActivityManager
+import android.hardware.display.DisplayManager
+import android.view.SurfaceControl
+import com.android.internal.protolog.ProtoLog
+import com.android.wm.shell.common.split.SplitLayout
+import com.android.wm.shell.protolog.ShellProtoLogGroup
+
+/**
+ * Helper class for managing split-screen functionality across multiple displays.
+ */
+class SplitMultiDisplayHelper(private val displayManager: DisplayManager) {
+
+    /**
+     * A map that stores the [SplitTaskHierarchy] associated with each display ID.
+     * The keys are display IDs (integers), and the values are [SplitTaskHierarchy] objects,
+     * which encapsulate the information needed to manage split-screen tasks on that display.
+     */
+    private val displayTaskMap: MutableMap<Int, SplitTaskHierarchy> = mutableMapOf()
+
+    /**
+     * SplitTaskHierarchy is a class that encapsulates the components required
+     * for managing split-screen functionality on a specific display.
+     */
+    data class SplitTaskHierarchy(
+        var rootTaskInfo: ActivityManager.RunningTaskInfo? = null,
+        var mainStage: StageTaskListener? = null,
+        var sideStage: StageTaskListener? = null,
+        var rootTaskLeash: SurfaceControl? = null,
+        var splitLayout: SplitLayout? = null
+    )
+
+    /**
+     * Returns a list of all currently connected display IDs.
+     *
+     * @return An ArrayList of display IDs.
+     */
+    fun getDisplayIds(): ArrayList<Int> {
+        val displayIds = ArrayList<Int>()
+        displayManager.displays?.forEach { display ->
+            displayIds.add(display.displayId)
+        }
+        return displayIds
+    }
+
+    /**
+     * Swaps the [SplitTaskHierarchy] objects associated with two different display IDs.
+     *
+     * @param firstDisplayId  The ID of the first display.
+     * @param secondDisplayId The ID of the second display.
+     */
+    fun swapDisplayTaskHierarchy(firstDisplayId: Int, secondDisplayId: Int) {
+        if (!displayTaskMap.containsKey(firstDisplayId) || !displayTaskMap.containsKey(secondDisplayId)) {
+            ProtoLog.w(
+                ShellProtoLogGroup.WM_SHELL_SPLIT_SCREEN,
+                "Attempted to swap task hierarchies for invalid display IDs: %d, %d",
+                firstDisplayId,
+                secondDisplayId
+            )
+            return
+        }
+
+        if (firstDisplayId == secondDisplayId) {
+            return
+        }
+
+        val firstHierarchy = displayTaskMap[firstDisplayId]
+        val secondHierarchy = displayTaskMap[secondDisplayId]
+
+        displayTaskMap[firstDisplayId] = checkNotNull(secondHierarchy)
+        displayTaskMap[secondDisplayId] = checkNotNull(firstHierarchy)
+    }
+
+    /**
+     * Gets the root task info for the given display ID.
+     *
+     * @param displayId The ID of the display.
+     * @return The root task info, or null if not found.
+     */
+    fun getDisplayRootTaskInfo(displayId: Int): ActivityManager.RunningTaskInfo? {
+        return displayTaskMap[displayId]?.rootTaskInfo
+    }
+
+    /**
+     * Sets the root task info for the given display ID.
+     *
+     * @param displayId    The ID of the display.
+     * @param rootTaskInfo The root task info to set.
+     */
+    fun setDisplayRootTaskInfo(
+        displayId: Int,
+        rootTaskInfo: ActivityManager.RunningTaskInfo?
+    ) {
+        val hierarchy = displayTaskMap.computeIfAbsent(displayId) { SplitTaskHierarchy() }
+        hierarchy.rootTaskInfo = rootTaskInfo
+    }
+}
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.kt
similarity index 80%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.kt
index d2e57e5..dce3dc1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitMultiDisplayProvider.kt
@@ -14,16 +14,16 @@
  * limitations under the License.
  */
 
-package com.android.wm.shell.splitscreen;
+package com.android.wm.shell.splitscreen
 
-import android.window.WindowContainerToken;
+import android.window.WindowContainerToken
 
-public interface SplitMultiDisplayProvider {
+interface SplitMultiDisplayProvider {
     /**
      * Returns the WindowContainerToken for the root of the given display ID.
      *
      * @param displayId The ID of the display.
      * @return The {@link WindowContainerToken} associated with the display's root task.
      */
-    WindowContainerToken getDisplayRootForDisplayId(int displayId);
+    fun getDisplayRootForDisplayId(displayId: Int): WindowContainerToken?
 }
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 75c09829..014c810 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
@@ -101,6 +101,7 @@
 import android.content.pm.ShortcutInfo;
 import android.graphics.Rect;
 import android.hardware.devicestate.DeviceStateManager;
+import android.hardware.display.DisplayManager;
 import android.os.Bundle;
 import android.os.Debug;
 import android.os.Handler;
@@ -123,6 +124,7 @@
 import android.view.WindowManager;
 import android.widget.Toast;
 import android.window.DesktopExperienceFlags;
+import android.window.DesktopModeFlags;
 import android.window.DisplayAreaInfo;
 import android.window.RemoteTransition;
 import android.window.TransitionInfo;
@@ -277,6 +279,8 @@
     // because we will be posting and removing it from the handler.
     private final Runnable mReEnableLaunchAdjacentOnRoot = () -> setLaunchAdjacentDisabled(false);
 
+    private SplitMultiDisplayHelper mSplitMultiDisplayHelper;
+
     /**
      * Since StageCoordinator only coordinates MainStage and SideStage, it shouldn't support
      * CompatUI layouts. CompatUI is handled separately by MainStage and SideStage.
@@ -392,6 +396,11 @@
         mDesktopTasksController = desktopTasksController;
         mRootTDAOrganizer = rootTDAOrganizer;
 
+        DisplayManager displayManager = context.getSystemService(DisplayManager.class);
+
+        mSplitMultiDisplayHelper = new SplitMultiDisplayHelper(
+                Objects.requireNonNull(displayManager));
+
         taskOrganizer.createRootTask(displayId, WINDOWING_MODE_FULLSCREEN, this /* listener */);
 
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "Creating main/side root task");
@@ -675,7 +684,8 @@
         if (!enteredSplitSelect) {
             return null;
         }
-        if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
+        if (!DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()
+                && !DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) {
             mTaskOrganizer.applyTransaction(wct);
             return null;
         }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
index 1853ffa..320a63a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedTransition.java
@@ -34,6 +34,7 @@
 import com.android.wm.shell.desktopmode.DesktopTasksController;
 import com.android.wm.shell.keyguard.KeyguardTransitionHandler;
 import com.android.wm.shell.pip.PipTransitionController;
+import com.android.wm.shell.pip2.phone.transition.PipTransitionUtils;
 import com.android.wm.shell.protolog.ShellProtoLogGroup;
 import com.android.wm.shell.splitscreen.StageCoordinator;
 import com.android.wm.shell.unfold.UnfoldTransitionHandler;
@@ -132,7 +133,7 @@
 
         TransitionInfo.Change pipActivityChange = null;
         if (pipChange != null) {
-            pipActivityChange = mPipHandler.getDeferConfigActivityChange(
+            pipActivityChange = PipTransitionUtils.getDeferConfigActivityChange(
                     info, pipChange.getContainer());
             everythingElse.getChanges().remove(pipActivityChange);
         }
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 23dfb41..cca9821 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
@@ -153,7 +153,6 @@
             return;
         }
         mPendingStartDragTransition = null;
-        if (aborted) return;
 
         if (mPendingHomeVisibilityUpdate != null) {
             notifyHomeVisibilityChanged(mPendingHomeVisibilityUpdate);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
deleted file mode 100644
index 978b8da..0000000
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/LegacyTransitions.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.wm.shell.transition;
-
-import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS;
-
-import android.annotation.NonNull;
-import android.os.RemoteException;
-import android.view.IRemoteAnimationFinishedCallback;
-import android.view.IRemoteAnimationRunner;
-import android.view.RemoteAnimationAdapter;
-import android.view.RemoteAnimationTarget;
-import android.view.SurfaceControl;
-import android.view.WindowManager;
-import android.window.IWindowContainerTransactionCallback;
-
-import com.android.internal.protolog.ProtoLog;
-
-/**
- * Utilities and interfaces for transition-like usage on top of the legacy app-transition and
- * synctransaction tools.
- */
-public class LegacyTransitions {
-
-    /**
-     * Interface for a "legacy" transition. Effectively wraps a sync callback + remoteAnimation
-     * into one callback.
-     */
-    public interface ILegacyTransition {
-        /**
-         * Called when both the associated sync transaction finishes and the remote animation is
-         * ready.
-         */
-        void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
-                RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
-                IRemoteAnimationFinishedCallback finishedCallback, SurfaceControl.Transaction t);
-    }
-
-    /**
-     * Makes sure that a remote animation and corresponding sync callback are called together
-     * such that the sync callback is called first. This assumes that both the callback receiver
-     * and the remoteanimation are in the same process so that order is preserved on both ends.
-     */
-    public static class LegacyTransition {
-        private final ILegacyTransition mLegacyTransition;
-        private int mSyncId = -1;
-        private SurfaceControl.Transaction mTransaction;
-        private int mTransit;
-        private RemoteAnimationTarget[] mApps;
-        private RemoteAnimationTarget[] mWallpapers;
-        private RemoteAnimationTarget[] mNonApps;
-        private IRemoteAnimationFinishedCallback mFinishCallback = null;
-        private boolean mCancelled = false;
-        private final SyncCallback mSyncCallback = new SyncCallback();
-        private final RemoteAnimationAdapter mAdapter =
-                new RemoteAnimationAdapter(new RemoteAnimationWrapper(), 0, 0);
-
-        public LegacyTransition(@WindowManager.TransitionType int type,
-                @NonNull ILegacyTransition legacyTransition) {
-            mLegacyTransition = legacyTransition;
-            mTransit = type;
-        }
-
-        public @WindowManager.TransitionType int getType() {
-            return mTransit;
-        }
-
-        public IWindowContainerTransactionCallback getSyncCallback() {
-            return mSyncCallback;
-        }
-
-        public RemoteAnimationAdapter getAdapter() {
-            return mAdapter;
-        }
-
-        private class SyncCallback extends IWindowContainerTransactionCallback.Stub {
-            @Override
-            public void onTransactionReady(int id, SurfaceControl.Transaction t)
-                    throws RemoteException {
-                ProtoLog.v(WM_SHELL_TRANSITIONS,
-                        "LegacyTransitions.onTransactionReady(): syncId=%d", id);
-                mSyncId = id;
-                mTransaction = t;
-                checkApply(true /* log */);
-            }
-        }
-
-        private class RemoteAnimationWrapper extends IRemoteAnimationRunner.Stub {
-            @Override
-            public void onAnimationStart(int transit, RemoteAnimationTarget[] apps,
-                    RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps,
-                    IRemoteAnimationFinishedCallback finishedCallback) throws RemoteException {
-                mTransit = transit;
-                mApps = apps;
-                mWallpapers = wallpapers;
-                mNonApps = nonApps;
-                mFinishCallback = finishedCallback;
-                checkApply(false /* log */);
-            }
-
-            @Override
-            public void onAnimationCancelled() throws RemoteException {
-                mCancelled = true;
-                mApps = mWallpapers = mNonApps = null;
-                checkApply(false /* log */);
-            }
-        }
-
-
-        private void checkApply(boolean log) throws RemoteException {
-            if (mSyncId < 0 || (mFinishCallback == null && !mCancelled)) {
-                if (log) {
-                    ProtoLog.v(WM_SHELL_TRANSITIONS, "\tSkipping hasFinishedCb=%b canceled=%b",
-                            mFinishCallback != null, mCancelled);
-                }
-                return;
-            }
-            if (log) {
-                ProtoLog.v(WM_SHELL_TRANSITIONS, "\tapply");
-            }
-            mLegacyTransition.onAnimationStart(mTransit, mApps, mWallpapers,
-                    mNonApps, mFinishCallback, mTransaction);
-        }
-    }
-}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
index e28a7fa..003ef1d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/Transitions.java
@@ -39,6 +39,7 @@
 
 import static com.android.systemui.shared.Flags.returnAnimationFrameworkLongLived;
 import static com.android.window.flags.Flags.ensureWallpaperInTransitions;
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_TRANSITIONS;
 import static com.android.wm.shell.shared.TransitionUtil.FLAG_IS_DESKTOP_WALLPAPER_ACTIVITY;
 import static com.android.wm.shell.shared.TransitionUtil.isClosingType;
 import static com.android.wm.shell.shared.TransitionUtil.isOpeningType;
@@ -52,6 +53,7 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
+import android.os.Build;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -138,6 +140,10 @@
         ShellCommandHandler.ShellCommandActionHandler {
     static final String TAG = "ShellTransitions";
 
+    // If set, will print the stack trace for transition starts within the process
+    static final boolean DEBUG_START_TRANSITION = Build.IS_DEBUGGABLE &&
+            SystemProperties.getBoolean("persist.wm.debug.start_shell_transition", false);
+
     /** Set to {@code true} to enable shell transitions. */
     public static final boolean ENABLE_SHELL_TRANSITIONS = getShellTransitEnabled();
     public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS
@@ -346,10 +352,10 @@
         mShellController = shellController;
         // The very last handler (0 in the list) should be the default one.
         mHandlers.add(mDefaultTransitionHandler);
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: Default");
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "addHandler: Default");
         // Next lowest priority is remote transitions.
         mHandlers.add(mRemoteTransitionHandler);
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: Remote");
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "addHandler: Remote");
         shellInit.addInitCallback(this::onInit, this);
         mHomeTransitionObserver = homeTransitionObserver;
         mFocusTransitionObserver = focusTransitionObserver;
@@ -439,7 +445,7 @@
         mHandlers.add(handler);
         // Set initial scale settings.
         handler.setAnimScaleSetting(mTransitionAnimationScaleSetting);
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "addHandler: %s",
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "addHandler: %s",
                 handler.getClass().getSimpleName());
     }
 
@@ -691,7 +697,7 @@
     void onTransitionReady(@NonNull IBinder transitionToken, @NonNull TransitionInfo info,
             @NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl.Transaction finishT) {
         info.setUnreleasedWarningCallSiteForAllSurfaces("Transitions.onTransitionReady");
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "onTransitionReady (#%d) %s: %s",
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "onTransitionReady (#%d) %s: %s",
                 info.getDebugId(), transitionToken, info.toString("    " /* prefix */));
         int activeIdx = findByToken(mPendingTransitions, transitionToken);
         if (activeIdx < 0) {
@@ -753,7 +759,7 @@
                 if (tr.isIdle()) continue;
                 hadPreceding = true;
                 // Sleep starts a process of forcing all prior transitions to finish immediately
-                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+                ProtoLog.v(WM_SHELL_TRANSITIONS,
                         "Start finish-for-sync track %d", i);
                 finishForSync(active.mToken, i, null /* forceFinish */);
             }
@@ -797,7 +803,7 @@
         if (info.getRootCount() == 0 && !KeyguardTransitionHandler.handles(info)) {
             // No root-leashes implies that the transition is empty/no-op, so just do
             // housekeeping and return.
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "No transition roots in %s so"
+            ProtoLog.v(WM_SHELL_TRANSITIONS, "No transition roots in %s so"
                     + " abort", active);
             onAbort(active);
             return true;
@@ -839,7 +845,7 @@
                 && allOccluded)) {
             // Treat this as an abort since we are bypassing any merge logic and effectively
             // finishing immediately.
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS,
+            ProtoLog.v(WM_SHELL_TRANSITIONS,
                     "Non-visible anim so abort: %s", active);
             onAbort(active);
             return true;
@@ -873,7 +879,7 @@
     void processReadyQueue(Track track) {
         if (track.mReadyTransitions.isEmpty()) {
             if (track.mActiveTransition == null) {
-                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Track %d became idle",
+                ProtoLog.v(WM_SHELL_TRANSITIONS, "Track %d became idle",
                         mTracks.indexOf(track));
                 if (areTracksIdle()) {
                     if (!mReadyDuringSync.isEmpty()) {
@@ -885,7 +891,7 @@
                             if (!success) break;
                         }
                     } else if (mPendingTransitions.isEmpty()) {
-                        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "All active transition "
+                        ProtoLog.v(WM_SHELL_TRANSITIONS, "All active transition "
                                 + "animations finished");
                         mKnownTransitions.clear();
                         // Run all runnables from the run-when-idle queue.
@@ -926,7 +932,7 @@
             onMerged(playingToken, readyToken);
             return;
         }
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition %s ready while"
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "Transition %s ready while"
                 + " %s is still animating. Notify the animating transition"
                 + " in case they can be merged", ready, playing);
         mTransitionTracer.logMergeRequested(ready.mInfo.getDebugId(), playing.mInfo.getDebugId());
@@ -955,7 +961,7 @@
         }
 
         final Track track = mTracks.get(playing.getTrack());
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition was merged: %s into %s",
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "Transition was merged: %s into %s",
                 merged, playing);
         int readyIdx = 0;
         if (track.mReadyTransitions.isEmpty() || track.mReadyTransitions.get(0) != merged) {
@@ -996,7 +1002,7 @@
     }
 
     private void playTransition(@NonNull ActiveTransition active) {
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Playing animation for %s", active);
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "Playing animation for %s", active);
         final var token = active.mToken;
 
         for (int i = 0; i < mObservers.size(); ++i) {
@@ -1007,12 +1013,12 @@
 
         // If a handler already chose to run this animation, try delegating to it first.
         if (active.mHandler != null) {
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " try firstHandler %s",
+            ProtoLog.v(WM_SHELL_TRANSITIONS, " try firstHandler %s",
                     active.mHandler);
             boolean consumed = active.mHandler.startAnimation(token, active.mInfo,
                     active.mStartT, active.mFinishT, (wct) -> onFinish(token, wct));
             if (consumed) {
-                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by firstHandler");
+                ProtoLog.v(WM_SHELL_TRANSITIONS, " animated by firstHandler");
                 mTransitionTracer.logDispatched(active.mInfo.getDebugId(), active.mHandler);
                 if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                     Trace.instant(TRACE_TAG_WINDOW_MANAGER,
@@ -1042,14 +1048,14 @@
     ) {
         for (int i = mHandlers.size() - 1; i >= 0; --i) {
             if (mHandlers.get(i) == skip) {
-                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " skip handler %s",
+                ProtoLog.v(WM_SHELL_TRANSITIONS, " skip handler %s",
                         mHandlers.get(i));
                 continue;
             }
             boolean consumed = mHandlers.get(i).startAnimation(transition, info, startT, finishT,
                     finishCB);
             if (consumed) {
-                ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " animated by %s",
+                ProtoLog.v(WM_SHELL_TRANSITIONS, " animated by %s",
                         mHandlers.get(i));
                 mTransitionTracer.logDispatched(info.getDebugId(), mHandlers.get(i));
                 if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
@@ -1155,7 +1161,7 @@
         for (int i = 0; i < mObservers.size(); ++i) {
             mObservers.get(i).onTransitionFinished(active.mToken, active.mAborted);
         }
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition animation finished "
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "Transition animation finished "
                 + "(aborted=%b), notifying core %s", active.mAborted, active);
         if (active.mStartT != null) {
             // Applied by now, so clear immediately to remove any references. Do not set to null
@@ -1209,7 +1215,7 @@
 
     void requestStartTransition(@NonNull IBinder transitionToken,
             @Nullable TransitionRequestInfo request) {
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Transition requested (#%d): %s %s",
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "Transition requested (#%d): %s %s",
                 request.getDebugId(), transitionToken, request);
         if (mKnownTransitions.containsKey(transitionToken)) {
             throw new RuntimeException("Transition already started " + transitionToken);
@@ -1228,6 +1234,8 @@
             if (requestResult != null) {
                 active.mHandler = requestResult.first;
                 wct = requestResult.second;
+                ProtoLog.v(WM_SHELL_TRANSITIONS, "Transition (#%d): request handled by %s",
+                        request.getDebugId(), active.mHandler.getClass().getSimpleName());
             }
             if (request.getDisplayChange() != null) {
                 TransitionRequestInfo.DisplayChange change = request.getDisplayChange();
@@ -1273,8 +1281,12 @@
      */
     public IBinder startTransition(@WindowManager.TransitionType int type,
             @NonNull WindowContainerTransaction wct, @Nullable TransitionHandler handler) {
-        ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "Directly starting a new transition "
+        ProtoLog.v(WM_SHELL_TRANSITIONS, "Directly starting a new transition "
                 + "type=%s wct=%s handler=%s", transitTypeToString(type), wct, handler);
+        if (DEBUG_START_TRANSITION) {
+            Log.d(TAG, "startTransition: type=" + transitTypeToString(type)
+                    + " wct=" + wct + " handler=" + handler.getClass().getName(), new Throwable());
+        }
         final ActiveTransition active =
                 new ActiveTransition(mOrganizer.startNewTransition(type, wct));
         active.mHandler = handler;
@@ -1362,7 +1374,7 @@
             }
             // Attempt to merge a SLEEP info to signal that the playing transition needs to
             // fast-forward.
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Attempt to merge sync %s"
+            ProtoLog.v(WM_SHELL_TRANSITIONS, " Attempt to merge sync %s"
                     + " into %s via a SLEEP proxy", nextSync, playing);
             playing.mHandler.mergeAnimation(nextSync.mToken, dummyInfo, dummyT, dummyT,
                     playing.mToken, (wct) -> {});
@@ -1598,7 +1610,7 @@
         public void onTransitionReady(IBinder iBinder, TransitionInfo transitionInfo,
                 SurfaceControl.Transaction t, SurfaceControl.Transaction finishT)
                 throws RemoteException {
-            ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, "onTransitionReady(transaction=%d)",
+            ProtoLog.v(WM_SHELL_TRANSITIONS, "onTransitionReady(transaction=%d)",
                     t.getId());
             mMainExecutor.execute(() -> Transitions.this.onTransitionReady(
                     iBinder, transitionInfo, t, finishT));
@@ -1784,8 +1796,9 @@
         pw.println(prefix + TAG);
 
         final String innerPrefix = prefix + "  ";
-        pw.println(prefix + "Handlers:");
-        for (TransitionHandler handler : mHandlers) {
+        pw.println(prefix + "Handlers (ordered by priority):");
+        for (int i = mHandlers.size() - 1; i >= 0; i--) {
+            final TransitionHandler handler = mHandlers.get(i);
             pw.print(innerPrefix);
             pw.print(handler.getClass().getSimpleName());
             pw.println(" (" + Integer.toHexString(System.identityHashCode(handler)) + ")");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
index 7871179..42321e56 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecorViewModel.java
@@ -49,6 +49,7 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.window.DisplayAreaInfo;
+import android.window.TransitionInfo;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
@@ -233,7 +234,8 @@
             RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             SurfaceControl.Transaction startT,
-            SurfaceControl.Transaction finishT) {
+            SurfaceControl.Transaction finishT,
+            @TransitionInfo.TransitionMode int changeMode) {
         final CaptionWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
 
         if (!shouldShowWindowDecor(taskInfo)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
index 5e8c1fe..e08ef58 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CaptionWindowDecoration.java
@@ -49,6 +49,7 @@
 import android.view.WindowInsets;
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
+import android.window.DesktopExperienceFlags;
 import android.window.DesktopModeFlags;
 import android.window.WindowContainerTransaction;
 
@@ -218,11 +219,17 @@
         relayoutParams.mRunningTaskInfo = taskInfo;
         relayoutParams.mLayoutResId = R.layout.caption_window_decor;
         relayoutParams.mCaptionHeightId = getCaptionHeightIdStatic(taskInfo.getWindowingMode());
-        relayoutParams.mShadowRadius = hasGlobalFocus
-                ? context.getResources().getDimensionPixelSize(
-                        R.dimen.freeform_decor_shadow_focused_thickness)
-                : context.getResources().getDimensionPixelSize(
-                        R.dimen.freeform_decor_shadow_unfocused_thickness);
+        if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+            relayoutParams.mShadowRadiusId = hasGlobalFocus
+                    ? R.dimen.freeform_decor_shadow_focused_thickness
+                    : R.dimen.freeform_decor_shadow_unfocused_thickness;
+        } else {
+            relayoutParams.mShadowRadius = hasGlobalFocus
+                    ? context.getResources().getDimensionPixelSize(
+                    R.dimen.freeform_decor_shadow_focused_thickness)
+                    : context.getResources().getDimensionPixelSize(
+                            R.dimen.freeform_decor_shadow_unfocused_thickness);
+        }
         relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
         relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;
         relayoutParams.mIsCaptionVisible = taskInfo.isFreeform()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java
index 2b2cdf8..4511fbe 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/CarWindowDecorViewModel.java
@@ -31,6 +31,7 @@
 import android.view.KeyEvent;
 import android.view.SurfaceControl;
 import android.view.View;
+import android.window.TransitionInfo;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
@@ -159,7 +160,8 @@
             RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             SurfaceControl.Transaction startT,
-            SurfaceControl.Transaction finishT) {
+            SurfaceControl.Transaction finishT,
+            @TransitionInfo.TransitionMode int changeMode) {
         final CarWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
 
         if (!shouldShowWindowDecor(taskInfo)) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
index febb885..800faca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModel.java
@@ -27,6 +27,7 @@
 import static android.view.MotionEvent.ACTION_MOVE;
 import static android.view.MotionEvent.ACTION_UP;
 import static android.view.WindowInsets.Type.statusBars;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
 
 import static com.android.internal.jank.Cuj.CUJ_DESKTOP_MODE_ENTER_MODE_APP_HANDLE_MENU;
 import static com.android.window.flags.Flags.enableDisplayFocusInShellTransitions;
@@ -79,6 +80,7 @@
 import android.view.ViewRootImpl;
 import android.window.DesktopModeFlags;
 import android.window.TaskSnapshot;
+import android.window.TransitionInfo;
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
@@ -150,18 +152,19 @@
 import com.android.wm.shell.windowdecor.extension.TaskInfoKt;
 import com.android.wm.shell.windowdecor.tiling.DesktopTilingDecorViewModel;
 import com.android.wm.shell.windowdecor.tiling.SnapEventHandler;
+import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder;
 import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
 
 import kotlin.Pair;
 import kotlin.Unit;
 import kotlin.jvm.functions.Function1;
 
-import org.jetbrains.annotations.NotNull;
-
 import kotlinx.coroutines.CoroutineScope;
 import kotlinx.coroutines.ExperimentalCoroutinesApi;
 import kotlinx.coroutines.MainCoroutineDispatcher;
 
+import org.jetbrains.annotations.NotNull;
+
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashSet;
@@ -206,6 +209,7 @@
     private final AppToWebEducationController mAppToWebEducationController;
     private final AppHandleAndHeaderVisibilityHelper mAppHandleAndHeaderVisibilityHelper;
     private final AppHeaderViewHolder.Factory mAppHeaderViewHolderFactory;
+    private final AppHandleViewHolder.Factory mAppHandleViewHolderFactory;
     private boolean mTransitionDragActive;
 
     private SparseArray<EventReceiver> mEventReceiversByDisplay = new SparseArray<>();
@@ -331,6 +335,7 @@
                 new InputMonitorFactory(),
                 SurfaceControl.Transaction::new,
                 new AppHeaderViewHolder.Factory(),
+                new AppHandleViewHolder.Factory(),
                 rootTaskDisplayAreaOrganizer,
                 new SparseArray<>(),
                 interactionJankMonitor,
@@ -380,6 +385,7 @@
             InputMonitorFactory inputMonitorFactory,
             Supplier<SurfaceControl.Transaction> transactionFactory,
             AppHeaderViewHolder.Factory appHeaderViewHolderFactory,
+            AppHandleViewHolder.Factory appHandleViewHolderFactory,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
             SparseArray<DesktopModeWindowDecoration> windowDecorByTaskId,
             InteractionJankMonitor interactionJankMonitor,
@@ -422,6 +428,7 @@
         mInputMonitorFactory = inputMonitorFactory;
         mTransactionFactory = transactionFactory;
         mAppHeaderViewHolderFactory = appHeaderViewHolderFactory;
+        mAppHandleViewHolderFactory = appHandleViewHolderFactory;
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
         mGenericLinksParser = genericLinksParser;
         mInputManager = mContext.getSystemService(InputManager.class);
@@ -486,7 +493,8 @@
                 new DesktopModeOnTaskResizeAnimationListener());
         mDesktopTasksController.setOnTaskRepositionAnimationListener(
                 new DesktopModeOnTaskRepositionAnimationListener());
-        if (DesktopModeFlags.ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX.isTrue()) {
+        if (DesktopModeFlags.ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX.isTrue()
+                || DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) {
             mRecentsTransitionHandler.addTransitionStateListener(
                     new DesktopModeRecentsTransitionStateListener());
         }
@@ -587,7 +595,8 @@
             RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             SurfaceControl.Transaction startT,
-            SurfaceControl.Transaction finishT) {
+            SurfaceControl.Transaction finishT,
+            @TransitionInfo.TransitionMode int changeMode) {
         final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(taskInfo.taskId);
         if (!shouldShowWindowDecor(taskInfo)) {
             if (decoration != null) {
@@ -601,8 +610,8 @@
         } else {
             decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                     false /* shouldSetTaskPositionAndCrop */,
-                    mFocusTransitionObserver.hasGlobalFocus(taskInfo),
-                    mExclusionRegion);
+                    mFocusTransitionObserver.hasGlobalFocus(taskInfo), mExclusionRegion,
+                    /*isMovingToBack= */ changeMode == TRANSIT_TO_BACK);
         }
     }
 
@@ -617,7 +626,7 @@
         decoration.relayout(taskInfo, startT, finishT, false /* applyStartTransactionOnDraw */,
                 false /* shouldSetTaskPositionAndCrop */,
                 mFocusTransitionObserver.hasGlobalFocus(taskInfo),
-                mExclusionRegion);
+                mExclusionRegion, /* isMovingToBack= */ false);
     }
 
     @Override
@@ -817,9 +826,6 @@
             return;
         }
         decoration.closeHandleMenu();
-        // When the app enters split-select, the handle will no longer be visible, meaning
-        // we shouldn't receive input for it any longer.
-        decoration.disposeStatusBarInputLayer();
         mDesktopTasksController.requestSplit(decoration.mTaskInfo, false /* leftOrTop */);
         mDesktopModeUiEventLogger.log(decoration.mTaskInfo,
                 DesktopUiEventEnum.DESKTOP_WINDOW_APP_HANDLE_MENU_TAP_TO_SPLIT_SCREEN);
@@ -1603,7 +1609,8 @@
                                     relevantDecor.mTaskInfo,
                                     relevantDecor.mTaskSurface, ev.getRawX(), ev.getRawY(),
                                     dragStartState);
-                    if (indicatorType != TO_FULLSCREEN_INDICATOR) {
+                    if (indicatorType != TO_FULLSCREEN_INDICATOR
+                            || BubbleAnythingFlagHelper.enableBubbleToFullscreen()) {
                         if (mMoveToDesktopAnimator == null) {
                             mMoveToDesktopAnimator = new MoveToDesktopAnimator(
                                     mContext, mDragToDesktopAnimationStartBounds,
@@ -1780,6 +1787,7 @@
                         mMainChoreographer,
                         mSyncQueue,
                         mAppHeaderViewHolderFactory,
+                        mAppHandleViewHolderFactory,
                         mRootTaskDisplayAreaOrganizer,
                         mGenericLinksParser,
                         mAssistContentRequester,
@@ -1871,12 +1879,13 @@
         windowDecoration.relayout(taskInfo, startT, finishT,
                 false /* applyStartTransactionOnDraw */, false /* shouldSetTaskPositionAndCrop */,
                 mFocusTransitionObserver.hasGlobalFocus(taskInfo),
-                mExclusionRegion);
+                mExclusionRegion, /* isMovingToBack= */ false);
         if (!DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue()) {
             incrementEventReceiverTasks(taskInfo.displayId);
         }
     }
 
+    @Nullable
     private RunningTaskInfo getOtherSplitTask(int taskId) {
         @SplitPosition int remainingTaskPosition = mSplitScreenController
                 .getSplitPosition(taskId) == SPLIT_POSITION_BOTTOM_OR_RIGHT
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 5432f6f..e8019e4 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
@@ -72,6 +72,7 @@
 import android.view.WindowManager;
 import android.view.WindowManagerGlobal;
 import android.widget.ImageButton;
+import android.window.DesktopExperienceFlags;
 import android.window.DesktopModeFlags;
 import android.window.TaskSnapshot;
 import android.window.WindowContainerTransaction;
@@ -190,6 +191,7 @@
     private ExclusionRegionListener mExclusionRegionListener;
 
     private final AppHeaderViewHolder.Factory mAppHeaderViewHolderFactory;
+    private final AppHandleViewHolder.Factory mAppHandleViewHolderFactory;
     private final RootTaskDisplayAreaOrganizer mRootTaskDisplayAreaOrganizer;
     private final MaximizeMenuFactory mMaximizeMenuFactory;
     private final HandleMenuFactory mHandleMenuFactory;
@@ -212,6 +214,7 @@
     private boolean mIsDragging = false;
     private Runnable mLoadAppInfoRunnable;
     private Runnable mSetAppInfoRunnable;
+    private boolean mIsMovingToBack;
 
     public DesktopModeWindowDecoration(
             Context context,
@@ -231,6 +234,7 @@
             Choreographer choreographer,
             SyncTransactionQueue syncQueue,
             AppHeaderViewHolder.Factory appHeaderViewHolderFactory,
+            AppHandleViewHolder.Factory appHandleViewHolderFactory,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
             AppToWebGenericLinksParser genericLinksParser,
             AssistContentRequester assistContentRequester,
@@ -242,10 +246,10 @@
         this (context, userContext, displayController, taskResourceLoader, splitScreenController,
                 desktopUserRepositories, taskOrganizer, taskInfo, taskSurface, handler,
                 mainExecutor, mainDispatcher, bgScope, bgExecutor, choreographer, syncQueue,
-                appHeaderViewHolderFactory, rootTaskDisplayAreaOrganizer, genericLinksParser,
-                assistContentRequester, SurfaceControl.Builder::new,
-                SurfaceControl.Transaction::new, WindowContainerTransaction::new,
-                SurfaceControl::new, new WindowManagerWrapper(
+                appHeaderViewHolderFactory, appHandleViewHolderFactory,
+                rootTaskDisplayAreaOrganizer, genericLinksParser, assistContentRequester,
+                SurfaceControl.Builder::new, SurfaceControl.Transaction::new,
+                WindowContainerTransaction::new, SurfaceControl::new, new WindowManagerWrapper(
                         context.getSystemService(WindowManager.class)),
                 new SurfaceControlViewHostFactory() {},
                 windowDecorViewHostSupplier,
@@ -273,6 +277,7 @@
             Choreographer choreographer,
             SyncTransactionQueue syncQueue,
             AppHeaderViewHolder.Factory appHeaderViewHolderFactory,
+            AppHandleViewHolder.Factory appHandleViewHolderFactory,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
             AppToWebGenericLinksParser genericLinksParser,
             AssistContentRequester assistContentRequester,
@@ -302,6 +307,7 @@
         mChoreographer = choreographer;
         mSyncQueue = syncQueue;
         mAppHeaderViewHolderFactory = appHeaderViewHolderFactory;
+        mAppHandleViewHolderFactory = appHandleViewHolderFactory;
         mRootTaskDisplayAreaOrganizer = rootTaskDisplayAreaOrganizer;
         mGenericLinksParser = genericLinksParser;
         mAssistContentRequester = assistContentRequester;
@@ -462,7 +468,7 @@
         // causes flickering. See b/270202228.
         final boolean applyTransactionOnDraw = taskInfo.isFreeform();
         relayout(taskInfo, t, t, applyTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
-                hasGlobalFocus, displayExclusionRegion);
+                hasGlobalFocus, displayExclusionRegion, mIsMovingToBack);
         if (!applyTransactionOnDraw) {
             t.apply();
         }
@@ -489,7 +495,8 @@
     void relayout(ActivityManager.RunningTaskInfo taskInfo,
             SurfaceControl.Transaction startT, SurfaceControl.Transaction finishT,
             boolean applyStartTransactionOnDraw, boolean shouldSetTaskVisibilityPositionAndCrop,
-            boolean hasGlobalFocus, @NonNull Region displayExclusionRegion) {
+            boolean hasGlobalFocus, @NonNull Region displayExclusionRegion,
+            boolean isMovingToBack) {
         Trace.beginSection("DesktopModeWindowDecoration#relayout");
 
         if (DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_APP_TO_WEB.isTrue()) {
@@ -512,12 +519,17 @@
 
         final boolean inFullImmersive = mDesktopUserRepositories.getProfile(taskInfo.userId)
                 .isTaskInFullImmersiveState(taskInfo.taskId);
+        mIsMovingToBack = isMovingToBack;
         updateRelayoutParams(mRelayoutParams, mContext, taskInfo, mSplitScreenController,
                 applyStartTransactionOnDraw, shouldSetTaskVisibilityPositionAndCrop,
                 mIsStatusBarVisible, mIsKeyguardVisibleAndOccluded, inFullImmersive,
                 mIsDragging, mDisplayController.getInsetsState(taskInfo.displayId), hasGlobalFocus,
-                displayExclusionRegion, mIsRecentsTransitionRunning,
-                mDesktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(taskInfo));
+                displayExclusionRegion,
+                /* shouldIgnoreCornerRadius= */ mIsRecentsTransitionRunning
+                        && DesktopModeFlags
+                        .ENABLE_DESKTOP_RECENTS_TRANSITIONS_CORNERS_BUGFIX.isTrue(),
+                mDesktopModeCompatPolicy.shouldExcludeCaptionFromAppBounds(taskInfo),
+                mIsRecentsTransitionRunning, mIsMovingToBack);
 
         final WindowDecorLinearLayout oldRootView = mResult.mRootView;
         final SurfaceControl oldDecorationSurface = mDecorationContainerSurface;
@@ -542,7 +554,9 @@
             return;
         }
 
-        if (oldRootView != mResult.mRootView) {
+        if (DesktopModeFlags.SKIP_DECOR_VIEW_RELAYOUT_WHEN_CLOSING_BUGFIX.isTrue()
+                ? (oldRootView != mResult.mRootView && taskInfo.isVisibleRequested)
+                : oldRootView != mResult.mRootView) {
             disposeStatusBarInputLayer();
             mWindowDecorViewHolder = createViewHolder();
             // Load these only when first creating the view.
@@ -558,29 +572,15 @@
             });
         }
 
-        final Point position = new Point();
-        if (isAppHandle(mWindowDecorViewHolder)) {
-            position.set(determineHandlePosition());
-        }
         if (canEnterDesktopMode(mContext) && isEducationEnabled()) {
             notifyCaptionStateChanged();
         }
 
         Trace.beginSection("DesktopModeWindowDecoration#relayout-bindData");
         if (isAppHandle(mWindowDecorViewHolder)) {
-            mWindowDecorViewHolder.bindData(new AppHandleViewHolder.HandleData(
-                    mTaskInfo, position, mResult.mCaptionWidth, mResult.mCaptionHeight,
-                    isCaptionVisible()
-            ));
+            updateAppHandleViewHolder();
         } else {
-            mWindowDecorViewHolder.bindData(new AppHeaderViewHolder.HeaderData(
-                    mTaskInfo,
-                    DesktopModeUtils.isTaskMaximized(mTaskInfo, mDisplayController),
-                    inFullImmersive,
-                    hasGlobalFocus,
-                    /* maximizeHoverEnabled= */ canOpenMaximizeMenu(
-                            /* animatingTaskResizeOrReposition= */ false)
-            ));
+            updateAppHeaderViewHolder(inFullImmersive, hasGlobalFocus);
         }
         Trace.endSection();
 
@@ -720,7 +720,8 @@
                 .getScaledTouchSlop();
         final Resources res = mResult.mRootView.getResources();
         final DragResizeWindowGeometry newGeometry = new DragResizeWindowGeometry(
-                mRelayoutParams.mCornerRadius,
+                DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()
+                        ? mResult.mCornerRadius : mRelayoutParams.mCornerRadius,
                 new Size(mResult.mWidth, mResult.mHeight),
                 getResizeEdgeHandleSize(res), getResizeHandleEdgeInset(res),
                 getFineResizeCornerSize(res), getLargeResizeCornerSize(res),
@@ -857,9 +858,31 @@
         asAppHandle(mWindowDecorViewHolder).disposeStatusBarInputLayer();
     }
 
+    /** Update the view holder for app handle. */
+    private void updateAppHandleViewHolder() {
+        if (!isAppHandle(mWindowDecorViewHolder)) return;
+        asAppHandle(mWindowDecorViewHolder).bindData(new AppHandleViewHolder.HandleData(
+                mTaskInfo, determineHandlePosition(), mResult.mCaptionWidth,
+                mResult.mCaptionHeight, isCaptionVisible()
+        ));
+    }
+
+    /** Update the view holder for app header. */
+    private void updateAppHeaderViewHolder(boolean inFullImmersive, boolean hasGlobalFocus) {
+        if (!isAppHeader(mWindowDecorViewHolder)) return;
+        asAppHeader(mWindowDecorViewHolder).bindData(new AppHeaderViewHolder.HeaderData(
+                mTaskInfo,
+                DesktopModeUtils.isTaskMaximized(mTaskInfo, mDisplayController),
+                inFullImmersive,
+                hasGlobalFocus,
+                /* maximizeHoverEnabled= */ canOpenMaximizeMenu(
+                    /* animatingTaskResizeOrReposition= */ false)
+        ));
+    }
+
     private WindowDecorationViewHolder createViewHolder() {
         if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_app_handle) {
-            return new AppHandleViewHolder(
+            return mAppHandleViewHolderFactory.create(
                     mResult.mRootView,
                     mOnCaptionTouchListener,
                     mOnCaptionButtonClickListener,
@@ -886,6 +909,10 @@
         return viewHolder instanceof AppHandleViewHolder;
     }
 
+    private boolean isAppHeader(WindowDecorationViewHolder viewHolder) {
+        return viewHolder instanceof AppHeaderViewHolder;
+    }
+
     @Nullable
     private AppHandleViewHolder asAppHandle(WindowDecorationViewHolder viewHolder) {
         if (viewHolder instanceof AppHandleViewHolder) {
@@ -918,7 +945,9 @@
             boolean hasGlobalFocus,
             @NonNull Region displayExclusionRegion,
             boolean shouldIgnoreCornerRadius,
-            boolean shouldExcludeCaptionFromAppBounds) {
+            boolean shouldExcludeCaptionFromAppBounds,
+            boolean isRecentsTransitionRunning,
+            boolean isMovingToBack) {
         final int captionLayoutId = getDesktopModeWindowDecorLayoutId(taskInfo.getWindowingMode());
         final boolean isAppHeader =
                 captionLayoutId == R.layout.desktop_mode_app_header;
@@ -935,11 +964,20 @@
         // the first frame.
         relayoutParams.mAsyncViewHost = isAppHandle;
 
-        final boolean showCaption;
-        if (DesktopModeFlags.ENABLE_DESKTOP_IMMERSIVE_DRAG_BUGFIX.isTrue() && isDragging) {
+        boolean showCaption;
+        // If this relayout is occurring from an observed TRANSIT_TO_BACK transition, do not
+        // show caption (this includes split select transition).
+        if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()
+                && isMovingToBack && !isDragging) {
+            showCaption = false;
+        } else if (DesktopModeFlags.ENABLE_DESKTOP_IMMERSIVE_DRAG_BUGFIX.isTrue() && isDragging) {
             // If the task is being dragged, the caption should not be hidden so that it continues
             // receiving input
             showCaption = true;
+        } else if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()
+                && isRecentsTransitionRunning) {
+            // Caption should not be visible in recents.
+            showCaption = false;
         } else if (DesktopModeFlags.ENABLE_FULLY_IMMERSIVE_IN_DESKTOP.isTrue()) {
             if (inFullImmersiveMode) {
                 showCaption = (isStatusBarVisible && !isKeyguardVisibleAndOccluded);
@@ -1036,13 +1074,23 @@
         }
         if (isAppHeader
                 && DesktopModeStatus.useWindowShadow(/* isFocusedWindow= */ hasGlobalFocus)) {
-            relayoutParams.mShadowRadius = hasGlobalFocus
-                    ? context.getResources().getDimensionPixelSize(
-                            R.dimen.freeform_decor_shadow_focused_thickness)
-                    : context.getResources().getDimensionPixelSize(
-                            R.dimen.freeform_decor_shadow_unfocused_thickness);
+            if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+                relayoutParams.mShadowRadiusId = hasGlobalFocus
+                        ? R.dimen.freeform_decor_shadow_focused_thickness
+                        : R.dimen.freeform_decor_shadow_unfocused_thickness;
+            } else {
+                relayoutParams.mShadowRadius = hasGlobalFocus
+                        ? context.getResources().getDimensionPixelSize(
+                        R.dimen.freeform_decor_shadow_focused_thickness)
+                        : context.getResources().getDimensionPixelSize(
+                                R.dimen.freeform_decor_shadow_unfocused_thickness);
+            }
         } else {
-            relayoutParams.mShadowRadius = INVALID_SHADOW_RADIUS;
+            if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+                relayoutParams.mShadowRadiusId = Resources.ID_NULL;
+            } else {
+                relayoutParams.mShadowRadius = INVALID_SHADOW_RADIUS;
+            }
         }
         relayoutParams.mApplyStartTransactionOnDraw = applyStartTransactionOnDraw;
         relayoutParams.mSetTaskVisibilityPositionAndCrop = shouldSetTaskVisibilityPositionAndCrop;
@@ -1068,8 +1116,13 @@
         relayoutParams.mWindowDecorConfig = windowDecorConfig;
 
         if (DesktopModeStatus.useRoundedCorners()) {
-            relayoutParams.mCornerRadius = shouldIgnoreCornerRadius ? INVALID_CORNER_RADIUS :
-                    getCornerRadius(context, relayoutParams.mLayoutResId);
+            if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+                relayoutParams.mCornerRadiusId = shouldIgnoreCornerRadius ? Resources.ID_NULL :
+                        getCornerRadiusId(relayoutParams.mLayoutResId);
+            } else {
+                relayoutParams.mCornerRadius = shouldIgnoreCornerRadius ? INVALID_CORNER_RADIUS :
+                        getCornerRadius(context, relayoutParams.mLayoutResId);
+            }
         }
         // Set opaque background for all freeform tasks to prevent freeform tasks below
         // from being visible if freeform task window above is translucent.
@@ -1077,6 +1130,7 @@
         relayoutParams.mShouldSetBackground = DesktopModeStatus.shouldSetBackground(taskInfo);
     }
 
+    @Deprecated
     private static int getCornerRadius(@NonNull Context context, int layoutResId) {
         if (layoutResId == R.layout.desktop_mode_app_header) {
             return loadDimensionPixelSize(context.getResources(),
@@ -1086,6 +1140,14 @@
         return INVALID_CORNER_RADIUS;
     }
 
+    private static int getCornerRadiusId(int layoutResId) {
+        if (layoutResId == R.layout.desktop_mode_app_header) {
+            return com.android.wm.shell.shared.R.dimen
+                    .desktop_windowing_freeform_rounded_corner_radius;
+        }
+        return Resources.ID_NULL;
+    }
+
     /**
      * If task has focused window decor, return the caption id of the fullscreen caption size
      * resource. Otherwise, return ID_NULL and caption width be set to task width.
@@ -1720,8 +1782,10 @@
         mExclusionRegionListener.onExclusionRegionDismissed(mTaskInfo.taskId);
         disposeResizeVeil();
         disposeStatusBarInputLayer();
-        mWindowDecorViewHolder.close();
-        mWindowDecorViewHolder = null;
+        if (mWindowDecorViewHolder != null) {
+            mWindowDecorViewHolder.close();
+            mWindowDecorViewHolder = null;
+        }
         if (canEnterDesktopMode(mContext) && isEducationEnabled()) {
             notifyNoCaptionHandle();
         }
@@ -1811,9 +1875,18 @@
      * <p> When a Recents transition is active we allow that transition to take ownership of the
      * corner radius of its task surfaces, so each window decoration should stop updating the corner
      * radius of its task surface during that time.
+     *
+     * We should not allow input to reach the input layer during a Recents transition, so
+     * update the handle view holder accordingly if transition status changes.
      */
     void setIsRecentsTransitionRunning(boolean isRecentsTransitionRunning) {
-        mIsRecentsTransitionRunning = isRecentsTransitionRunning;
+        if (mIsRecentsTransitionRunning != isRecentsTransitionRunning) {
+            mIsRecentsTransitionRunning = isRecentsTransitionRunning;
+            if (DesktopModeFlags.ENABLE_INPUT_LAYER_TRANSITION_FIX.isTrue()) {
+                // We don't relayout decor on recents transition, so we need to call it directly.
+                relayout(mTaskInfo, mHasGlobalFocus, mRelayoutParams.mDisplayExclusionRegion);
+            }
+        }
     }
 
     /**
@@ -1878,6 +1951,7 @@
                 Choreographer choreographer,
                 SyncTransactionQueue syncQueue,
                 AppHeaderViewHolder.Factory appHeaderViewHolderFactory,
+                AppHandleViewHolder.Factory appHandleViewHolderFactory,
                 RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer,
                 AppToWebGenericLinksParser genericLinksParser,
                 AssistContentRequester assistContentRequester,
@@ -1905,6 +1979,7 @@
                     choreographer,
                     syncQueue,
                     appHeaderViewHolderFactory,
+                    appHandleViewHolderFactory,
                     rootTaskDisplayAreaOrganizer,
                     genericLinksParser,
                     assistContentRequester,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 7a4a834..8a8bdca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -23,12 +23,12 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
 
+import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
 import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
 import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_BOTTOM;
 import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_LEFT;
 import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_RIGHT;
 import static com.android.wm.shell.windowdecor.DragPositioningCallback.CTRL_TYPE_TOP;
-import static com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.ResizeTrigger;
 import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEdgeResizePermitted;
 import static com.android.wm.shell.windowdecor.DragResizeWindowGeometry.isEventFromTouchscreen;
 
@@ -127,7 +127,9 @@
             Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
             Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
             DisplayController displayController,
-            DesktopModeEventLogger desktopModeEventLogger) {
+            DesktopModeEventLogger desktopModeEventLogger,
+            InputChannel inputChannel,
+            InputChannel sinkInputChannel) {
         mContext = context;
         mWindowSession = windowSession;
         mBgExecutor = bgExecutor;
@@ -136,7 +138,11 @@
         mHandler = handler;
         mChoreographer = choreographer;
         mDisplayId = displayId;
-        mDecorationSurface = decorationSurface;
+        // Creates a new SurfaceControl pointing the same underlying surface with decorationSurface
+        // to ensure that mDecorationSurface will not be released while it's used on the background
+        // thread. Note that the empty name will be overridden by the next copyFrom call.
+        mDecorationSurface = surfaceControlBuilderSupplier.get().setName("").build();
+        mDecorationSurface.copyFrom(decorationSurface, "DragResizeInputListener");
         mDragPositioningCallback = callback;
         mSurfaceControlBuilderSupplier = surfaceControlBuilderSupplier;
         mSurfaceControlTransactionSupplier = surfaceControlTransactionSupplier;
@@ -154,9 +160,13 @@
             final InputSetUpResult result = setUpInputChannels(mDisplayId, mWindowSession,
                     mDecorationSurface, mClientToken, mSinkClientToken,
                     mSurfaceControlBuilderSupplier,
-                    mSurfaceControlTransactionSupplier);
+                    mSurfaceControlTransactionSupplier, inputChannel, sinkInputChannel);
             mainExecutor.execute(() -> {
                 if (mClosed) {
+                    result.mInputChannel.dispose();
+                    result.mSinkInputChannel.dispose();
+                    mSurfaceControlTransactionSupplier.get().remove(
+                            result.mInputSinkSurface).apply();
                     return;
                 }
                 mInputSinkSurface = result.mInputSinkSurface;
@@ -208,7 +218,7 @@
                 new DefaultTaskResizeInputEventReceiverFactory(), taskInfo,
                 handler, choreographer, displayId, decorationSurface, callback,
                 surfaceControlBuilderSupplier, surfaceControlTransactionSupplier,
-                displayController, desktopModeEventLogger);
+                displayController, desktopModeEventLogger, new InputChannel(), new InputChannel());
     }
 
     DragResizeInputListener(
@@ -251,11 +261,11 @@
             @NonNull IBinder clientToken,
             @NonNull IBinder sinkClientToken,
             @NonNull Supplier<SurfaceControl.Builder> surfaceControlBuilderSupplier,
-            @NonNull Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier) {
+            @NonNull Supplier<SurfaceControl.Transaction> surfaceControlTransactionSupplier,
+            @NonNull InputChannel inputChannel,
+            @NonNull InputChannel sinkInputChannel) {
         Trace.beginSection("DragResizeInputListener#setUpInputChannels");
         final InputTransferToken inputTransferToken = new InputTransferToken();
-        final InputChannel inputChannel = new InputChannel();
-        final InputChannel sinkInputChannel = new InputChannel();
         try {
             windowSession.grantInputChannel(
                     displayId,
@@ -332,6 +342,7 @@
         try {
             mWindowSession.updateInputChannel(
                     mInputChannel.getToken(),
+                    null /* hostInputToken */,
                     mDisplayId,
                     mDecorationSurface,
                     FLAG_NOT_FOCUSABLE,
@@ -373,6 +384,7 @@
         try {
             mWindowSession.updateInputChannel(
                     mSinkInputChannel.getToken(),
+                    null /* hostInputToken */,
                     mDisplayId,
                     mInputSinkSurface,
                     FLAG_NOT_FOCUSABLE,
@@ -421,6 +433,9 @@
             } catch (RemoteException e) {
                 e.rethrowFromSystemServer();
             }
+            // Removing this surface on the background thread to ensure that mInitInputChannels has
+            // already been finished.
+            mSurfaceControlTransactionSupplier.get().remove(mDecorationSurface).apply();
         });
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
index 2d6f745..732f042 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/FluidResizeTaskPositioner.java
@@ -173,6 +173,9 @@
         return new Rect(mRepositionTaskBounds);
     }
 
+    @Override
+    public void close() {}
+
     private boolean isResizing() {
         return (mCtrlType & CTRL_TYPE_TOP) != 0 || (mCtrlType & CTRL_TYPE_BOTTOM) != 0
                 || (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0;
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 a8a7032..9cc64ac 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
@@ -109,15 +109,18 @@
         get() = (DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue() && !taskInfo.isFreeform)
 
     private val pillTopMargin: Int = loadDimensionPixelSize(
-        R.dimen.desktop_mode_handle_menu_pill_spacing_margin)
+        R.dimen.desktop_mode_handle_menu_pill_spacing_margin
+    )
     private val menuWidth = loadDimensionPixelSize(R.dimen.desktop_mode_handle_menu_width)
     private val menuHeight = getHandleMenuHeight()
     private val marginMenuTop = loadDimensionPixelSize(R.dimen.desktop_mode_handle_menu_margin_top)
     private val marginMenuStart = loadDimensionPixelSize(
-        R.dimen.desktop_mode_handle_menu_margin_start)
+        R.dimen.desktop_mode_handle_menu_margin_start
+    )
 
     @VisibleForTesting
     var handleMenuViewContainer: AdditionalViewContainer? = null
+
     @VisibleForTesting
     var handleMenuView: HandleMenuView? = null
 
@@ -136,7 +139,7 @@
 
     private val shouldShowMoreActionsPill: Boolean
         get() = SHOULD_SHOW_SCREENSHOT_BUTTON || shouldShowNewWindowButton ||
-            shouldShowManageWindowsButton || shouldShowChangeAspectRatioButton
+                shouldShowManageWindowsButton || shouldShowChangeAspectRatioButton
 
     private var loadAppInfoJob: Job? = null
 
@@ -240,7 +243,8 @@
         val y = handleMenuPosition.y.toInt()
         handleMenuViewContainer =
             if ((!taskInfo.isFreeform && DesktopModeFlags.ENABLE_HANDLE_INPUT_FIX.isTrue())
-                    || forceShowSystemBars) {
+                || forceShowSystemBars
+            ) {
                 AdditionalSystemViewContainer(
                     windowManagerWrapper = windowManagerWrapper,
                     taskId = taskInfo.taskId,
@@ -251,7 +255,11 @@
                     flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                             WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                     view = handleMenuView.rootView,
-                    forciblyShownTypes = if (forceShowSystemBars) { systemBars() } else { 0 },
+                    forciblyShownTypes = if (forceShowSystemBars) {
+                        systemBars()
+                    } else {
+                        0
+                    },
                     ignoreCutouts = Flags.showAppHandleLargeScreens()
                             || BubbleAnythingFlagHelper.enableBubbleToFullscreen()
                 )
@@ -369,7 +377,8 @@
                 inputPoint.y - globalMenuPosition.y
             )
             if (splitScreenController.getSplitPosition(taskInfo.taskId)
-                == SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT) {
+                == SplitScreenConstants.SPLIT_POSITION_BOTTOM_OR_RIGHT
+            ) {
                 val leftStageBounds = Rect()
                 splitScreenController.getStageBounds(leftStageBounds, Rect())
                 inputRelativeToMenu.x += leftStageBounds.width().toFloat()
@@ -398,7 +407,8 @@
         var menuHeight = loadDimensionPixelSize(R.dimen.desktop_mode_handle_menu_height)
         if (!shouldShowWindowingPill) {
             menuHeight -= loadDimensionPixelSize(
-                R.dimen.desktop_mode_handle_menu_windowing_pill_height)
+                R.dimen.desktop_mode_handle_menu_windowing_pill_height
+            )
             menuHeight -= pillTopMargin
         }
         if (!SHOULD_SHOW_SCREENSHOT_BUTTON) {
@@ -418,14 +428,16 @@
         }
         if (!shouldShowChangeAspectRatioButton) {
             menuHeight -= loadDimensionPixelSize(
-                R.dimen.desktop_mode_handle_menu_change_aspect_ratio_height)
+                R.dimen.desktop_mode_handle_menu_change_aspect_ratio_height
+            )
         }
         if (!shouldShowMoreActionsPill) {
             menuHeight -= pillTopMargin
         }
         if (!shouldShowBrowserPill) {
             menuHeight -= loadDimensionPixelSize(
-                R.dimen.desktop_mode_handle_menu_open_in_browser_pill_height)
+                R.dimen.desktop_mode_handle_menu_open_in_browser_pill_height
+            )
             menuHeight -= pillTopMargin
         }
         return menuHeight
@@ -468,48 +480,66 @@
 
         // Insets for ripple effect of App Info Pill. and Windowing Pill. buttons
         val iconButtondrawableShiftInset = context.resources.getDimensionPixelSize(
-            R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_shift)
+            R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_shift
+        )
         val iconButtondrawableBaseInset = context.resources.getDimensionPixelSize(
-            R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_base)
+            R.dimen.desktop_mode_handle_menu_icon_button_ripple_inset_base
+        )
         private val iconButtonRippleRadius = context.resources.getDimensionPixelSize(
-            R.dimen.desktop_mode_handle_menu_icon_button_ripple_radius)
-        private val iconButtonDrawableInsetsBase = DrawableInsets(t = iconButtondrawableBaseInset,
+            R.dimen.desktop_mode_handle_menu_icon_button_ripple_radius
+        )
+        private val iconButtonDrawableInsetsBase = DrawableInsets(
+            t = iconButtondrawableBaseInset,
             b = iconButtondrawableBaseInset, l = iconButtondrawableBaseInset,
-            r = iconButtondrawableBaseInset)
-        private val iconButtonDrawableInsetsLeft = DrawableInsets(t = iconButtondrawableBaseInset,
-            b = iconButtondrawableBaseInset, l = iconButtondrawableShiftInset, r = 0)
-        private val iconButtonDrawableInsetsRight = DrawableInsets(t = iconButtondrawableBaseInset,
-            b = iconButtondrawableBaseInset, l = 0, r = iconButtondrawableShiftInset)
+            r = iconButtondrawableBaseInset
+        )
+        private val iconButtonDrawableInsetsLeft = DrawableInsets(
+            t = iconButtondrawableBaseInset,
+            b = iconButtondrawableBaseInset, l = iconButtondrawableShiftInset, r = 0
+        )
+        private val iconButtonDrawableInsetsRight = DrawableInsets(
+            t = iconButtondrawableBaseInset,
+            b = iconButtondrawableBaseInset, l = 0, r = iconButtondrawableShiftInset
+        )
 
         // App Info Pill.
         private val appInfoPill = rootView.requireViewById<View>(R.id.app_info_pill)
         private val collapseMenuButton = appInfoPill.requireViewById<HandleMenuImageButton>(
-            R.id.collapse_menu_button)
+            R.id.collapse_menu_button
+        )
+
         @VisibleForTesting
         val appIconView = appInfoPill.requireViewById<ImageView>(R.id.application_icon)
+
         @VisibleForTesting
         val appNameView = appInfoPill.requireViewById<MarqueedTextView>(R.id.application_name)
 
         // Windowing Pill.
         private val windowingPill = rootView.requireViewById<View>(R.id.windowing_pill)
         private val fullscreenBtn = windowingPill.requireViewById<ImageButton>(
-            R.id.fullscreen_button)
+            R.id.fullscreen_button
+        )
         private val splitscreenBtn = windowingPill.requireViewById<ImageButton>(
-            R.id.split_screen_button)
+            R.id.split_screen_button
+        )
         private val floatingBtn = windowingPill.requireViewById<ImageButton>(R.id.floating_button)
         private val floatingBtnSpace = windowingPill.requireViewById<Space>(
-            R.id.floating_button_space)
+            R.id.floating_button_space
+        )
 
         private val desktopBtn = windowingPill.requireViewById<ImageButton>(R.id.desktop_button)
         private val desktopBtnSpace = windowingPill.requireViewById<Space>(
-            R.id.desktop_button_space)
+            R.id.desktop_button_space
+        )
 
         // More Actions Pill.
         private val moreActionsPill = rootView.requireViewById<View>(R.id.more_actions_pill)
         private val screenshotBtn = moreActionsPill.requireViewById<HandleMenuActionButton>(
-            R.id.screenshot_button)
+            R.id.screenshot_button
+        )
         private val newWindowBtn = moreActionsPill.requireViewById<HandleMenuActionButton>(
-            R.id.new_window_button)
+            R.id.new_window_button
+        )
         private val manageWindowBtn = moreActionsPill
             .requireViewById<HandleMenuActionButton>(R.id.manage_windows_button)
         private val changeAspectRatioBtn = moreActionsPill
@@ -517,11 +547,14 @@
 
         // Open in Browser/App Pill.
         private val openInAppOrBrowserPill = rootView.requireViewById<View>(
-            R.id.open_in_app_or_browser_pill)
+            R.id.open_in_app_or_browser_pill
+        )
         private val openInAppOrBrowserBtn = openInAppOrBrowserPill.requireViewById<View>(
-            R.id.open_in_app_or_browser_button)
+            R.id.open_in_app_or_browser_button
+        )
         private val openByDefaultBtn = openInAppOrBrowserPill.requireViewById<ImageButton>(
-            R.id.open_by_default_button)
+            R.id.open_by_default_button
+        )
         private val decorThemeUtil = DecorThemeUtil(context)
         private val animator = HandleMenuAnimator(rootView, menuWidth, captionHeight.toFloat())
 
@@ -730,9 +763,9 @@
             desktopBtn.imageTintList = style.windowingButtonColor
 
             val startInsets = if (context.isRtl) iconButtonDrawableInsetsRight
-                else iconButtonDrawableInsetsLeft
+            else iconButtonDrawableInsetsLeft
             val endInsets = if (context.isRtl) iconButtonDrawableInsetsLeft
-                else iconButtonDrawableInsetsRight
+            else iconButtonDrawableInsetsRight
 
             fullscreenBtn.apply {
                 background = createBackgroundDrawable(
@@ -804,9 +837,11 @@
                 getString(R.string.open_in_browser_text)
             }
 
+            val buttonRoot = openInAppOrBrowserBtn.requireViewById<LinearLayout>(R.id.action_button)
             val label = openInAppOrBrowserBtn.requireViewById<MarqueedTextView>(R.id.label)
             val image = openInAppOrBrowserBtn.requireViewById<ImageView>(R.id.image)
             openInAppOrBrowserBtn.contentDescription = btnText
+            buttonRoot.contentDescription = btnText
             label.apply {
                 text = btnText
                 setTextColor(style.textColor)
@@ -837,7 +872,7 @@
          */
         fun shouldShowChangeAspectRatioButton(taskInfo: RunningTaskInfo): Boolean =
             taskInfo.appCompatTaskInfo.eligibleForUserAspectRatioButton() &&
-                taskInfo.windowingMode == WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+                    taskInfo.windowingMode == WindowConfiguration.WINDOWING_MODE_FULLSCREEN
     }
 }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt
index 4b2e473..a723a7a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/HandleMenuActionButton.kt
@@ -23,9 +23,7 @@
 import android.view.LayoutInflater
 import android.widget.ImageView
 import android.widget.LinearLayout
-import android.widget.TextView
 import androidx.core.content.withStyledAttributes
-import androidx.core.view.isGone
 import com.android.wm.shell.R
 
 /**
@@ -54,6 +52,7 @@
 
         context.withStyledAttributes(attrs, R.styleable.HandleMenuActionButton) {
             textView.text = getString(R.styleable.HandleMenuActionButton_android_text)
+            rootElement.contentDescription = getString(R.styleable.HandleMenuActionButton_android_text)
             textView.setTextColor(getColor(R.styleable.HandleMenuActionButton_android_textColor, 0))
             iconView.setImageResource(getResourceId(
                 R.styleable.HandleMenuActionButton_android_src, 0))
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt
index 1b0e0f70..2382427 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositioner.kt
@@ -278,13 +278,16 @@
                         currentDisplayLayout,
                     )
                 )
-
-                multiDisplayDragMoveIndicatorController.onDragEnd(
-                    desktopWindowDecoration.mTaskInfo.taskId,
-                    transactionSupplier,
-                )
             }
 
+            // Call the MultiDisplayDragMoveIndicatorController to clear any active indicator
+            // surfaces. This is necessary even if the drag ended on the same display, as surfaces
+            // may have been created for other displays during the drag.
+            multiDisplayDragMoveIndicatorController.onDragEnd(
+                desktopWindowDecoration.mTaskInfo.taskId,
+                transactionSupplier,
+            )
+
             interactionJankMonitor.end(Cuj.CUJ_DESKTOP_MODE_DRAG_WINDOW)
         }
 
@@ -294,6 +297,10 @@
         return Rect(repositionTaskBounds)
     }
 
+    override fun close() {
+        displayController.removeDisplayWindowListener(this)
+    }
+
     private fun resetVeilIfVisible() {
         if (isResizingOrAnimatingResize) {
             desktopWindowDecoration.hideResizeVeil()
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskDragResizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskDragResizer.java
index 63b288d..06e5380 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskDragResizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/TaskDragResizer.java
@@ -41,4 +41,10 @@
      */
     void removeDragEventListener(
             DragPositioningCallbackUtility.DragEventListener dragEventListener);
+
+    /**
+     * Releases any resources associated with this TaskDragResizer. This should be called when the
+     * associated window is closed.
+     */
+    void close();
 }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
index d2c79d7..7e941ec 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/VeiledResizeTaskPositioner.java
@@ -205,6 +205,9 @@
         return new Rect(mRepositionTaskBounds);
     }
 
+    @Override
+    public void close() {}
+
     private boolean isResizing() {
         return (mCtrlType & CTRL_TYPE_TOP) != 0 || (mCtrlType & CTRL_TYPE_BOTTOM) != 0
                 || (mCtrlType & CTRL_TYPE_LEFT) != 0 || (mCtrlType & CTRL_TYPE_RIGHT) != 0;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
index 1563259..5e4a0a5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecorViewModel.java
@@ -18,6 +18,7 @@
 
 import android.app.ActivityManager;
 import android.view.SurfaceControl;
+import android.window.TransitionInfo;
 
 import com.android.wm.shell.freeform.FreeformTaskTransitionStarter;
 import com.android.wm.shell.splitscreen.SplitScreenController;
@@ -83,12 +84,14 @@
      * @param taskSurface the surface of the task
      * @param startT      the start transaction to be applied before the transition
      * @param finishT     the finish transaction to restore states after the transition
+     * @param changeMode  the type of change to the task
      */
     void onTaskChanging(
             ActivityManager.RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
             SurfaceControl.Transaction startT,
-            SurfaceControl.Transaction finishT);
+            SurfaceControl.Transaction finishT,
+            @TransitionInfo.TransitionMode int changeMode);
 
     /**
      * Notifies that the given task is about to close to give the window decoration a chance to
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index bde46a1..6fd963f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -47,6 +47,7 @@
 import android.view.View;
 import android.view.WindowManager;
 import android.view.WindowlessWindowManager;
+import android.window.DesktopExperienceFlags;
 import android.window.SurfaceSyncGroup;
 import android.window.TaskConstants;
 import android.window.WindowContainerToken;
@@ -286,6 +287,14 @@
         outResult.mCaptionX = (outResult.mWidth - outResult.mCaptionWidth) / 2;
         outResult.mCaptionY = 0;
         outResult.mCaptionTopPadding = params.mCaptionTopPadding;
+        if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+            outResult.mCornerRadius = params.mCornerRadiusId == Resources.ID_NULL
+                    ? INVALID_CORNER_RADIUS : loadDimensionPixelSize(resources,
+                    params.mCornerRadiusId);
+            outResult.mShadowRadius = params.mShadowRadiusId == Resources.ID_NULL
+                    ? INVALID_SHADOW_RADIUS : loadDimensionPixelSize(resources,
+                    params.mShadowRadiusId);
+        }
 
         Trace.beginSection("relayout-createViewHostIfNeeded");
         createViewHostIfNeeded(mDecorWindowContext, mDisplay);
@@ -497,9 +506,16 @@
                     .setPosition(mTaskSurface, taskPosition.x, taskPosition.y);
         }
 
-        if (params.mShadowRadius != INVALID_SHADOW_RADIUS) {
-            startT.setShadowRadius(mTaskSurface, params.mShadowRadius);
-            finishT.setShadowRadius(mTaskSurface, params.mShadowRadius);
+        if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+            if (outResult.mShadowRadius != INVALID_SHADOW_RADIUS) {
+                startT.setShadowRadius(mTaskSurface, outResult.mShadowRadius);
+                finishT.setShadowRadius(mTaskSurface, outResult.mShadowRadius);
+            }
+        } else {
+            if (params.mShadowRadius != INVALID_SHADOW_RADIUS) {
+                startT.setShadowRadius(mTaskSurface, params.mShadowRadius);
+                finishT.setShadowRadius(mTaskSurface, params.mShadowRadius);
+            }
         }
 
         if (params.mSetTaskVisibilityPositionAndCrop) {
@@ -517,9 +533,16 @@
             startT.unsetColor(mTaskSurface);
         }
 
-        if (params.mCornerRadius != INVALID_CORNER_RADIUS) {
-            startT.setCornerRadius(mTaskSurface, params.mCornerRadius);
-            finishT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+        if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+            if (outResult.mCornerRadius != INVALID_CORNER_RADIUS) {
+                startT.setCornerRadius(mTaskSurface, outResult.mCornerRadius);
+                finishT.setCornerRadius(mTaskSurface, outResult.mCornerRadius);
+            }
+        } else {
+            if (params.mCornerRadius != INVALID_CORNER_RADIUS) {
+                startT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+                finishT.setCornerRadius(mTaskSurface, params.mCornerRadius);
+            }
         }
     }
 
@@ -699,6 +722,9 @@
     public void close() {
         Trace.beginSection("WindowDecoration#close");
         mDisplayController.removeDisplayWindowListener(mOnDisplaysChangedListener);
+        if (mTaskDragResizer != null) {
+            mTaskDragResizer.close();
+        }
         final WindowContainerTransaction wct = mWindowContainerTransactionSupplier.get();
         releaseViews(wct);
         mTaskOrganizer.applyTransaction(wct);
@@ -821,9 +847,14 @@
         @InsetsSource.Flags int mInsetSourceFlags;
         final Region mDisplayExclusionRegion = Region.obtain();
 
+        @Deprecated
         int mShadowRadius = INVALID_SHADOW_RADIUS;
+        @Deprecated
         int mCornerRadius = INVALID_CORNER_RADIUS;
 
+        int mShadowRadiusId = Resources.ID_NULL;
+        int mCornerRadiusId = Resources.ID_NULL;
+
         int mCaptionTopPadding;
         boolean mIsCaptionVisible;
 
@@ -846,9 +877,13 @@
             mIsInsetSource = true;
             mInsetSourceFlags = 0;
             mDisplayExclusionRegion.setEmpty();
-
-            mShadowRadius = INVALID_SHADOW_RADIUS;
-            mCornerRadius = INVALID_SHADOW_RADIUS;
+            if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+                mShadowRadiusId = Resources.ID_NULL;
+                mCornerRadiusId = Resources.ID_NULL;
+            } else {
+                mShadowRadius = INVALID_SHADOW_RADIUS;
+                mCornerRadius = INVALID_SHADOW_RADIUS;
+            }
 
             mCaptionTopPadding = 0;
             mIsCaptionVisible = false;
@@ -890,6 +925,8 @@
         int mWidth;
         int mHeight;
         T mRootView;
+        int mCornerRadius;
+        int mShadowRadius;
 
         void reset() {
             mWidth = 0;
@@ -901,6 +938,10 @@
             mCaptionTopPadding = 0;
             mCustomizableCaptionRegion.setEmpty();
             mRootView = null;
+            if (DesktopExperienceFlags.ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX.isTrue()) {
+                mCornerRadius = INVALID_CORNER_RADIUS;
+                mShadowRadius = INVALID_SHADOW_RADIUS;
+            }
         }
     }
 
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
index 9c55f0e..854d9e1 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecoration.kt
@@ -137,6 +137,7 @@
         // Observe drag resizing to break tiling if a task is drag resized.
         desktopModeWindowDecoration.addDragResizeListener(this)
         val callback = { initTilingForDisplayIfNeeded(taskInfo.configuration, isFirstTiledApp) }
+        updateDesktopRepository(taskInfo.taskId, snapPosition = position)
         if (isTiled) {
             val wct = WindowContainerTransaction().setBounds(taskInfo.token, destinationBounds)
             toggleResizeDesktopTaskTransitionHandler.startTransition(wct, currentBounds, callback)
@@ -152,11 +153,21 @@
                     endBounds = destinationBounds,
                     callback,
                 )
+            } else {
+                callback.invoke()
             }
         }
         return isTiled
     }
 
+    private fun updateDesktopRepository(taskId: Int, snapPosition: SnapPosition) {
+        when (snapPosition) {
+            SnapPosition.LEFT -> desktopUserRepositories.current.addLeftTiledTask(displayId, taskId)
+            SnapPosition.RIGHT ->
+                desktopUserRepositories.current.addRightTiledTask(displayId, taskId)
+        }
+    }
+
     // If a task is already tiled on the same position, release this task, otherwise if the same
     // task is tiled on the opposite side, remove it from the opposite side so it's tiled correctly.
     private fun initTilingApps(
@@ -578,6 +589,7 @@
     ) {
         val taskRepository = desktopUserRepositories.current
         if (taskId == leftTaskResizingHelper?.taskInfo?.taskId) {
+            desktopUserRepositories.current.removeLeftTiledTask(displayId)
             removeTask(leftTaskResizingHelper, taskVanished, shouldDelayUpdate)
             leftTaskResizingHelper = null
             val taskId = rightTaskResizingHelper?.taskInfo?.taskId
@@ -591,6 +603,7 @@
         }
 
         if (taskId == rightTaskResizingHelper?.taskInfo?.taskId) {
+            desktopUserRepositories.current.removeRightTiledTask(displayId)
             removeTask(rightTaskResizingHelper, taskVanished, shouldDelayUpdate)
             rightTaskResizingHelper = null
             val taskId = leftTaskResizingHelper?.taskInfo?.taskId
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 d9df899f..0985587 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
@@ -49,7 +49,7 @@
  * A desktop mode window decoration used when the window is in full "focus" (i.e. fullscreen/split).
  * It hosts a simple handle bar from which to initiate a drag motion to enter desktop mode.
  */
-internal class AppHandleViewHolder(
+class AppHandleViewHolder(
     rootView: View,
     onCaptionTouchListener: View.OnTouchListener,
     onCaptionButtonClickListener: OnClickListener,
@@ -66,7 +66,7 @@
         val position: Point,
         val width: Int,
         val height: Int,
-        val isCaptionVisible: Boolean
+        val showInputLayer: Boolean
     ) : Data()
 
     private lateinit var taskInfo: RunningTaskInfo
@@ -101,7 +101,7 @@
     }
 
     override fun bindData(data: HandleData) {
-        bindData(data.taskInfo, data.position, data.width, data.height, data.isCaptionVisible)
+        bindData(data.taskInfo, data.position, data.width, data.height, data.showInputLayer)
     }
 
     private fun bindData(
@@ -109,14 +109,13 @@
         position: Point,
         width: Int,
         height: Int,
-        isCaptionVisible: Boolean
+        showInputLayer: Boolean
     ) {
         captionHandle.imageTintList = ColorStateList.valueOf(getCaptionHandleBarColor(taskInfo))
         this.taskInfo = taskInfo
         // If handle is not in status bar region(i.e., bottom stage in vertical split),
         // do not create an input layer
-        if (position.y >= SystemBarUtils.getStatusBarHeight(context)) return
-        if (!isCaptionVisible) {
+        if (position.y >= SystemBarUtils.getStatusBarHeight(context) || !showInputLayer) {
             disposeStatusBarInputLayer()
             return
         }
@@ -276,4 +275,25 @@
     }
 
     override fun close() {}
+
+    /** Factory class for creating [AppHandleViewHolder] objects. */
+    class Factory {
+        /**
+         * Create a [AppHandleViewHolder] object to handle caption view and status bar
+         * input layer logic.
+         */
+        fun create(
+            rootView: View,
+            onCaptionTouchListener: View.OnTouchListener,
+            onCaptionButtonClickListener: OnClickListener,
+            windowManagerWrapper: WindowManagerWrapper,
+            handler: Handler,
+        ): AppHandleViewHolder = AppHandleViewHolder(
+            rootView,
+            onCaptionTouchListener,
+            onCaptionButtonClickListener,
+            windowManagerWrapper,
+            handler,
+        )
+    }
 }
diff --git a/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/SimulatedConnectedDisplayTestRule.kt b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/SimulatedConnectedDisplayTestRule.kt
new file mode 100644
index 0000000..68f7ef0
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/e2e/utils/src/com/android/wm/shell/SimulatedConnectedDisplayTestRule.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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
+
+import android.graphics.Point
+import android.hardware.display.DisplayManager
+import android.hardware.display.DisplayManager.DisplayListener
+import android.os.Handler
+import android.os.Looper
+import android.provider.Settings
+import android.util.Log
+import androidx.test.platform.app.InstrumentationRegistry
+import kotlin.time.Duration.Companion.seconds
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.take
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.withTimeoutOrNull
+import org.junit.rules.TestRule
+import org.junit.runner.Description
+import org.junit.runners.model.Statement
+
+/**
+ * A TestRule to manage multiple simulated connected overlay displays.
+ */
+class SimulatedConnectedDisplayTestRule : TestRule {
+
+    private val context = InstrumentationRegistry.getInstrumentation().targetContext
+    private val uiAutomation = InstrumentationRegistry.getInstrumentation().uiAutomation
+    private val displayManager = context.getSystemService(DisplayManager::class.java)
+    private val addedDisplays = mutableListOf<Int>()
+
+    override fun apply(base: Statement, description: Description): Statement =
+        object : Statement() {
+            override fun evaluate() {
+                try {
+                    base.evaluate()
+                } finally {
+                    teardown()
+                }
+            }
+        }
+
+    private fun teardown() {
+        cleanupTestDisplays()
+    }
+
+    /**
+     * Adds multiple overlay displays with specified dimensions. Any existing overlay displays
+     * will be removed before adding the new ones.
+     *
+     * @param displays A list of [Point] objects, where each [Point] represents the
+     *                 width and height of a simulated display.
+     * @return List of displayIds of added displays.
+     */
+    fun setupTestDisplays(displays: List<Point>): List<Int> = runBlocking {
+        // Cleanup any existing overlay displays.
+        cleanupTestDisplays()
+
+        if (displays.isEmpty()) {
+            Log.w(TAG, "setupTestDisplays called with an empty list. No displays created.")
+            return@runBlocking emptyList()
+        }
+
+        val displayAddedFlow: Flow<Int> = callbackFlow {
+            val listener = object : DisplayListener {
+                override fun onDisplayAdded(displayId: Int) {
+                    trySend(displayId)
+                }
+
+                override fun onDisplayRemoved(displayId: Int) {}
+                override fun onDisplayChanged(displayId: Int) {}
+            }
+
+            val handler = Handler(Looper.getMainLooper())
+            displayManager.registerDisplayListener(listener, handler)
+
+            awaitClose {
+                displayManager.unregisterDisplayListener(listener)
+            }
+        }
+
+        val displaySettings = displays.joinToString(separator = ";") { size ->
+            "${size.x}x${size.y}/$DEFAULT_DENSITY"
+        }
+
+        // Add the overlay displays
+        Settings.Global.putString(
+            InstrumentationRegistry.getInstrumentation().context.contentResolver,
+            Settings.Global.OVERLAY_DISPLAY_DEVICES, displaySettings
+        )
+        withTimeoutOrNull(TIMEOUT) {
+            displayAddedFlow.take(displays.size).collect { displayId ->
+                addedDisplays.add(displayId)
+            }
+        } ?: error("Timed out waiting for displays to be added.")
+        addedDisplays
+    }
+
+    /**
+     * Adds multiple overlay displays with default dimensions. Any existing overlay displays
+     * will be removed before adding the new ones.
+     *
+     * @param count number of displays to add.
+     * @return List of displayIds of added displays.
+     */
+    fun setupTestDisplays(count: Int): List<Int> {
+        val displays = List(count) { Point(DEFAULT_WIDTH, DEFAULT_HEIGHT) }
+        return setupTestDisplays(displays)
+    }
+
+    private fun cleanupTestDisplays() = runBlocking {
+        if (addedDisplays.isEmpty()) {
+            return@runBlocking
+        }
+
+        val displayRemovedFlow: Flow<Int> = callbackFlow {
+            val listener = object : DisplayListener {
+                override fun onDisplayAdded(displayId: Int) {}
+                override fun onDisplayRemoved(displayId: Int) {
+                    trySend(displayId)
+                }
+
+                override fun onDisplayChanged(displayId: Int) {}
+            }
+            val handler = Handler(Looper.getMainLooper())
+            displayManager.registerDisplayListener(listener, handler)
+
+            awaitClose {
+                displayManager.unregisterDisplayListener(listener)
+            }
+        }
+
+        // Remove overlay displays
+        Settings.Global.putString(
+            InstrumentationRegistry.getInstrumentation().context.contentResolver,
+            Settings.Global.OVERLAY_DISPLAY_DEVICES, null)
+
+        withTimeoutOrNull(TIMEOUT) {
+            displayRemovedFlow.take(addedDisplays.size).collect { displayId ->
+                addedDisplays.remove(displayId)
+            }
+        } ?: error("Timed out waiting for displays to be removed.")
+    }
+
+    private companion object {
+        const val DEFAULT_WIDTH = 1280
+        const val DEFAULT_HEIGHT = 720
+        const val DEFAULT_DENSITY = 160
+        const val TAG = "SimulatedConnectedDisplayTestRule"
+        val TIMEOUT = 10.seconds
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt
index 509f4f2..8e1cf167 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/CommonAssertions.kt
@@ -254,6 +254,16 @@
     }
 }
 
+/**
+ * Checks that surfaces are still within the expected region after snapping to a snap point.
+ *
+ * @param component The component we are checking (should be one of the two split apps)
+ * @param landscapePosLeft If [true], and device is in left/right split, app is on the left side of
+ * the screen. Has no meaning if device is in top/bottom split.
+ * @param portraitPosTop If [true], and device is in top/bottom split, app is on the top side of
+ * the screen. Has no meaning if device is in left/right split.
+ * @param rotation The rotation state of the display.
+ */
 fun LayerTraceEntrySubject.splitAppLayerBoundsSnapToDivider(
     component: IComponentMatcher,
     landscapePosLeft: Boolean,
@@ -268,10 +278,12 @@
         visibleRegion(component).isNotEmpty()
         visibleRegion(component)
             .coversAtMost(
+                // TODO (b/403082705): Should use the new method for determining left/right split.
                 if (displayBounds.width() > displayBounds.height()) {
                     if (landscapePosLeft) {
                         Region(
-                            0,
+                            // TODO (b/403304310): Check if we're in an offscreen-enabled mode.
+                            -displayBounds.right, // the receding app can go offscreen
                             0,
                             (dividerRegion.left + dividerRegion.right) / 2,
                             displayBounds.bottom
@@ -280,7 +292,7 @@
                         Region(
                             (dividerRegion.left + dividerRegion.right) / 2,
                             0,
-                            displayBounds.right,
+                            displayBounds.right * 2, // the receding app can go offscreen
                             displayBounds.bottom
                         )
                     }
@@ -288,7 +300,7 @@
                     if (portraitPosTop) {
                         Region(
                             0,
-                            0,
+                            -displayBounds.bottom, // the receding app can go offscreen
                             displayBounds.right,
                             (dividerRegion.top + dividerRegion.bottom) / 2
                         )
@@ -297,7 +309,7 @@
                             0,
                             (dividerRegion.top + dividerRegion.bottom) / 2,
                             displayBounds.right,
-                            displayBounds.bottom
+                            displayBounds.bottom * 2 // the receding app can go offscreen
                         )
                     }
                 }
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
index 49d6877..e4183f1 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/utils/SplitScreenUtils.kt
@@ -310,12 +310,18 @@
         }
     }
 
+    /**
+     * Drags the divider, then releases, making it snap to a new snap point.
+     */
     fun dragDividerToResizeAndWait(device: UiDevice, wmHelper: WindowManagerStateHelper) {
+        // Find the first display that is turned on (making the assumption that there is only one).
         val displayBounds =
-            wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual }?.layerStackSpace
-                ?: error("Display not found")
+            wmHelper.currentState.layerState.displays.firstOrNull { !it.isVirtual && it.isOn }
+                ?.layerStackSpace ?: error("Display not found")
         val dividerBar = device.wait(Until.findObject(dividerBarSelector), TIMEOUT_MS)
-        dividerBar.drag(Point(displayBounds.width() * 1 / 3, displayBounds.height() * 2 / 3), 200)
+        // Drag to a point on the lower left of the screen -- this will cause the divider to snap
+        // to the left- or bottom-side snap point, shrinking the "primary" test app.
+        dividerBar.drag(Point(displayBounds.width() * 1 / 4, displayBounds.height() * 3 / 4), 200)
 
         wmHelper
             .StateSyncBuilder()
diff --git a/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml b/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
index aa1b241..33ea0ba 100644
--- a/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/tests/unittest/res/values/dimen.xml
@@ -18,6 +18,8 @@
     <!-- Resources used in WindowDecorationTests -->
     <dimen name="test_freeform_decor_caption_height">32dp</dimen>
     <dimen name="test_freeform_decor_caption_menu_width">216dp</dimen>
+    <dimen name="test_freeform_shadow_radius">20dp</dimen>
+    <dimen name="test_freeform_corner_radius">16dp</dimen>
     <dimen name="test_window_decor_left_outset">10dp</dimen>
     <dimen name="test_window_decor_top_outset">20dp</dimen>
     <dimen name="test_window_decor_right_outset">30dp</dimen>
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 05750a5..b139c00 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -889,8 +889,8 @@
      */
     private void doStartEvents(int startX, int moveX) {
         doMotionEvent(MotionEvent.ACTION_DOWN, startX);
-        mController.onThresholdCrossed();
         doMotionEvent(MotionEvent.ACTION_MOVE, moveX);
+        mController.onThresholdCrossed();
     }
 
     private void simulateRemoteAnimationStart() throws RemoteException {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 7a7d88b..b3d2db6 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.Notification;
@@ -804,7 +803,7 @@
         mBubbleData.setListener(mListener);
 
         changeExpandedStateAtTime(true, 2000L);
-        verifyZeroInteractions(mListener);
+        verifyNoMoreInteractions(mListener);
     }
 
     /**
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java
index 25f17fe..2de77b2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleTransitionsTest.java
@@ -30,6 +30,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.ArgumentMatchers.isNull;
+import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
@@ -37,6 +38,7 @@
 import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.os.IBinder;
@@ -47,7 +49,9 @@
 import android.window.WindowContainerToken;
 import android.window.WindowContainerTransaction;
 
+import androidx.core.animation.AnimatorTestRule;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.launcher3.icons.BubbleIconFactory;
 import com.android.wm.shell.ShellTaskOrganizer;
@@ -65,6 +69,7 @@
 import com.android.wm.shell.transition.Transitions;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
@@ -76,6 +81,8 @@
 @SmallTest
 public class BubbleTransitionsTest extends ShellTestCase {
 
+    @Rule public final AnimatorTestRule mAnimatorTestRule = new AnimatorTestRule();
+
     private static final int FULLSCREEN_TASK_WIDTH = 200;
     private static final int FULLSCREEN_TASK_HEIGHT = 100;
 
@@ -292,23 +299,71 @@
     @Test
     public void convertDraggedBubbleToFullscreen() {
         ActivityManager.RunningTaskInfo taskInfo = setupBubble();
+        SurfaceControl.Transaction animT = mock(SurfaceControl.Transaction.class);
+        BubbleTransitions.TransactionProvider transactionProvider = () -> animT;
         final DraggedBubbleIconToFullscreen bt =
-                (DraggedBubbleIconToFullscreen) mBubbleTransitions
-                        .startDraggedBubbleIconToFullscreen(mBubble);
+                mBubbleTransitions.new DraggedBubbleIconToFullscreen(
+                        mBubble, new Point(100, 50), transactionProvider);
         verify(mTransitions).startTransition(anyInt(), any(), eq(bt));
 
+        SurfaceControl taskLeash = new SurfaceControl.Builder().setName("taskLeash").build();
         final TransitionInfo info = new TransitionInfo(TRANSIT_TO_FRONT, 0);
-        final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token,
-                mock(SurfaceControl.class));
+        final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token, taskLeash);
         chg.setMode(TRANSIT_TO_FRONT);
         chg.setTaskInfo(taskInfo);
         info.addChange(chg);
         info.addRoot(new TransitionInfo.Root(0, mock(SurfaceControl.class), 0, 0));
         SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
         SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class);
-        Transitions.TransitionFinishCallback finishCb = wct -> {};
-        bt.startAnimation(bt.mTransition, info, startT, finishT, finishCb);
+        boolean[] transitionFinished = {false};
+        Transitions.TransitionFinishCallback finishCb = wct -> transitionFinished[0] = true;
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            bt.startAnimation(bt.mTransition, info, startT, finishT, finishCb);
+            mAnimatorTestRule.advanceTimeBy(250);
+        });
+        verify(startT).setScale(taskLeash, 0, 0);
+        verify(startT).setPosition(taskLeash, 100, 50);
         verify(startT).apply();
+        verify(animT).setScale(taskLeash, 1, 1);
+        verify(animT).setPosition(taskLeash, 0, 0);
+        verify(animT, atLeastOnce()).apply();
+        verify(animT).close();
+        assertFalse(mTaskViewTransitions.hasPending());
+        assertTrue(transitionFinished[0]);
+    }
+
+    @Test
+    public void convertFloatingBubbleToFullscreen() {
+        final BubbleExpandedView bev = mock(BubbleExpandedView.class);
+        final ViewRootImpl vri = mock(ViewRootImpl.class);
+        when(bev.getViewRootImpl()).thenReturn(vri);
+        when(mBubble.getBubbleBarExpandedView()).thenReturn(null);
+        when(mBubble.getExpandedView()).thenReturn(bev);
+
+        ActivityManager.RunningTaskInfo taskInfo = setupBubble();
+        final BubbleTransitions.BubbleTransition bt = mBubbleTransitions.startConvertFromBubble(
+                mBubble, taskInfo);
+        final BubbleTransitions.ConvertFromBubble cfb = (BubbleTransitions.ConvertFromBubble) bt;
+        verify(mTransitions).startTransition(anyInt(), any(), eq(cfb));
+        verify(mBubble).setPreparingTransition(eq(bt));
+        assertTrue(mTaskViewTransitions.hasPending());
+
+        final TransitionInfo info = new TransitionInfo(TRANSIT_CHANGE, 0);
+        final TransitionInfo.Change chg = new TransitionInfo.Change(taskInfo.token,
+                mock(SurfaceControl.class));
+        chg.setMode(TRANSIT_CHANGE);
+        chg.setTaskInfo(taskInfo);
+        info.addChange(chg);
+        info.addRoot(new TransitionInfo.Root(0, mock(SurfaceControl.class), 0, 0));
+        SurfaceControl.Transaction startT = mock(SurfaceControl.Transaction.class);
+        SurfaceControl.Transaction finishT = mock(SurfaceControl.Transaction.class);
+        Transitions.TransitionFinishCallback finishCb = wct -> {};
+        cfb.startAnimation(cfb.mTransition, info, startT, finishT, finishCb);
+
+        // Can really only verify that it interfaces with the taskViewTransitions queue.
+        // The actual functioning of this is tightly-coupled with SurfaceFlinger and renderthread
+        // in order to properly synchronize surface manipulation with drawing and thus can't be
+        // directly tested.
         assertFalse(mTaskViewTransitions.hasPending());
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandlerTest.java
index c4b9c9b..b4b9679 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubblesNavBarMotionEventHandlerTest.java
@@ -25,7 +25,6 @@
 import static org.mockito.ArgumentMatchers.floatThat;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.os.SystemClock;
 import android.testing.AndroidTestingRunner;
@@ -84,7 +83,7 @@
         verify(mMotionEventListener).onMove(0, -600);
         // Check that velocity up is about 5000
         verify(mMotionEventListener).onUp(eq(0f), floatThat(f -> Math.round(f) == -5000));
-        verifyZeroInteractions(mMotionEventListener);
+        verifyNoMoreInteractions(mMotionEventListener);
         verify(mInterceptTouchRunnable).run();
     }
 
@@ -94,8 +93,8 @@
         mMotionEventHandler.onMotionEvent(newEvent(ACTION_MOVE, 0, 100));
         mMotionEventHandler.onMotionEvent(newEvent(ACTION_UP, 0, 100));
 
-        verifyZeroInteractions(mMotionEventListener);
-        verifyZeroInteractions(mInterceptTouchRunnable);
+        verifyNoMoreInteractions(mMotionEventListener);
+        verifyNoMoreInteractions(mInterceptTouchRunnable);
     }
 
     @Test
@@ -107,7 +106,7 @@
         verify(mMotionEventListener).onDown(0, 990);
         verify(mMotionEventListener).onMove(100, 0);
         verify(mMotionEventListener).onUp(0, 0);
-        verifyZeroInteractions(mMotionEventListener);
+        verifyNoMoreInteractions(mMotionEventListener);
         verify(mInterceptTouchRunnable).run();
     }
 
@@ -119,7 +118,7 @@
 
         verify(mMotionEventListener).onDown(0, 990);
         verifyNoMoreInteractions(mMotionEventListener);
-        verifyZeroInteractions(mInterceptTouchRunnable);
+        verifyNoMoreInteractions(mInterceptTouchRunnable);
     }
 
     @Test
@@ -129,7 +128,7 @@
         verify(mMotionEventListener).onDown(0, 990);
         verify(mMotionEventListener).onCancel();
         verifyNoMoreInteractions(mMotionEventListener);
-        verifyZeroInteractions(mInterceptTouchRunnable);
+        verifyNoMoreInteractions(mInterceptTouchRunnable);
     }
 
     private MotionEvent newEvent(int actionDown, float x, float y) {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DevicePostureControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DevicePostureControllerTest.java
index 3323740..1472464 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DevicePostureControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DevicePostureControllerTest.java
@@ -22,7 +22,7 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.content.Context;
 
@@ -105,6 +105,6 @@
         int sameDevicePosture = mDevicePostureCaptor.getValue();
         mDevicePostureController.onDevicePostureChanged(sameDevicePosture);
 
-        verifyZeroInteractions(mOnDevicePostureChangedListener);
+        verifyNoMoreInteractions(mOnDevicePostureChangedListener);
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
index ee9d177..a53277a 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayImeControllerTest.java
@@ -32,7 +32,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.graphics.Insets;
 import android.graphics.Point;
@@ -108,26 +108,26 @@
     public void insetsControlChanged_schedulesNoWorkOnExecutor() {
         Looper.prepare();
         mPerDisplay.insetsControlChanged(insetsStateWithIme(false), insetsSourceControl());
-        verifyZeroInteractions(mExecutor);
+        verifyNoMoreInteractions(mExecutor);
     }
 
     @Test
     public void insetsChanged_schedulesNoWorkOnExecutor() {
         Looper.prepare();
         mPerDisplay.insetsChanged(insetsStateWithIme(false));
-        verifyZeroInteractions(mExecutor);
+        verifyNoMoreInteractions(mExecutor);
     }
 
     @Test
     public void showInsets_schedulesNoWorkOnExecutor() {
         mPerDisplay.showInsets(ime(), true /* fromIme */, ImeTracker.Token.empty());
-        verifyZeroInteractions(mExecutor);
+        verifyNoMoreInteractions(mExecutor);
     }
 
     @Test
     public void hideInsets_schedulesNoWorkOnExecutor() {
         mPerDisplay.hideInsets(ime(), true /* fromIme */, ImeTracker.Token.empty());
-        verifyZeroInteractions(mExecutor);
+        verifyNoMoreInteractions(mExecutor);
     }
 
     // With the refactor, the control's isInitiallyVisible is used to apply to the IME, therefore
@@ -135,7 +135,7 @@
     @Test
     @RequiresFlagsDisabled(android.view.inputmethod.Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
     public void reappliesVisibilityToChangedLeash() {
-        verifyZeroInteractions(mT);
+        verifyNoMoreInteractions(mT);
         mPerDisplay.mImeShowing = false;
 
         mPerDisplay.insetsControlChanged(insetsStateWithIme(false), insetsSourceControl());
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TabletopModeControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TabletopModeControllerTest.java
index 96d202c..7d18669 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TabletopModeControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/TabletopModeControllerTest.java
@@ -29,7 +29,7 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -145,7 +145,7 @@
         mConfiguration.windowConfiguration.setDisplayRotation(Surface.ROTATION_0);
         mPipTabletopController.onDisplayConfigurationChanged(DEFAULT_DISPLAY, mConfiguration);
 
-        verifyZeroInteractions(mOnTabletopModeChangedListener);
+        verifyNoMoreInteractions(mOnTabletopModeChangedListener);
     }
 
     // Test cases starting from folded state (DEVICE_POSTURE_CLOSED)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipAppOpsListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipAppOpsListenerTest.java
index e92e243..a2066db 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipAppOpsListenerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/pip/PipAppOpsListenerTest.java
@@ -21,7 +21,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.AppOpsManager;
@@ -157,7 +157,7 @@
         opChangedListener.onOpChanged(String.valueOf(AppOpsManager.OP_PICTURE_IN_PICTURE),
                 packageName);
 
-        verifyZeroInteractions(mMockExecutor);
+        verifyNoMoreInteractions(mMockExecutor);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt
index fa95fae..9c45cd2 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterbox/LetterboxInputControllerTest.kt
@@ -35,6 +35,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.any
+import org.mockito.kotlin.anyOrNull
 import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
@@ -191,6 +192,7 @@
         fun checkUpdateSessionRegion(times: Int = 1, displayId: Int = DISPLAY_ID, region: Region) {
             verify(windowSession, times(times)).updateInputChannel(
                 any(),
+                anyOrNull(),
                 eq(displayId),
                 any(),
                 any(),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt
index 450989d..96b826f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt
@@ -26,28 +26,37 @@
 import android.os.Handler
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
+import android.platform.test.annotations.UsesFlags
 import android.platform.test.flag.junit.FlagsParameterization
 import android.provider.Settings
 import android.provider.Settings.Global.DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS
+import android.view.Display
 import android.view.Display.DEFAULT_DISPLAY
 import android.view.IWindowManager
+import android.view.InputDevice
 import android.view.WindowManager.TRANSIT_CHANGE
 import android.window.DisplayAreaInfo
 import android.window.WindowContainerTransaction
 import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession
 import com.android.dx.mockito.inline.extended.ExtendedMockito.never
+import com.android.dx.mockito.inline.extended.StaticMockitoSession
+import com.android.server.display.feature.flags.Flags as DisplayFlags
 import com.android.window.flags.Flags
 import com.android.wm.shell.MockToken
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.desktopmode.desktopwallpaperactivity.DesktopWallpaperActivityTokenProvider
+import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.transition.Transitions
 import com.google.common.truth.Truth.assertThat
 import com.google.testing.junit.testparameterinjector.TestParameter
 import com.google.testing.junit.testparameterinjector.TestParameterInjector
 import com.google.testing.junit.testparameterinjector.TestParameterValuesProvider
+import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -60,6 +69,7 @@
 import org.mockito.kotlin.eq
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.whenever
+import org.mockito.quality.Strictness
 
 /**
  * Test class for [DesktopDisplayModeController]
@@ -68,6 +78,7 @@
  */
 @SmallTest
 @RunWith(TestParameterInjector::class)
+@UsesFlags(com.android.server.display.feature.flags.Flags::class)
 class DesktopDisplayModeControllerTest(
     @TestParameter(valuesProvider = FlagsParameterizationProvider::class)
     flags: FlagsParameterization
@@ -79,6 +90,7 @@
     private val desktopWallpaperActivityTokenProvider =
         mock<DesktopWallpaperActivityTokenProvider>()
     private val inputManager = mock<InputManager>()
+    private val displayController = mock<DisplayController>()
     private val mainHandler = mock<Handler>()
 
     private lateinit var controller: DesktopDisplayModeController
@@ -90,6 +102,14 @@
         TestRunningTaskInfoBuilder().setWindowingMode(WINDOWING_MODE_FULLSCREEN).build()
     private val defaultTDA = DisplayAreaInfo(MockToken().token(), DEFAULT_DISPLAY, 0)
     private val wallpaperToken = MockToken().token()
+    private val defaultDisplay = mock<Display>()
+    private val externalDisplay = mock<Display>()
+    private val mouseDevice = mock<InputDevice>()
+
+    private lateinit var extendedDisplaySettingsRestoreSession:
+        ExtendedDisplaySettingsRestoreSession
+
+    private lateinit var mockitoSession: StaticMockitoSession
 
     init {
         mSetFlagsRule.setFlagsParameterization(flags)
@@ -97,6 +117,13 @@
 
     @Before
     fun setUp() {
+        mockitoSession =
+            mockitoSession()
+                .strictness(Strictness.LENIENT)
+                .mockStatic(DesktopModeStatus::class.java)
+                .startMocking()
+        extendedDisplaySettingsRestoreSession =
+            ExtendedDisplaySettingsRestoreSession(context.contentResolver)
         whenever(transitions.startTransition(anyInt(), any(), isNull())).thenReturn(Binder())
         whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY))
             .thenReturn(defaultTDA)
@@ -109,42 +136,60 @@
                 shellTaskOrganizer,
                 desktopWallpaperActivityTokenProvider,
                 inputManager,
+                displayController,
                 mainHandler,
             )
         runningTasks.add(freeformTask)
         runningTasks.add(fullscreenTask)
         whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenReturn(ArrayList(runningTasks))
         whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(wallpaperToken)
+        whenever(displayController.getDisplay(DEFAULT_DISPLAY)).thenReturn(defaultDisplay)
+        whenever(displayController.getDisplay(EXTERNAL_DISPLAY_ID)).thenReturn(externalDisplay)
         setTabletModeStatus(SwitchState.UNKNOWN)
+        whenever(
+            DesktopModeStatus.isDesktopModeSupportedOnDisplay(
+                context,
+                defaultDisplay
+            )
+        ).thenReturn(true)
+        whenever(mouseDevice.supportsSource(InputDevice.SOURCE_MOUSE)).thenReturn(true)
+        whenever(inputManager.getInputDevice(EXTERNAL_DEVICE_ID)).thenReturn(mouseDevice)
+        setMouseConnected(false)
+    }
+
+    @After
+    fun tearDown() {
+        extendedDisplaySettingsRestoreSession.restore()
+        mockitoSession.finishMocking()
     }
 
     private fun testDisplayWindowingModeSwitchOnDisplayConnected(expectToSwitch: Boolean) {
         defaultTDA.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
         whenever(mockWindowManager.getWindowingMode(anyInt())).thenReturn(WINDOWING_MODE_FULLSCREEN)
-        ExtendedDisplaySettingsSession(context.contentResolver, 1).use {
-            connectExternalDisplay()
-            if (expectToSwitch) {
-                // Assumes [connectExternalDisplay] properly triggered the switching transition.
-                // Will verify the transition later along with [disconnectExternalDisplay].
-                defaultTDA.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM
-            }
-            disconnectExternalDisplay()
+        setExtendedMode(true)
 
-            if (expectToSwitch) {
-                val arg = argumentCaptor<WindowContainerTransaction>()
-                verify(transitions, times(2))
-                    .startTransition(eq(TRANSIT_CHANGE), arg.capture(), isNull())
-                assertThat(arg.firstValue.changes[defaultTDA.token.asBinder()]?.windowingMode)
-                    .isEqualTo(WINDOWING_MODE_FREEFORM)
-                assertThat(arg.firstValue.changes[wallpaperToken.asBinder()]?.windowingMode)
-                    .isEqualTo(WINDOWING_MODE_FULLSCREEN)
-                assertThat(arg.secondValue.changes[defaultTDA.token.asBinder()]?.windowingMode)
-                    .isEqualTo(WINDOWING_MODE_FULLSCREEN)
-                assertThat(arg.secondValue.changes[wallpaperToken.asBinder()]?.windowingMode)
-                    .isEqualTo(WINDOWING_MODE_FULLSCREEN)
-            } else {
-                verify(transitions, never()).startTransition(eq(TRANSIT_CHANGE), any(), isNull())
-            }
+        connectExternalDisplay()
+        if (expectToSwitch) {
+            // Assumes [connectExternalDisplay] properly triggered the switching transition.
+            // Will verify the transition later along with [disconnectExternalDisplay].
+            defaultTDA.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FREEFORM
+        }
+        disconnectExternalDisplay()
+
+        if (expectToSwitch) {
+            val arg = argumentCaptor<WindowContainerTransaction>()
+            verify(transitions, times(2))
+                .startTransition(eq(TRANSIT_CHANGE), arg.capture(), isNull())
+            assertThat(arg.firstValue.changes[defaultTDA.token.asBinder()]?.windowingMode)
+                .isEqualTo(WINDOWING_MODE_FREEFORM)
+            assertThat(arg.firstValue.changes[wallpaperToken.asBinder()]?.windowingMode)
+                .isEqualTo(WINDOWING_MODE_FULLSCREEN)
+            assertThat(arg.secondValue.changes[defaultTDA.token.asBinder()]?.windowingMode)
+                .isEqualTo(WINDOWING_MODE_FULLSCREEN)
+            assertThat(arg.secondValue.changes[wallpaperToken.asBinder()]?.windowingMode)
+                .isEqualTo(WINDOWING_MODE_FULLSCREEN)
+        } else {
+            verify(transitions, never()).startTransition(eq(TRANSIT_CHANGE), any(), isNull())
         }
     }
 
@@ -167,6 +212,7 @@
     fun testTargetWindowingMode_formfactorDisabled(
         @TestParameter param: ExternalDisplayBasedTargetModeTestCase,
         @TestParameter tabletModeStatus: SwitchState,
+        @TestParameter hasAnyMouseDevice: Boolean,
     ) {
         whenever(mockWindowManager.getWindowingMode(anyInt()))
             .thenReturn(param.defaultWindowingMode)
@@ -176,15 +222,17 @@
             disconnectExternalDisplay()
         }
         setTabletModeStatus(tabletModeStatus)
-
-        ExtendedDisplaySettingsSession(
-                context.contentResolver,
-                if (param.extendedDisplayEnabled) 1 else 0,
+        setMouseConnected(hasAnyMouseDevice)
+        setExtendedMode(param.extendedDisplayEnabled)
+        whenever(
+            DesktopModeStatus.isDesktopModeSupportedOnDisplay(
+                context,
+                defaultDisplay
             )
-            .use {
-                assertThat(controller.getTargetWindowingModeForDefaultDisplay())
-                    .isEqualTo(param.expectedWindowingMode)
-            }
+        ).thenReturn(param.isDefaultDisplayDesktopEligible)
+
+        assertThat(controller.getTargetWindowingModeForDefaultDisplay())
+            .isEqualTo(param.expectedWindowingMode)
     }
 
     @Test
@@ -199,15 +247,17 @@
             disconnectExternalDisplay()
         }
         setTabletModeStatus(param.tabletModeStatus)
-
-        ExtendedDisplaySettingsSession(
-                context.contentResolver,
-                if (param.extendedDisplayEnabled) 1 else 0,
+        setExtendedMode(param.extendedDisplayEnabled)
+        whenever(
+            DesktopModeStatus.isDesktopModeSupportedOnDisplay(
+                context,
+                defaultDisplay
             )
-            .use {
-                assertThat(controller.getTargetWindowingModeForDefaultDisplay())
-                    .isEqualTo(param.expectedWindowingMode)
-            }
+        ).thenReturn(param.isDefaultDisplayDesktopEligible)
+        setMouseConnected(param.hasAnyMouseDevice)
+
+        assertThat(controller.getTargetWindowingModeForDefaultDisplay())
+            .isEqualTo(param.expectedWindowingMode)
     }
 
     @Test
@@ -215,18 +265,16 @@
     fun displayWindowingModeSwitch_existingTasksOnConnected() {
         defaultTDA.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN
         whenever(mockWindowManager.getWindowingMode(anyInt())).thenReturn(WINDOWING_MODE_FULLSCREEN)
+        setExtendedMode(true)
 
-        ExtendedDisplaySettingsSession(context.contentResolver, 1).use {
-            connectExternalDisplay()
+        connectExternalDisplay()
 
-            val arg = argumentCaptor<WindowContainerTransaction>()
-            verify(transitions, times(1))
-                .startTransition(eq(TRANSIT_CHANGE), arg.capture(), isNull())
-            assertThat(arg.firstValue.changes[freeformTask.token.asBinder()]?.windowingMode)
-                .isEqualTo(WINDOWING_MODE_UNDEFINED)
-            assertThat(arg.firstValue.changes[fullscreenTask.token.asBinder()]?.windowingMode)
-                .isEqualTo(WINDOWING_MODE_FULLSCREEN)
-        }
+        val arg = argumentCaptor<WindowContainerTransaction>()
+        verify(transitions, times(1)).startTransition(eq(TRANSIT_CHANGE), arg.capture(), isNull())
+        assertThat(arg.firstValue.changes[freeformTask.token.asBinder()]?.windowingMode)
+            .isEqualTo(WINDOWING_MODE_UNDEFINED)
+        assertThat(arg.firstValue.changes[fullscreenTask.token.asBinder()]?.windowingMode)
+            .isEqualTo(WINDOWING_MODE_FULLSCREEN)
     }
 
     @Test
@@ -236,18 +284,16 @@
         whenever(mockWindowManager.getWindowingMode(anyInt())).thenAnswer {
             WINDOWING_MODE_FULLSCREEN
         }
+        setExtendedMode(true)
 
-        ExtendedDisplaySettingsSession(context.contentResolver, 1).use {
-            disconnectExternalDisplay()
+        disconnectExternalDisplay()
 
-            val arg = argumentCaptor<WindowContainerTransaction>()
-            verify(transitions, times(1))
-                .startTransition(eq(TRANSIT_CHANGE), arg.capture(), isNull())
-            assertThat(arg.firstValue.changes[freeformTask.token.asBinder()]?.windowingMode)
-                .isEqualTo(WINDOWING_MODE_FREEFORM)
-            assertThat(arg.firstValue.changes[fullscreenTask.token.asBinder()]?.windowingMode)
-                .isEqualTo(WINDOWING_MODE_UNDEFINED)
-        }
+        val arg = argumentCaptor<WindowContainerTransaction>()
+        verify(transitions, times(1)).startTransition(eq(TRANSIT_CHANGE), arg.capture(), isNull())
+        assertThat(arg.firstValue.changes[freeformTask.token.asBinder()]?.windowingMode)
+            .isEqualTo(WINDOWING_MODE_FREEFORM)
+        assertThat(arg.firstValue.changes[fullscreenTask.token.asBinder()]?.windowingMode)
+            .isEqualTo(WINDOWING_MODE_UNDEFINED)
     }
 
     private fun connectExternalDisplay() {
@@ -266,18 +312,35 @@
         whenever(inputManager.isInTabletMode()).thenReturn(status.value)
     }
 
-    private class ExtendedDisplaySettingsSession(
-        private val contentResolver: ContentResolver,
-        private val overrideValue: Int,
-    ) : AutoCloseable {
+    private fun setExtendedMode(enabled: Boolean) {
+        if (DisplayFlags.enableDisplayContentModeManagement()) {
+            whenever(
+                DesktopModeStatus.isDesktopModeSupportedOnDisplay(
+                    context,
+                    externalDisplay
+                )
+            ).thenReturn(enabled)
+        } else {
+            Settings.Global.putInt(
+                context.contentResolver,
+                DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS,
+                if (enabled) 1 else 0,
+            )
+        }
+    }
+
+    private fun setMouseConnected(connected: Boolean) {
+        whenever(inputManager.inputDeviceIds)
+            .thenReturn(if (connected) intArrayOf(EXTERNAL_DEVICE_ID) else intArrayOf())
+    }
+
+    private class ExtendedDisplaySettingsRestoreSession(
+        private val contentResolver: ContentResolver
+    ) {
         private val settingName = DEVELOPMENT_FORCE_DESKTOP_MODE_ON_EXTERNAL_DISPLAYS
         private val initialValue = Settings.Global.getInt(contentResolver, settingName, 0)
 
-        init {
-            Settings.Global.putInt(contentResolver, settingName, overrideValue)
-        }
-
-        override fun close() {
+        fun restore() {
             Settings.Global.putInt(contentResolver, settingName, initialValue)
         }
     }
@@ -287,13 +350,15 @@
             context: TestParameterValuesProvider.Context
         ): List<FlagsParameterization> {
             return FlagsParameterization.allCombinationsOf(
-                Flags.FLAG_FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH
+                Flags.FLAG_FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH,
+                DisplayFlags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT,
             )
         }
     }
 
     companion object {
         const val EXTERNAL_DISPLAY_ID = 100
+        const val EXTERNAL_DEVICE_ID = 10
 
         enum class SwitchState(val value: Int) {
             UNKNOWN(InputManager.SWITCH_STATE_UNKNOWN),
@@ -305,54 +370,119 @@
             val defaultWindowingMode: Int,
             val hasExternalDisplay: Boolean,
             val extendedDisplayEnabled: Boolean,
+            val isDefaultDisplayDesktopEligible: Boolean,
             val expectedWindowingMode: Int,
         ) {
-            FREEFORM_EXTERNAL_EXTENDED(
+            FREEFORM_EXTERNAL_EXTENDED_NO_PROJECTED(
                 defaultWindowingMode = WINDOWING_MODE_FREEFORM,
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = true,
+                isDefaultDisplayDesktopEligible = true,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            FULLSCREEN_EXTERNAL_EXTENDED(
+            FULLSCREEN_EXTERNAL_EXTENDED_NO_PROJECTED(
                 defaultWindowingMode = WINDOWING_MODE_FULLSCREEN,
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = true,
+                isDefaultDisplayDesktopEligible = true,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            FREEFORM_NO_EXTERNAL_EXTENDED(
+            FREEFORM_NO_EXTERNAL_EXTENDED_NO_PROJECTED(
                 defaultWindowingMode = WINDOWING_MODE_FREEFORM,
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = true,
+                isDefaultDisplayDesktopEligible = true,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            FULLSCREEN_NO_EXTERNAL_EXTENDED(
+            FULLSCREEN_NO_EXTERNAL_EXTENDED_NO_PROJECTED(
                 defaultWindowingMode = WINDOWING_MODE_FULLSCREEN,
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = true,
+                isDefaultDisplayDesktopEligible = true,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
-            FREEFORM_EXTERNAL_MIRROR(
+            FREEFORM_EXTERNAL_MIRROR_NO_PROJECTED(
                 defaultWindowingMode = WINDOWING_MODE_FREEFORM,
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = false,
+                isDefaultDisplayDesktopEligible = true,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            FULLSCREEN_EXTERNAL_MIRROR(
+            FULLSCREEN_EXTERNAL_MIRROR_NO_PROJECTED(
                 defaultWindowingMode = WINDOWING_MODE_FULLSCREEN,
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = false,
+                isDefaultDisplayDesktopEligible = true,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
-            FREEFORM_NO_EXTERNAL_MIRROR(
+            FREEFORM_NO_EXTERNAL_MIRROR_NO_PROJECTED(
                 defaultWindowingMode = WINDOWING_MODE_FREEFORM,
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = false,
+                isDefaultDisplayDesktopEligible = true,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            FULLSCREEN_NO_EXTERNAL_MIRROR(
+            FULLSCREEN_NO_EXTERNAL_MIRROR_NO_PROJECTED(
                 defaultWindowingMode = WINDOWING_MODE_FULLSCREEN,
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = false,
+                isDefaultDisplayDesktopEligible = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            FREEFORM_EXTERNAL_EXTENDED_PROJECTED(
+                defaultWindowingMode = WINDOWING_MODE_FREEFORM,
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                isDefaultDisplayDesktopEligible = false,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            FULLSCREEN_EXTERNAL_EXTENDED_PROJECTED(
+                defaultWindowingMode = WINDOWING_MODE_FULLSCREEN,
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                isDefaultDisplayDesktopEligible = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            FREEFORM_NO_EXTERNAL_EXTENDED_PROJECTED(
+                defaultWindowingMode = WINDOWING_MODE_FREEFORM,
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                isDefaultDisplayDesktopEligible = false,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            FULLSCREEN_NO_EXTERNAL_EXTENDED_PROJECTED(
+                defaultWindowingMode = WINDOWING_MODE_FULLSCREEN,
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                isDefaultDisplayDesktopEligible = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            FREEFORM_EXTERNAL_MIRROR_PROJECTED(
+                defaultWindowingMode = WINDOWING_MODE_FREEFORM,
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                isDefaultDisplayDesktopEligible = false,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            FULLSCREEN_EXTERNAL_MIRROR_PROJECTED(
+                defaultWindowingMode = WINDOWING_MODE_FULLSCREEN,
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                isDefaultDisplayDesktopEligible = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            FREEFORM_NO_EXTERNAL_MIRROR_PROJECTED(
+                defaultWindowingMode = WINDOWING_MODE_FREEFORM,
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                isDefaultDisplayDesktopEligible = false,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            FULLSCREEN_NO_EXTERNAL_MIRROR_PROJECTED(
+                defaultWindowingMode = WINDOWING_MODE_FULLSCREEN,
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                isDefaultDisplayDesktopEligible = false,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
         }
@@ -361,78 +491,392 @@
             val hasExternalDisplay: Boolean,
             val extendedDisplayEnabled: Boolean,
             val tabletModeStatus: SwitchState,
+            val isDefaultDisplayDesktopEligible: Boolean,
+            val hasAnyMouseDevice: Boolean,
             val expectedWindowingMode: Int,
         ) {
-            EXTERNAL_EXTENDED_TABLET(
+            EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = true,
                 tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            NO_EXTERNAL_EXTENDED_TABLET(
+            NO_EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = true,
                 tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
-            EXTERNAL_MIRROR_TABLET(
+            EXTERNAL_MIRROR_TABLET_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = false,
                 tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
-            NO_EXTERNAL_MIRROR_TABLET(
+            NO_EXTERNAL_MIRROR_TABLET_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = false,
                 tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
-            EXTERNAL_EXTENDED_CLAMSHELL(
+            EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = true,
                 tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            NO_EXTERNAL_EXTENDED_CLAMSHELL(
+            NO_EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = true,
                 tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            EXTERNAL_MIRROR_CLAMSHELL(
+            EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = false,
                 tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            NO_EXTERNAL_MIRROR_CLAMSHELL(
+            NO_EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = false,
                 tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            EXTERNAL_EXTENDED_UNKNOWN(
+            EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = true,
                 tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FREEFORM,
             ),
-            NO_EXTERNAL_EXTENDED_UNKNOWN(
+            NO_EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = true,
                 tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
-            EXTERNAL_MIRROR_UNKNOWN(
+            EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = true,
                 extendedDisplayEnabled = false,
                 tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
-            NO_EXTERNAL_MIRROR_UNKNOWN(
+            NO_EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_NO_MOUSE(
                 hasExternalDisplay = false,
                 extendedDisplayEnabled = false,
                 tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_EXTENDED_TABLET_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_EXTENDED_TABLET_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_MIRROR_TABLET_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_MIRROR_TABLET_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_MIRROR_UNKNOWN_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_MIRROR_UNKNOWN_PROJECTED_NO_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = false,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            NO_EXTERNAL_EXTENDED_TABLET_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            EXTERNAL_MIRROR_TABLET_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            NO_EXTERNAL_MIRROR_TABLET_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            NO_EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            NO_EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            NO_EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            NO_EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = true,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FREEFORM,
+            ),
+            EXTERNAL_EXTENDED_TABLET_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_EXTENDED_TABLET_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_MIRROR_TABLET_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_MIRROR_TABLET_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.ON,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_MIRROR_CLAMSHELL_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.OFF,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_EXTENDED_UNKNOWN_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = true,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            EXTERNAL_MIRROR_UNKNOWN_PROJECTED_MOUSE(
+                hasExternalDisplay = true,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
+                expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
+            ),
+            NO_EXTERNAL_MIRROR_UNKNOWN_PROJECTED_MOUSE(
+                hasExternalDisplay = false,
+                extendedDisplayEnabled = false,
+                tabletModeStatus = SwitchState.UNKNOWN,
+                isDefaultDisplayDesktopEligible = false,
+                hasAnyMouseDevice = true,
                 expectedWindowingMode = WINDOWING_MODE_FULLSCREEN,
             ),
         }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
index 8a5acfa..695cf60 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeEventLoggerTest.kt
@@ -23,7 +23,7 @@
 import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
 import com.android.dx.mockito.inline.extended.ExtendedMockito.staticMockMarker
 import com.android.dx.mockito.inline.extended.ExtendedMockito.verify
-import com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions
+import com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions
 import com.android.internal.util.FrameworkStatsLog
 import com.android.modules.utils.testing.ExtendedMockitoRule
 import com.android.window.flags.Flags
@@ -102,7 +102,7 @@
                 eq(sessionId),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -127,7 +127,7 @@
                 eq(sessionId),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -135,7 +135,7 @@
         desktopModeEventLogger.logSessionExit(ExitReason.DRAG_TO_EXIT)
 
         verifyNoLogging()
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -157,7 +157,7 @@
                 eq(sessionId),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
         assertThat(desktopModeEventLogger.currentSessionId.get()).isEqualTo(NO_SESSION_ID)
     }
 
@@ -166,7 +166,7 @@
         desktopModeEventLogger.logTaskAdded(TASK_UPDATE)
 
         verifyNoLogging()
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -205,7 +205,7 @@
                 eq(UNSET_FOCUS_REASON),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -213,7 +213,7 @@
         desktopModeEventLogger.logTaskRemoved(TASK_UPDATE)
 
         verifyNoLogging()
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -252,7 +252,7 @@
                 eq(UNSET_FOCUS_REASON),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -260,7 +260,7 @@
         desktopModeEventLogger.logTaskInfoChanged(TASK_UPDATE)
 
         verifyNoLogging()
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -302,7 +302,7 @@
                 eq(UNSET_FOCUS_REASON),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -346,7 +346,7 @@
                 eq(UNSET_FOCUS_REASON),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -390,7 +390,7 @@
                 eq(UNSET_FOCUS_REASON),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -434,7 +434,7 @@
                 eq(FocusReason.UNKNOWN.reason),
             )
         }
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -446,7 +446,7 @@
         )
 
         verifyNoLogging()
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
@@ -485,7 +485,7 @@
         )
 
         verifyNoLogging()
-        verifyZeroInteractions(staticMockMarker(EventLogTags::class.java))
+        verifyNoMoreInteractions(staticMockMarker(EventLogTags::class.java))
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
index b7d25b5..bd37610 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserverTest.kt
@@ -83,7 +83,7 @@
 import org.mockito.kotlin.spy
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
-import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.verifyNoMoreInteractions
 import org.mockito.kotlin.whenever
 
 /**
@@ -596,7 +596,7 @@
             .logTaskRemoved(
                 eq(DEFAULT_TASK_UPDATE.copy(minimizeReason = MinimizeReason.MINIMIZE_BUTTON))
             )
-        verifyZeroInteractions(desktopModeEventLogger)
+        verifyNoMoreInteractions(desktopModeEventLogger)
     }
 
     @Test
@@ -668,7 +668,7 @@
             .logTaskInfoChanged(
                 eq(DEFAULT_TASK_UPDATE.copy(taskX = DEFAULT_TASK_X + 100, visibleTaskCount = 1))
             )
-        verifyZeroInteractions(desktopModeEventLogger)
+        verifyNoMoreInteractions(desktopModeEventLogger)
     }
 
     @Test
@@ -701,7 +701,7 @@
                     )
                 )
             )
-        verifyZeroInteractions(desktopModeEventLogger)
+        verifyNoMoreInteractions(desktopModeEventLogger)
     }
 
     @Test
@@ -729,7 +729,7 @@
                     )
                 )
             )
-        verifyZeroInteractions(desktopModeEventLogger)
+        verifyNoMoreInteractions(desktopModeEventLogger)
     }
 
     @Test
@@ -753,7 +753,7 @@
             .logTaskInfoChanged(
                 eq(DEFAULT_TASK_UPDATE.copy(taskX = DEFAULT_TASK_X + 100, visibleTaskCount = 2))
             )
-        verifyZeroInteractions(desktopModeEventLogger)
+        verifyNoMoreInteractions(desktopModeEventLogger)
 
         // task 2 resize
         val newTaskInfo2 =
@@ -781,7 +781,7 @@
                     )
                 )
             )
-        verifyZeroInteractions(desktopModeEventLogger)
+        verifyNoMoreInteractions(desktopModeEventLogger)
     }
 
     @Test
@@ -892,14 +892,14 @@
                 eq(taskUpdate.visibleTaskCount.toString()),
             )
         }
-        verifyZeroInteractions(desktopModeEventLogger)
+        verifyNoMoreInteractions(desktopModeEventLogger)
     }
 
     private fun verifyTaskRemovedAndExitLogging(exitReason: ExitReason, taskUpdate: TaskUpdate) {
         assertFalse(transitionObserver.isSessionActive)
         verify(desktopModeEventLogger, times(1)).logTaskRemoved(eq(taskUpdate))
         verify(desktopModeEventLogger, times(1)).logSessionExit(eq(exitReason))
-        verifyZeroInteractions(desktopModeEventLogger)
+        verifyNoMoreInteractions(desktopModeEventLogger)
     }
 
     private companion object {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt
index 6a99d47..a7ea66e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeMoveToDisplayTransitionHandlerTest.kt
@@ -43,7 +43,8 @@
 
     @Before
     fun setUp() {
-        handler = DesktopModeMoveToDisplayTransitionHandler(StubTransaction())
+        handler =
+            DesktopModeMoveToDisplayTransitionHandler(StubTransaction(), mock(), mock(), mock())
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
index b859a00..652fae0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopModeVisualIndicatorTest.kt
@@ -36,6 +36,7 @@
 import com.android.wm.shell.common.DisplayController
 import com.android.wm.shell.common.DisplayLayout
 import com.android.wm.shell.common.SyncTransactionQueue
+import com.android.wm.shell.shared.R as sharedR
 import com.android.wm.shell.shared.bubbles.BubbleDropTargetBoundsProvider
 import com.android.wm.shell.windowdecor.tiling.SnapEventHandler
 import com.google.common.truth.Truth.assertThat
@@ -78,9 +79,7 @@
 
     @Before
     fun setUp() {
-        whenever(displayLayout.width()).thenReturn(DISPLAY_BOUNDS.width())
-        whenever(displayLayout.height()).thenReturn(DISPLAY_BOUNDS.height())
-        whenever(displayLayout.stableInsets()).thenReturn(STABLE_INSETS)
+        setUpDisplayBoundsTablet()
         whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
         whenever(displayController.getDisplay(anyInt())).thenReturn(mContext.display)
         whenever(bubbleBoundsProvider.getBubbleBarExpandedViewDropTargetBounds(any()))
@@ -97,12 +96,36 @@
         )
     }
 
+    private fun setUpDisplayBoundsTablet() {
+        whenever(displayLayout.width()).thenReturn(TABLET_DISPLAY_BOUNDS.width())
+        whenever(displayLayout.height()).thenReturn(TABLET_DISPLAY_BOUNDS.height())
+        whenever(displayLayout.stableInsets()).thenReturn(TABLET_STABLE_INSETS)
+    }
+
+    private fun setUpDisplayBoundsFoldable() {
+        whenever(displayLayout.width()).thenReturn(FOLDABLE_DISPLAY_BOUNDS.width())
+        whenever(displayLayout.height()).thenReturn(FOLDABLE_DISPLAY_BOUNDS.height())
+        whenever(displayLayout.stableInsets()).thenReturn(FOLDABLE_STABLE_INSETS)
+    }
+
+    private fun disableDesktop() {
+        mContext.orCreateTestableResources.addOverride(
+            com.android.internal.R.bool.config_canInternalDisplayHostDesktops,
+            false,
+        )
+    }
+
+    private fun setUpFoldable() {
+        setUpDisplayBoundsFoldable()
+        disableDesktop()
+    }
+
     @Test
     fun testFullscreenRegionCalculation() {
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
         var testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT)
         assertThat(testRegion.bounds)
-            .isEqualTo(Rect(0, Short.MIN_VALUE.toInt(), 2400, 2 * STABLE_INSETS.top))
+            .isEqualTo(Rect(0, Short.MIN_VALUE.toInt(), 2400, 2 * TABLET_STABLE_INSETS.top))
 
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM)
         testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT)
@@ -113,9 +136,9 @@
         assertThat(testRegion.bounds)
             .isEqualTo(
                 Rect(
-                    (DISPLAY_BOUNDS.width() / 2f - toFullscreenWidth / 2f).toInt(),
+                    (TABLET_DISPLAY_BOUNDS.width() / 2f - toFullscreenWidth / 2f).toInt(),
                     Short.MIN_VALUE.toInt(),
-                    (DISPLAY_BOUNDS.width() / 2f + toFullscreenWidth / 2f).toInt(),
+                    (TABLET_DISPLAY_BOUNDS.width() / 2f + toFullscreenWidth / 2f).toInt(),
                     transitionHeight,
                 )
             )
@@ -123,7 +146,7 @@
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
         testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT)
         assertThat(testRegion.bounds)
-            .isEqualTo(Rect(0, Short.MIN_VALUE.toInt(), 2400, 2 * STABLE_INSETS.top))
+            .isEqualTo(Rect(0, Short.MIN_VALUE.toInt(), 2400, 2 * TABLET_STABLE_INSETS.top))
 
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
         testRegion = visualIndicator.calculateFullscreenRegion(displayLayout, CAPTION_HEIGHT)
@@ -142,7 +165,7 @@
                 TRANSITION_AREA_WIDTH,
                 CAPTION_HEIGHT,
             )
-        assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600))
+        assertThat(testRegion).isEqualTo(Rect(0, -50, 32, 1600))
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM)
         testRegion =
             visualIndicator.calculateSplitLeftRegion(
@@ -150,7 +173,7 @@
                 TRANSITION_AREA_WIDTH,
                 CAPTION_HEIGHT,
             )
-        assertThat(testRegion.bounds).isEqualTo(Rect(0, transitionHeight, 32, 1600))
+        assertThat(testRegion).isEqualTo(Rect(0, transitionHeight, 32, 1600))
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
         testRegion =
             visualIndicator.calculateSplitLeftRegion(
@@ -158,7 +181,7 @@
                 TRANSITION_AREA_WIDTH,
                 CAPTION_HEIGHT,
             )
-        assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600))
+        assertThat(testRegion).isEqualTo(Rect(0, -50, 32, 1600))
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
         testRegion =
             visualIndicator.calculateSplitLeftRegion(
@@ -166,7 +189,7 @@
                 TRANSITION_AREA_WIDTH,
                 CAPTION_HEIGHT,
             )
-        assertThat(testRegion.bounds).isEqualTo(Rect(0, -50, 32, 1600))
+        assertThat(testRegion).isEqualTo(Rect(0, -50, 32, 1600))
     }
 
     @Test
@@ -180,7 +203,7 @@
                 TRANSITION_AREA_WIDTH,
                 CAPTION_HEIGHT,
             )
-        assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600))
+        assertThat(testRegion).isEqualTo(Rect(2368, -50, 2400, 1600))
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FREEFORM)
         testRegion =
             visualIndicator.calculateSplitRightRegion(
@@ -188,7 +211,7 @@
                 TRANSITION_AREA_WIDTH,
                 CAPTION_HEIGHT,
             )
-        assertThat(testRegion.bounds).isEqualTo(Rect(2368, transitionHeight, 2400, 1600))
+        assertThat(testRegion).isEqualTo(Rect(2368, transitionHeight, 2400, 1600))
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
         testRegion =
             visualIndicator.calculateSplitRightRegion(
@@ -196,7 +219,7 @@
                 TRANSITION_AREA_WIDTH,
                 CAPTION_HEIGHT,
             )
-        assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600))
+        assertThat(testRegion).isEqualTo(Rect(2368, -50, 2400, 1600))
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
         testRegion =
             visualIndicator.calculateSplitRightRegion(
@@ -204,41 +227,37 @@
                 TRANSITION_AREA_WIDTH,
                 CAPTION_HEIGHT,
             )
-        assertThat(testRegion.bounds).isEqualTo(Rect(2368, -50, 2400, 1600))
+        assertThat(testRegion).isEqualTo(Rect(2368, -50, 2400, 1600))
     }
 
     @Test
     fun testBubbleLeftRegionCalculation() {
-        val bubbleRegionWidth =
-            context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_width)
-        val bubbleRegionHeight =
-            context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_height)
-        val expectedRect = Rect(0, 1600 - bubbleRegionHeight, bubbleRegionWidth, 1600)
+        val bubbleRegionSize =
+            context.resources.getDimensionPixelSize(sharedR.dimen.drag_zone_bubble_tablet)
+        val expectedRect = Rect(0, 1600 - bubbleRegionSize, bubbleRegionSize, 1600)
 
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
         var testRegion = visualIndicator.calculateBubbleLeftRegion(displayLayout)
-        assertThat(testRegion.bounds).isEqualTo(expectedRect)
+        assertThat(testRegion).isEqualTo(expectedRect)
 
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
         testRegion = visualIndicator.calculateBubbleLeftRegion(displayLayout)
-        assertThat(testRegion.bounds).isEqualTo(expectedRect)
+        assertThat(testRegion).isEqualTo(expectedRect)
     }
 
     @Test
     fun testBubbleRightRegionCalculation() {
-        val bubbleRegionWidth =
-            context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_width)
-        val bubbleRegionHeight =
-            context.resources.getDimensionPixelSize(R.dimen.bubble_transform_area_height)
-        val expectedRect = Rect(2400 - bubbleRegionWidth, 1600 - bubbleRegionHeight, 2400, 1600)
+        val bubbleRegionSize =
+            context.resources.getDimensionPixelSize(sharedR.dimen.drag_zone_bubble_tablet)
+        val expectedRect = Rect(2400 - bubbleRegionSize, 1600 - bubbleRegionSize, 2400, 1600)
 
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
         var testRegion = visualIndicator.calculateBubbleRightRegion(displayLayout)
-        assertThat(testRegion.bounds).isEqualTo(expectedRect)
+        assertThat(testRegion).isEqualTo(expectedRect)
 
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
         testRegion = visualIndicator.calculateBubbleRightRegion(displayLayout)
-        assertThat(testRegion.bounds).isEqualTo(expectedRect)
+        assertThat(testRegion).isEqualTo(expectedRect)
     }
 
     @Test
@@ -264,47 +283,107 @@
         com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
         com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
     )
-    fun testDefaultIndicatorWithNoDesktop() {
-        mContext.orCreateTestableResources.addOverride(
-            com.android.internal.R.bool.config_canInternalDisplayHostDesktops,
-            false,
-        )
-        // Fullscreen to center, no desktop indicator
+    fun testDefaultIndicators_bubblesEnabled() {
         createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN)
-        var result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
-        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
-        // Fullscreen to split
-        result = visualIndicator.updateIndicatorType(PointF(10000f, 500f))
-        assertThat(result)
-            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR)
-        result = visualIndicator.updateIndicatorType(PointF(-10000f, 500f))
-        assertThat(result)
-            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR)
-        // Fullscreen to bubble
-        result = visualIndicator.updateIndicatorType(PointF(100f, 1500f))
+        var result = visualIndicator.updateIndicatorType(PointF(10f, 1500f))
         assertThat(result)
             .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR)
         result = visualIndicator.updateIndicatorType(PointF(2300f, 1500f))
         assertThat(result)
             .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR)
-        // Split to center, no desktop indicator
-        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.FROM_SPLIT)
-        result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
-        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
-        // Split to fullscreen
-        result = visualIndicator.updateIndicatorType(PointF(500f, 0f))
+    }
+
+    @Test
+    @EnableFlags(
+        com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+        com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+    )
+    fun testDefaultIndicators_foldable_leftRightSplit() {
+        setUpFoldable()
+
+        createVisualIndicator(
+            DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN,
+            isSmallTablet = true,
+            isLeftRightSplit = true,
+        )
+        var result = visualIndicator.updateIndicatorType(foldCenter())
         assertThat(result)
             .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
-        // Split to bubble
-        result = visualIndicator.updateIndicatorType(PointF(100f, 1500f))
+
+        result = visualIndicator.updateIndicatorType(foldLeftEdge())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_LEFT_INDICATOR)
+
+        result = visualIndicator.updateIndicatorType(foldRightEdge())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_SPLIT_RIGHT_INDICATOR)
+
+        result = visualIndicator.updateIndicatorType(foldLeftBottom())
         assertThat(result)
             .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR)
-        result = visualIndicator.updateIndicatorType(PointF(2300f, 1500f))
+
+        result = visualIndicator.updateIndicatorType(foldRightBottom())
         assertThat(result)
             .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR)
-        // Drag app to center, no desktop indicator
-        createVisualIndicator(DesktopModeVisualIndicator.DragStartState.DRAGGED_INTENT)
-        result = visualIndicator.updateIndicatorType(PointF(500f, 500f))
+
+        createVisualIndicator(
+            DesktopModeVisualIndicator.DragStartState.FROM_SPLIT,
+            isSmallTablet = true,
+            isLeftRightSplit = true,
+        )
+        result = visualIndicator.updateIndicatorType(foldCenter())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
+
+        result = visualIndicator.updateIndicatorType(foldLeftBottom())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR)
+
+        result = visualIndicator.updateIndicatorType(foldRightBottom())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR)
+    }
+
+    @Test
+    @EnableFlags(
+        com.android.wm.shell.Flags.FLAG_ENABLE_BUBBLE_TO_FULLSCREEN,
+        com.android.wm.shell.Flags.FLAG_ENABLE_CREATE_ANY_BUBBLE,
+    )
+    fun testDefaultIndicators_foldable_topBottomSplit() {
+        setUpFoldable()
+
+        createVisualIndicator(
+            DesktopModeVisualIndicator.DragStartState.FROM_FULLSCREEN,
+            isSmallTablet = true,
+            isLeftRightSplit = false,
+        )
+        var result = visualIndicator.updateIndicatorType(foldCenter())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
+
+        result = visualIndicator.updateIndicatorType(foldLeftEdge())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR)
+
+        result = visualIndicator.updateIndicatorType(foldLeftBottom())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_LEFT_INDICATOR)
+
+        result = visualIndicator.updateIndicatorType(foldRightBottom())
+        assertThat(result)
+            .isEqualTo(DesktopModeVisualIndicator.IndicatorType.TO_BUBBLE_RIGHT_INDICATOR)
+
+        createVisualIndicator(
+            DesktopModeVisualIndicator.DragStartState.FROM_SPLIT,
+            isSmallTablet = true,
+            isLeftRightSplit = false,
+        )
+        // No indicator as top/bottom split apps should not be dragged
+        result = visualIndicator.updateIndicatorType(foldCenter())
+        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
+        result = visualIndicator.updateIndicatorType(foldLeftBottom())
+        assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
+        result = visualIndicator.updateIndicatorType(foldRightBottom())
         assertThat(result).isEqualTo(DesktopModeVisualIndicator.IndicatorType.NO_INDICATOR)
     }
 
@@ -382,7 +461,11 @@
         verify(taskDisplayAreaOrganizer, never()).attachToDisplayArea(anyInt(), any())
     }
 
-    private fun createVisualIndicator(dragStartState: DesktopModeVisualIndicator.DragStartState) {
+    private fun createVisualIndicator(
+        dragStartState: DesktopModeVisualIndicator.DragStartState,
+        isSmallTablet: Boolean = false,
+        isLeftRightSplit: Boolean = true,
+    ) {
         visualIndicator =
             DesktopModeVisualIndicator(
                 desktopExecutor,
@@ -396,20 +479,53 @@
                 dragStartState,
                 bubbleBoundsProvider,
                 snapEventHandler,
+                isSmallTablet,
+                isLeftRightSplit,
             )
     }
 
+    private fun foldCenter(): PointF {
+        return PointF(
+            FOLDABLE_DISPLAY_BOUNDS.centerX().toFloat(),
+            FOLDABLE_DISPLAY_BOUNDS.centerY().toFloat(),
+        )
+    }
+
+    private fun foldLeftEdge(): PointF {
+        return PointF(0f, 50f)
+    }
+
+    private fun foldRightEdge(): PointF {
+        return PointF(750f, 50f)
+    }
+
+    private fun foldLeftBottom(): PointF {
+        return PointF(0f, 650f)
+    }
+
+    private fun foldRightBottom(): PointF {
+        return PointF(750f, 650f)
+    }
+
     companion object {
         private const val TRANSITION_AREA_WIDTH = 32
         private const val CAPTION_HEIGHT = 50
-        private val DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
         private const val NAVBAR_HEIGHT = 50
-        private val STABLE_INSETS =
+        private val TABLET_DISPLAY_BOUNDS = Rect(0, 0, 2400, 1600)
+        private val TABLET_STABLE_INSETS =
             Rect(
-                DISPLAY_BOUNDS.left,
-                DISPLAY_BOUNDS.top + CAPTION_HEIGHT,
-                DISPLAY_BOUNDS.right,
-                DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
+                TABLET_DISPLAY_BOUNDS.left,
+                TABLET_DISPLAY_BOUNDS.top + CAPTION_HEIGHT,
+                TABLET_DISPLAY_BOUNDS.right,
+                TABLET_DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
+            )
+        private val FOLDABLE_DISPLAY_BOUNDS = Rect(0, 0, 800, 700)
+        private val FOLDABLE_STABLE_INSETS =
+            Rect(
+                FOLDABLE_DISPLAY_BOUNDS.left,
+                FOLDABLE_DISPLAY_BOUNDS.top + CAPTION_HEIGHT,
+                FOLDABLE_DISPLAY_BOUNDS.right,
+                FOLDABLE_DISPLAY_BOUNDS.bottom - NAVBAR_HEIGHT,
             )
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt
new file mode 100644
index 0000000..ef394d8
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopPipTransitionObserverTest.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.desktopmode
+
+import android.app.WindowConfiguration.WINDOWING_MODE_PINNED
+import android.os.Binder
+import android.platform.test.annotations.EnableFlags
+import android.platform.test.flag.junit.SetFlagsRule
+import android.testing.AndroidTestingRunner
+import android.view.WindowManager.TRANSIT_PIP
+import android.window.TransitionInfo
+import androidx.test.filters.SmallTest
+import com.android.window.flags.Flags
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.TestRunningTaskInfoBuilder
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.mock
+
+/**
+ * Tests for [DesktopPipTransitionObserver].
+ *
+ * Build/Install/Run: atest WMShellUnitTests:DesktopPipTransitionObserverTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class DesktopPipTransitionObserverTest : ShellTestCase() {
+
+    @JvmField @Rule val setFlagsRule = SetFlagsRule()
+
+    private lateinit var observer: DesktopPipTransitionObserver
+
+    private val transition = Binder()
+    private var onSuccessInvokedCount = 0
+
+    @Before
+    fun setUp() {
+        observer = DesktopPipTransitionObserver()
+
+        onSuccessInvokedCount = 0
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+    fun onTransitionReady_taskInPinnedWindowingMode_onSuccessInvoked() {
+        val taskId = 1
+        val pipTransition = createPendingPipTransition(taskId)
+        val successfulChange = createChange(taskId, WINDOWING_MODE_PINNED)
+        observer.addPendingPipTransition(pipTransition)
+
+        observer.onTransitionReady(
+            transition = transition,
+            info = TransitionInfo(
+                TRANSIT_PIP, /* flags= */
+                0
+            ).apply { addChange(successfulChange) },
+        )
+
+        assertThat(onSuccessInvokedCount).isEqualTo(1)
+    }
+
+    private fun createPendingPipTransition(
+        taskId: Int
+    ): DesktopPipTransitionObserver.PendingPipTransition {
+        return DesktopPipTransitionObserver.PendingPipTransition(
+            token = transition,
+            taskId = taskId,
+            onSuccess = { onSuccessInvokedCount += 1 },
+        )
+    }
+
+    private fun createChange(taskId: Int, windowingMode: Int): TransitionInfo.Change {
+        return TransitionInfo.Change(mock(), mock()).apply {
+            taskInfo =
+                TestRunningTaskInfoBuilder()
+                    .setTaskId(taskId)
+                    .setWindowingMode(windowingMode)
+                    .build()
+        }
+    }
+}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
index c455205..3fb0083 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopRepositoryTest.kt
@@ -58,6 +58,7 @@
 import org.mockito.kotlin.any
 import org.mockito.kotlin.clearInvocations
 import org.mockito.kotlin.eq
+import org.mockito.kotlin.isNull
 import org.mockito.kotlin.never
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
@@ -331,6 +332,8 @@
                         visibleTasks = ArraySet(arrayOf(1)),
                         minimizedTasks = ArraySet(),
                         freeformTasksInZOrder = arrayListOf(),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
                 verify(persistentRepository)
                     .addOrUpdateDesktop(
@@ -339,6 +342,8 @@
                         visibleTasks = ArraySet(arrayOf(1, 2)),
                         minimizedTasks = ArraySet(),
                         freeformTasksInZOrder = arrayListOf(),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
             }
         }
@@ -358,6 +363,52 @@
     }
 
     @Test
+    @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE)
+    fun leftTiledTask_updatedInRepoAndPersisted() {
+        runTest(StandardTestDispatcher()) {
+            repo.addLeftTiledTask(displayId = DEFAULT_DISPLAY, taskId = 1)
+
+            assertThat(repo.getLeftTiledTask(displayId = DEFAULT_DISPLAY)).isEqualTo(1)
+            verify(persistentRepository)
+                .addOrUpdateDesktop(
+                    DEFAULT_USER_ID,
+                    DEFAULT_DESKTOP_ID,
+                    visibleTasks = ArraySet(),
+                    minimizedTasks = ArraySet(),
+                    freeformTasksInZOrder = arrayListOf(),
+                    leftTiledTask = 1,
+                    rightTiledTask = null,
+                )
+
+            repo.removeRightTiledTask(displayId = DEFAULT_DISPLAY)
+            assertThat(repo.getRightTiledTask(displayId = DEFAULT_DISPLAY)).isNull()
+        }
+    }
+
+    @Test
+    @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE)
+    fun rightTiledTask_updatedInRepoAndPersisted() {
+        runTest(StandardTestDispatcher()) {
+            repo.addRightTiledTask(displayId = DEFAULT_DISPLAY, taskId = 1)
+
+            assertThat(repo.getRightTiledTask(displayId = DEFAULT_DISPLAY)).isEqualTo(1)
+            verify(persistentRepository)
+                .addOrUpdateDesktop(
+                    DEFAULT_USER_ID,
+                    DEFAULT_DESKTOP_ID,
+                    visibleTasks = ArraySet(),
+                    minimizedTasks = ArraySet(),
+                    freeformTasksInZOrder = arrayListOf(),
+                    leftTiledTask = null,
+                    rightTiledTask = 1,
+                )
+
+            repo.removeLeftTiledTask(displayId = DEFAULT_DISPLAY)
+            assertThat(repo.getLeftTiledTask(displayId = DEFAULT_DISPLAY)).isNull()
+        }
+    }
+
+    @Test
     fun isOnlyVisibleNonClosingTask_singleVisibleMinimizedTask() {
         val taskId = 1
         repo.addTask(DEFAULT_DISPLAY, taskId, isVisible = true)
@@ -663,6 +714,8 @@
                         visibleTasks = ArraySet(),
                         minimizedTasks = ArraySet(),
                         freeformTasksInZOrder = arrayListOf(5),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
                 verify(persistentRepository)
                     .addOrUpdateDesktop(
@@ -671,6 +724,8 @@
                         visibleTasks = ArraySet(arrayOf(5)),
                         minimizedTasks = ArraySet(),
                         freeformTasksInZOrder = arrayListOf(6, 5),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
                 verify(persistentRepository)
                     .addOrUpdateDesktop(
@@ -679,6 +734,8 @@
                         visibleTasks = ArraySet(arrayOf(5, 6)),
                         minimizedTasks = ArraySet(),
                         freeformTasksInZOrder = arrayListOf(7, 6, 5),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
             }
         }
@@ -729,6 +786,8 @@
                         visibleTasks = ArraySet(),
                         minimizedTasks = ArraySet(),
                         freeformTasksInZOrder = arrayListOf(5),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
                 verify(persistentRepository)
                     .addOrUpdateDesktop(
@@ -737,6 +796,8 @@
                         visibleTasks = ArraySet(arrayOf(5)),
                         minimizedTasks = ArraySet(),
                         freeformTasksInZOrder = arrayListOf(6, 5),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
                 verify(persistentRepository)
                     .addOrUpdateDesktop(
@@ -745,6 +806,8 @@
                         visibleTasks = ArraySet(arrayOf(5, 6)),
                         minimizedTasks = ArraySet(),
                         freeformTasksInZOrder = arrayListOf(7, 6, 5),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
                 verify(persistentRepository, times(2))
                     .addOrUpdateDesktop(
@@ -753,6 +816,8 @@
                         visibleTasks = ArraySet(arrayOf(5, 7)),
                         minimizedTasks = ArraySet(arrayOf(6)),
                         freeformTasksInZOrder = arrayListOf(7, 6, 5),
+                        leftTiledTask = null,
+                        rightTiledTask = null,
                     )
             }
         }
@@ -793,6 +858,8 @@
                     visibleTasks = ArraySet(),
                     minimizedTasks = ArraySet(),
                     freeformTasksInZOrder = arrayListOf(1),
+                    leftTiledTask = null,
+                    rightTiledTask = null,
                 )
             verify(persistentRepository)
                 .addOrUpdateDesktop(
@@ -801,6 +868,8 @@
                     visibleTasks = ArraySet(),
                     minimizedTasks = ArraySet(),
                     freeformTasksInZOrder = ArrayList(),
+                    leftTiledTask = null,
+                    rightTiledTask = null,
                 )
         }
     }
@@ -830,6 +899,8 @@
                     visibleTasks = ArraySet(),
                     minimizedTasks = ArraySet(),
                     freeformTasksInZOrder = arrayListOf(1),
+                    leftTiledTask = null,
+                    rightTiledTask = null,
                 )
             verify(persistentRepository)
                 .addOrUpdateDesktop(
@@ -838,6 +909,8 @@
                     visibleTasks = ArraySet(),
                     minimizedTasks = ArraySet(),
                     freeformTasksInZOrder = ArrayList(),
+                    leftTiledTask = null,
+                    rightTiledTask = null,
                 )
         }
     }
@@ -869,6 +942,8 @@
                     visibleTasks = ArraySet(),
                     minimizedTasks = ArraySet(),
                     freeformTasksInZOrder = arrayListOf(1),
+                    leftTiledTask = null,
+                    rightTiledTask = null,
                 )
             verify(persistentRepository, never())
                 .addOrUpdateDesktop(
@@ -877,6 +952,8 @@
                     visibleTasks = ArraySet(),
                     minimizedTasks = ArraySet(),
                     freeformTasksInZOrder = ArrayList(),
+                    leftTiledTask = null,
+                    rightTiledTask = null,
                 )
         }
     }
@@ -1237,36 +1314,6 @@
     }
 
     @Test
-    fun setTaskInPip_savedAsMinimizedPipInDisplay() {
-        assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isFalse()
-
-        repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true)
-
-        assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isTrue()
-    }
-
-    @Test
-    fun removeTaskInPip_removedAsMinimizedPipInDisplay() {
-        repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true)
-        assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isTrue()
-
-        repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = false)
-
-        assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isFalse()
-    }
-
-    @Test
-    fun setTaskInPip_multipleDisplays_bothAreInPip() {
-        repo.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
-        repo.setActiveDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
-        repo.setTaskInPip(DEFAULT_DESKTOP_ID, taskId = 1, enterPip = true)
-        repo.setTaskInPip(SECOND_DISPLAY, taskId = 2, enterPip = true)
-
-        assertThat(repo.isTaskMinimizedPipInDisplay(DEFAULT_DESKTOP_ID, taskId = 1)).isTrue()
-        assertThat(repo.isTaskMinimizedPipInDisplay(SECOND_DISPLAY, taskId = 2)).isTrue()
-    }
-
-    @Test
     @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun addTask_deskDoesNotExists_createsDesk() {
         repo.addTask(displayId = 999, taskId = 6, isVisible = true)
@@ -1421,6 +1468,8 @@
                 visibleTasks = any(),
                 minimizedTasks = any(),
                 freeformTasksInZOrder = any(),
+                leftTiledTask = isNull(),
+                rightTiledTask = isNull(),
             )
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
index 3835c02..71e46bc 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksControllerTest.kt
@@ -57,6 +57,7 @@
 import android.testing.TestableContext
 import android.view.Display
 import android.view.Display.DEFAULT_DISPLAY
+import android.view.Display.INVALID_DISPLAY
 import android.view.DragEvent
 import android.view.Gravity
 import android.view.MotionEvent
@@ -264,6 +265,7 @@
     @Mock private lateinit var desksOrganizer: DesksOrganizer
     @Mock private lateinit var userProfileContexts: UserProfileContexts
     @Mock private lateinit var desksTransitionsObserver: DesksTransitionObserver
+    @Mock private lateinit var desktopPipTransitionObserver: DesktopPipTransitionObserver
     @Mock private lateinit var packageManager: PackageManager
     @Mock private lateinit var mockDisplayContext: Context
     @Mock private lateinit var dragToDisplayTransitionHandler: DragToDisplayTransitionHandler
@@ -358,6 +360,7 @@
             .thenReturn(Binder())
         whenever(displayController.getDisplayLayout(anyInt())).thenReturn(displayLayout)
         whenever(displayController.getDisplayContext(anyInt())).thenReturn(mockDisplayContext)
+        whenever(mockDisplayContext.resources).thenReturn(resources)
         whenever(displayController.getDisplay(anyInt())).thenReturn(display)
         whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
             (i.arguments.first() as Rect).set(STABLE_BOUNDS)
@@ -392,6 +395,7 @@
         whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(wallpaperToken)
         whenever(userProfileContexts[anyInt()]).thenReturn(context)
         whenever(userProfileContexts.getOrCreate(anyInt())).thenReturn(context)
+        whenever(freeformTaskTransitionStarter.startPipTransition(any())).thenReturn(Binder())
 
         controller = createController()
         controller.setSplitScreenController(splitScreenController)
@@ -456,6 +460,7 @@
             overviewToDesktopTransitionObserver,
             desksOrganizer,
             desksTransitionsObserver,
+            Optional.of(desktopPipTransitionObserver),
             userProfileContexts,
             desktopModeCompatPolicy,
             dragToDisplayTransitionHandler,
@@ -3501,6 +3506,7 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
     fun onPipTaskMinimize_autoEnterEnabled_startPipTransition() {
         val task = setUpPipTask(autoEnterEnabled = true)
         val handler = mock(TransitionHandler::class.java)
@@ -3515,6 +3521,7 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
     fun onPipTaskMinimize_autoEnterDisabled_startMinimizeTransition() {
         val task = setUpPipTask(autoEnterEnabled = false)
         whenever(
@@ -3534,6 +3541,103 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+    fun onPipTaskMinimize_autoEnterEnabled_sendsTaskbarRoundingUpdate() {
+        val task = setUpPipTask(autoEnterEnabled = true)
+        val handler = mock(TransitionHandler::class.java)
+        whenever(transitions.dispatchRequest(any(), any(), anyOrNull()))
+            .thenReturn(android.util.Pair(handler, WindowContainerTransaction()))
+
+        controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
+
+        verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(anyBoolean())
+    }
+
+    @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
+    )
+    fun onDesktopTaskEnteredPip_pipIsLastTask_removesWallpaper() {
+        val task = setUpPipTask(autoEnterEnabled = true)
+
+        controller.onDesktopTaskEnteredPip(
+            taskId = task.taskId,
+            deskId = DEFAULT_DISPLAY,
+            displayId = task.displayId,
+            taskIsLastVisibleTaskBeforePip = true,
+        )
+
+        // Wallpaper is moved to the back
+        val wct = getLatestTransition()
+        wct.assertReorder(wallpaperToken, /* toTop= */ false)
+    }
+
+    @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP,
+        Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun onDesktopTaskEnteredPip_pipIsLastTask_deactivatesDesk() {
+        val deskId = DEFAULT_DISPLAY
+        val task = setUpPipTask(autoEnterEnabled = true, deskId = deskId)
+        val transition = Binder()
+        whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition)
+
+        controller.onDesktopTaskEnteredPip(
+            taskId = task.taskId,
+            deskId = deskId,
+            displayId = task.displayId,
+            taskIsLastVisibleTaskBeforePip = true,
+        )
+
+        verify(desksOrganizer).deactivateDesk(any(), eq(deskId))
+        verify(desksTransitionsObserver)
+            .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId))
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+    fun onDesktopTaskEnteredPip_pipIsLastTask_launchesHome() {
+        val task = setUpPipTask(autoEnterEnabled = true)
+
+        controller.onDesktopTaskEnteredPip(
+            taskId = task.taskId,
+            deskId = DEFAULT_DISPLAY,
+            displayId = task.displayId,
+            taskIsLastVisibleTaskBeforePip = true,
+        )
+
+        val wct = getLatestTransition()
+        wct.assertPendingIntent(launchHomeIntent(DEFAULT_DISPLAY))
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
+    fun onDesktopTaskEnteredPip_pipIsNotLastTask_doesntExitDesktopMode() {
+        val task = setUpPipTask(autoEnterEnabled = true)
+        val deskId = DEFAULT_DISPLAY
+        setUpFreeformTask(deskId = deskId) // launch another freeform task
+        val transition = Binder()
+        whenever(transitions.startTransition(any(), any(), anyOrNull())).thenReturn(transition)
+
+        controller.onDesktopTaskEnteredPip(
+            taskId = task.taskId,
+            deskId = deskId,
+            displayId = task.displayId,
+            taskIsLastVisibleTaskBeforePip = false,
+        )
+
+        // No transition to exit Desktop mode is started
+        verifyWCTNotExecuted()
+        verify(desktopModeEnterExitTransitionListener, never())
+            .onExitDesktopModeTransitionStarted(FULLSCREEN_ANIMATION_DURATION)
+        verify(desksOrganizer, never()).deactivateDesk(any(), eq(deskId))
+        verify(desksTransitionsObserver, never())
+            .addPendingTransition(DeskTransition.DeactivateDesk(transition, deskId))
+    }
+
+    @Test
     fun onDesktopWindowMinimize_singleActiveTask_noWallpaperActivityToken_doesntRemoveWallpaper() {
         val task = setUpFreeformTask(active = true)
         val transition = Binder()
@@ -3751,6 +3855,24 @@
     }
 
     @Test
+    fun onDesktopWindowMinimize_sendsTaskbarRoundingUpdate() {
+        val task = setUpFreeformTask(displayId = DEFAULT_DISPLAY)
+        val transition = Binder()
+        whenever(
+                freeformTaskTransitionStarter.startMinimizedModeTransition(
+                    any(),
+                    anyInt(),
+                    anyBoolean(),
+                )
+            )
+            .thenReturn(transition)
+
+        controller.minimizeTask(task, MinimizeReason.MINIMIZE_BUTTON)
+
+        verify(taskbarDesktopTaskListener).onTaskbarCornerRoundingUpdate(anyBoolean())
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
     fun handleRequest_fullscreenTask_switchToDesktop_movesTaskToDesk() {
         taskRepository.addDesk(displayId = DEFAULT_DISPLAY, deskId = 5)
@@ -5014,6 +5136,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY)
+    @DisableFlags(Flags.FLAG_ENABLE_MODALS_FULLSCREEN_WITH_PERMISSION)
     fun handleRequest_closeTransition_singleTaskNoToken_secondaryDisplay_launchesHome() {
         taskRepository.addDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
         taskRepository.setActiveDesk(displayId = SECOND_DISPLAY, deskId = SECOND_DISPLAY)
@@ -7351,6 +7474,14 @@
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    fun testCreateDesk_invalidDisplay_dropsRequest() {
+        controller.createDesk(INVALID_DISPLAY)
+
+        verify(desksOrganizer, never()).createDesk(any(), any())
+    }
+
+    @Test
     @EnableFlags(
         Flags.FLAG_ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY,
         Flags.FLAG_ENABLE_DESKTOP_WALLPAPER_ACTIVITY_FOR_SYSTEM_USER,
@@ -7646,8 +7777,12 @@
         return task
     }
 
-    private fun setUpPipTask(autoEnterEnabled: Boolean): RunningTaskInfo =
-        setUpFreeformTask().apply {
+    private fun setUpPipTask(
+        autoEnterEnabled: Boolean,
+        displayId: Int = DEFAULT_DISPLAY,
+        deskId: Int = DEFAULT_DISPLAY,
+    ): RunningTaskInfo =
+        setUpFreeformTask(displayId = displayId, deskId = deskId).apply {
             pictureInPictureParams =
                 PictureInPictureParams.Builder().setAutoEnterEnabled(autoEnterEnabled).build()
         }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
index a7dc706..5ef1ace 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksTransitionObserverTest.kt
@@ -22,7 +22,6 @@
 import android.content.ComponentName
 import android.content.Context
 import android.content.Intent
-import android.os.Binder
 import android.os.IBinder
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
@@ -30,7 +29,6 @@
 import android.view.WindowManager
 import android.view.WindowManager.TRANSIT_CLOSE
 import android.view.WindowManager.TRANSIT_OPEN
-import android.view.WindowManager.TRANSIT_PIP
 import android.view.WindowManager.TRANSIT_TO_BACK
 import android.view.WindowManager.TRANSIT_TO_FRONT
 import android.window.IWindowContainerToken
@@ -41,7 +39,6 @@
 import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
 import com.android.modules.utils.testing.ExtendedMockitoRule
 import com.android.window.flags.Flags
-import com.android.window.flags.Flags.FLAG_ENABLE_DESKTOP_WINDOWING_PIP
 import com.android.wm.shell.MockToken
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.back.BackAnimationController
@@ -51,10 +48,9 @@
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus
 import com.android.wm.shell.sysui.ShellInit
 import com.android.wm.shell.transition.Transitions
-import com.android.wm.shell.transition.Transitions.TRANSIT_EXIT_PIP
-import com.android.wm.shell.transition.Transitions.TRANSIT_REMOVE_PIP
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
+import java.util.Optional
 import org.junit.Before
 import org.junit.Rule
 import org.junit.Test
@@ -90,6 +86,7 @@
     private val userRepositories = mock<DesktopUserRepositories>()
     private val taskRepository = mock<DesktopRepository>()
     private val mixedHandler = mock<DesktopMixedTransitionHandler>()
+    private val pipTransitionObserver = mock<DesktopPipTransitionObserver>()
     private val backAnimationController = mock<BackAnimationController>()
     private val desktopWallpaperActivityTokenProvider =
         mock<DesktopWallpaperActivityTokenProvider>()
@@ -114,6 +111,7 @@
                 transitions,
                 shellTaskOrganizer,
                 mixedHandler,
+                Optional.of(pipTransitionObserver),
                 backAnimationController,
                 desktopWallpaperActivityTokenProvider,
                 shellInit,
@@ -336,6 +334,50 @@
     }
 
     @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY,
+        Flags.FLAG_INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC,
+    )
+    fun nonTopTransparentTaskOpened_clearTopTransparentTaskIdFromRepository() {
+        val mockTransition = Mockito.mock(IBinder::class.java)
+        val topTransparentTask = createTaskInfo(1)
+        val nonTopTransparentTask = createTaskInfo(2)
+        whenever(taskRepository.getTopTransparentFullscreenTaskId(any()))
+            .thenReturn(topTransparentTask.taskId)
+
+        transitionObserver.onTransitionReady(
+            transition = mockTransition,
+            info = createOpenChangeTransition(nonTopTransparentTask),
+            startTransaction = mock(),
+            finishTransaction = mock(),
+        )
+
+        verify(taskRepository).clearTopTransparentFullscreenTaskId(topTransparentTask.displayId)
+    }
+
+    @Test
+    @EnableFlags(
+        Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODALS_POLICY,
+        Flags.FLAG_INCLUDE_TOP_TRANSPARENT_FULLSCREEN_TASK_IN_DESKTOP_HEURISTIC,
+    )
+    fun nonTopTransparentTaskSentToFront_clearTopTransparentTaskIdFromRepository() {
+        val mockTransition = Mockito.mock(IBinder::class.java)
+        val topTransparentTask = createTaskInfo(1)
+        val nonTopTransparentTask = createTaskInfo(2)
+        whenever(taskRepository.getTopTransparentFullscreenTaskId(any()))
+            .thenReturn(topTransparentTask.taskId)
+
+        transitionObserver.onTransitionReady(
+            transition = mockTransition,
+            info = createToFrontTransition(nonTopTransparentTask),
+            startTransaction = mock(),
+            finishTransaction = mock(),
+        )
+
+        verify(taskRepository).clearTopTransparentFullscreenTaskId(topTransparentTask.displayId)
+    }
+
+    @Test
     fun transitCloseWallpaper_wallpaperActivityVisibilitySaved() {
         val wallpaperTask = createWallpaperTaskInfo()
 
@@ -349,56 +391,6 @@
         verify(desktopWallpaperActivityTokenProvider).removeToken(wallpaperTask.displayId)
     }
 
-    @Test
-    @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
-    fun pendingPipTransitionAborted_taskRepositoryOnPipAbortedInvoked() {
-        val task = createTaskInfo(1, WINDOWING_MODE_FREEFORM)
-        val pipTransition = Binder()
-        whenever(taskRepository.isTaskMinimizedPipInDisplay(any(), any())).thenReturn(true)
-
-        transitionObserver.onTransitionReady(
-            transition = pipTransition,
-            info = createOpenChangeTransition(task, type = TRANSIT_PIP),
-            startTransaction = mock(),
-            finishTransaction = mock(),
-        )
-        transitionObserver.onTransitionFinished(transition = pipTransition, aborted = true)
-
-        verify(taskRepository).onPipAborted(task.displayId, task.taskId)
-    }
-
-    @Test
-    @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
-    fun exitPipTransition_taskRepositoryClearTaskInPip() {
-        val task = createTaskInfo(1, WINDOWING_MODE_FREEFORM)
-        whenever(taskRepository.isTaskMinimizedPipInDisplay(any(), any())).thenReturn(true)
-
-        transitionObserver.onTransitionReady(
-            transition = mock(),
-            info = createOpenChangeTransition(task, type = TRANSIT_EXIT_PIP),
-            startTransaction = mock(),
-            finishTransaction = mock(),
-        )
-
-        verify(taskRepository).setTaskInPip(task.displayId, task.taskId, enterPip = false)
-    }
-
-    @Test
-    @EnableFlags(FLAG_ENABLE_DESKTOP_WINDOWING_PIP)
-    fun removePipTransition_taskRepositoryClearTaskInPip() {
-        val task = createTaskInfo(1, WINDOWING_MODE_FREEFORM)
-        whenever(taskRepository.isTaskMinimizedPipInDisplay(any(), any())).thenReturn(true)
-
-        transitionObserver.onTransitionReady(
-            transition = mock(),
-            info = createOpenChangeTransition(task, type = TRANSIT_REMOVE_PIP),
-            startTransaction = mock(),
-            finishTransaction = mock(),
-        )
-
-        verify(taskRepository).setTaskInPip(task.displayId, task.taskId, enterPip = false)
-    }
-
     private fun createBackNavigationTransition(
         task: RunningTaskInfo?,
         type: Int = TRANSIT_TO_BACK,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
index dc96694..4e2994c 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DragToDesktopTransitionHandlerTest.kt
@@ -66,7 +66,7 @@
 import org.mockito.kotlin.never
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
-import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.verifyNoMoreInteractions
 import org.mockito.kotlin.whenever
 import org.mockito.quality.Strictness
 
@@ -457,7 +457,7 @@
         )
 
         // No need to animate the cancel since the start animation couldn't even start.
-        verifyZeroInteractions(dragAnimator)
+        verifyNoMoreInteractions(dragAnimator)
     }
 
     @Test
@@ -508,7 +508,7 @@
         )
 
         // Should NOT have any transaction changes
-        verifyZeroInteractions(mergedStartTransaction)
+        verifyNoMoreInteractions(mergedStartTransaction)
         // Should NOT merge animation
         verify(finishCallback, never()).onTransitionFinished(any())
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
index c7518d5..3983bfb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/VisualIndicatorViewContainerTest.kt
@@ -54,7 +54,7 @@
 import org.mockito.kotlin.never
 import org.mockito.kotlin.spy
 import org.mockito.kotlin.verify
-import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.verifyNoMoreInteractions
 import org.mockito.kotlin.whenever
 
 /**
@@ -111,7 +111,7 @@
                 eq(DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR),
             )
         // Assert fadeIn, fadeOut, and animateIndicatorType were not called.
-        verifyZeroInteractions(spyViewContainer)
+        verifyNoMoreInteractions(spyViewContainer)
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
index 7560945..dc973d0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/compatui/SystemModalsTransitionHandlerTest.kt
@@ -90,7 +90,7 @@
         whenever(packageManager.getHomeActivities(ArrayList())).thenReturn(componentName)
         desktopModeCompatPolicy = DesktopModeCompatPolicy(spyContext)
         transitionHandler = createTransitionHandler()
-        allowOverlayPermission(arrayOf(SYSTEM_ALERT_WINDOW))
+        allowOverlayPermissionForAllUsers(arrayOf(SYSTEM_ALERT_WINDOW))
     }
 
     private fun createTransitionHandler() =
@@ -200,10 +200,16 @@
             .isTrue()
     }
 
-    fun allowOverlayPermission(permissions: Array<String>) {
+    fun allowOverlayPermissionForAllUsers(permissions: Array<String>) {
         val packageInfo = mock<PackageInfo>()
         packageInfo.requestedPermissions = permissions
-        whenever(packageManager.getPackageInfo(anyString(), eq(PackageManager.GET_PERMISSIONS)))
+        whenever(
+                packageManager.getPackageInfoAsUser(
+                    anyString(),
+                    eq(PackageManager.GET_PERMISSIONS),
+                    anyInt(),
+                )
+            )
             .thenReturn(packageInfo)
     }
 }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt
index 5f92326..6039b8f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopPersistentRepositoryTest.kt
@@ -115,6 +115,8 @@
                 minimizedTasks = minimizedTasks,
                 freeformTasksInZOrder = freeformTasksInZOrder,
                 userId = DEFAULT_USER_ID,
+                leftTiledTask = null,
+                rightTiledTask = null,
             )
 
             val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID)
@@ -124,6 +126,50 @@
     }
 
     @Test
+    fun addTiledTasks_addsTiledTasksToDesktop() {
+        runTest(StandardTestDispatcher()) {
+            // Create a basic repository state
+            val task = createDesktopTask(1)
+            val desktopPersistentRepositories = createRepositoryWithOneDesk(task)
+            testDatastore.updateData { desktopPersistentRepositories }
+            // Create a new state to be initialized
+            val visibleTasks = ArraySet(listOf(1, 2))
+
+            // Update with new state
+            datastoreRepository.addOrUpdateDesktop(
+                visibleTasks = visibleTasks,
+                minimizedTasks = ArraySet(),
+                freeformTasksInZOrder = ArrayList(),
+                userId = DEFAULT_USER_ID,
+                leftTiledTask = 1,
+                rightTiledTask = null,
+            )
+
+            var actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID)
+            assertThat(actualDesktop?.tasksByTaskIdMap?.get(1)?.desktopTaskTilingState)
+                .isEqualTo(DesktopTaskTilingState.LEFT)
+            assertThat(actualDesktop?.tasksByTaskIdMap?.get(2)?.desktopTaskTilingState)
+                .isEqualTo(DesktopTaskTilingState.NONE)
+
+            // Update with new state
+            datastoreRepository.addOrUpdateDesktop(
+                visibleTasks = visibleTasks,
+                minimizedTasks = ArraySet(),
+                freeformTasksInZOrder = ArrayList(),
+                userId = DEFAULT_USER_ID,
+                leftTiledTask = null,
+                rightTiledTask = 2,
+            )
+
+            actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID)
+            assertThat(actualDesktop?.tasksByTaskIdMap?.get(1)?.desktopTaskTilingState)
+                .isEqualTo(DesktopTaskTilingState.NONE)
+            assertThat(actualDesktop?.tasksByTaskIdMap?.get(2)?.desktopTaskTilingState)
+                .isEqualTo(DesktopTaskTilingState.RIGHT)
+        }
+    }
+
+    @Test
     fun removeUsers_removesUsersData() {
         runTest(StandardTestDispatcher()) {
             val task = createDesktopTask(1)
@@ -138,12 +184,16 @@
                 minimizedTasks = minimizedTasks,
                 freeformTasksInZOrder = freeformTasksInZOrder,
                 userId = DEFAULT_USER_ID,
+                leftTiledTask = null,
+                rightTiledTask = null,
             )
             datastoreRepository.addOrUpdateDesktop(
                 visibleTasks = visibleTasks,
                 minimizedTasks = minimizedTasks,
                 freeformTasksInZOrder = freeformTasksInZOrder,
                 userId = USER_ID_2,
+                leftTiledTask = null,
+                rightTiledTask = null,
             )
 
             datastoreRepository.removeUsers(mutableListOf(USER_ID_2))
@@ -175,6 +225,8 @@
                 minimizedTasks = minimizedTasks,
                 freeformTasksInZOrder = freeformTasksInZOrder,
                 userId = DEFAULT_USER_ID,
+                leftTiledTask = null,
+                rightTiledTask = null,
             )
 
             val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID)
@@ -200,6 +252,8 @@
                 minimizedTasks = minimizedTasks,
                 freeformTasksInZOrder = freeformTasksInZOrder,
                 userId = DEFAULT_USER_ID,
+                leftTiledTask = null,
+                rightTiledTask = null,
             )
 
             val actualDesktop = datastoreRepository.readDesktop(DEFAULT_USER_ID, DEFAULT_DESKTOP_ID)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
index 4440d4e..601eb31 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/persistence/DesktopRepositoryInitializerTest.kt
@@ -27,6 +27,7 @@
 import com.android.wm.shell.ShellTestCase
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.desktopmode.DesktopUserRepositories
+import com.android.wm.shell.desktopmode.persistence.DesktopRepositoryInitializer.DeskRecreationFactory
 import com.android.wm.shell.sysui.ShellController
 import com.android.wm.shell.sysui.ShellInit
 import com.google.common.truth.Truth.assertThat
@@ -242,6 +243,36 @@
                 .inOrder()
         }
 
+    @Test
+    @EnableFlags(
+        FLAG_ENABLE_DESKTOP_WINDOWING_PERSISTENCE,
+        FLAG_ENABLE_DESKTOP_WINDOWING_HSUM,
+        FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+    )
+    fun initWithPersistence_deskRecreationFailed_deskNotAdded() =
+        runTest(StandardTestDispatcher()) {
+            whenever(persistentRepository.getUserDesktopRepositoryMap())
+                .thenReturn(mapOf(USER_ID_1 to desktopRepositoryState1))
+            whenever(persistentRepository.getDesktopRepositoryState(USER_ID_1))
+                .thenReturn(desktopRepositoryState1)
+            whenever(persistentRepository.readDesktop(USER_ID_1, DESKTOP_ID_1)).thenReturn(desktop1)
+            whenever(persistentRepository.readDesktop(USER_ID_1, DESKTOP_ID_2)).thenReturn(desktop2)
+
+            // Make [DESKTOP_ID_2] re-creation fail.
+            repositoryInitializer.deskRecreationFactory =
+                DeskRecreationFactory { userId, destinationDisplayId, deskId ->
+                    if (deskId == DESKTOP_ID_2) {
+                        null
+                    } else {
+                        deskId
+                    }
+                }
+            repositoryInitializer.initialize(desktopUserRepositories)
+
+            assertThat(desktopUserRepositories.getProfile(USER_ID_1).getDeskIds(DEFAULT_DISPLAY))
+                .containsExactly(DESKTOP_ID_1)
+        }
+
     @After
     fun tearDown() {
         datastoreScope.cancel()
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipAlphaAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipAlphaAnimatorTest.java
index 14f9ffc..2bd9afc 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipAlphaAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipAlphaAnimatorTest.java
@@ -24,7 +24,7 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -107,7 +107,7 @@
         });
 
         verify(mMockStartCallback).run();
-        verifyZeroInteractions(mMockEndCallback);
+        verifyNoMoreInteractions(mMockEndCallback);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipEnterAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipEnterAnimatorTest.java
index 72c4666..fa7ab952 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipEnterAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipEnterAnimatorTest.java
@@ -24,7 +24,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -117,7 +117,7 @@
         });
 
         verify(mMockStartCallback).run();
-        verifyZeroInteractions(mMockEndCallback);
+        verifyNoMoreInteractions(mMockEndCallback);
 
         // Check corner and shadow radii were set
         verify(mMockAnimateTransaction, atLeastOnce())
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipExpandAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipExpandAnimatorTest.java
index b816f0e..97133be 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipExpandAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipExpandAnimatorTest.java
@@ -21,7 +21,7 @@
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -143,7 +143,7 @@
         });
 
         verify(mMockStartCallback).run();
-        verifyZeroInteractions(mMockEndCallback);
+        verifyNoMoreInteractions(mMockEndCallback);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipResizeAnimatorTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipResizeAnimatorTest.java
index 23fbad0..c99ca6d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipResizeAnimatorTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/animation/PipResizeAnimatorTest.java
@@ -22,7 +22,7 @@
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 import static org.mockito.kotlin.MatchersKt.eq;
 
@@ -118,7 +118,7 @@
         });
 
         verify(mMockStartCallback).run();
-        verifyZeroInteractions(mMockEndCallback);
+        verifyNoMoreInteractions(mMockEndCallback);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
index 5029371..a760890 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipTaskListenerTest.java
@@ -30,7 +30,7 @@
 import static org.mockito.kotlin.VerificationKt.clearInvocations;
 import static org.mockito.kotlin.VerificationKt.times;
 import static org.mockito.kotlin.VerificationKt.verify;
-import static org.mockito.kotlin.VerificationKt.verifyZeroInteractions;
+import static org.mockito.kotlin.VerificationKt.verifyNoMoreInteractions;
 
 import android.app.ActivityManager;
 import android.app.PendingIntent;
@@ -176,7 +176,7 @@
         mPipTaskListener.setPictureInPictureParams(getPictureInPictureParams(
                 aspectRatio, action1));
 
-        verifyZeroInteractions(mMockPipParamsChangedCallback);
+        verifyNoMoreInteractions(mMockPipParamsChangedCallback);
     }
 
     @Test
@@ -193,9 +193,10 @@
         clearInvocations(mMockPipParamsChangedCallback);
         mPipTaskListener.onTaskInfoChanged(new ActivityManager.RunningTaskInfo());
 
-        verifyZeroInteractions(mMockPipParamsChangedCallback);
+        verifyNoMoreInteractions(mMockPipParamsChangedCallback);
         verify(mMockPipTransitionState, times(0))
                 .setOnIdlePipTransitionStateRunnable(any(Runnable.class));
+        assertTrue(mPipTaskListener.getPictureInPictureParams().empty());
     }
 
     @Test
@@ -245,7 +246,7 @@
         mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
 
         verify(mMockPipTransitionState).setOnIdlePipTransitionStateRunnable(any(Runnable.class));
-        verifyZeroInteractions(mMockPipParamsChangedCallback);
+        verifyNoMoreInteractions(mMockPipParamsChangedCallback);
     }
 
     @Test
@@ -262,7 +263,7 @@
         clearInvocations(mMockPipParamsChangedCallback);
         mPipTaskListener.onTaskInfoChanged(getTaskInfo(aspectRatio, action1));
 
-        verifyZeroInteractions(mMockPipParamsChangedCallback);
+        verifyNoMoreInteractions(mMockPipParamsChangedCallback);
         verify(mMockPipTransitionState, times(0))
                 .setOnIdlePipTransitionStateRunnable(any(Runnable.class));
     }
@@ -319,7 +320,7 @@
                 PipTransitionState.SCHEDULED_BOUNDS_CHANGE,
                 extras);
 
-        verifyZeroInteractions(mMockPipScheduler);
+        verifyNoMoreInteractions(mMockPipScheduler);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipUiStateChangeControllerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipUiStateChangeControllerTests.java
index 82cdfd5..51de50d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipUiStateChangeControllerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip2/phone/PipUiStateChangeControllerTests.java
@@ -20,7 +20,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.Flags;
@@ -82,7 +82,7 @@
         mPipUiStateChangeController.onPipTransitionStateChanged(
                 PipTransitionState.SWIPING_TO_PIP, PipTransitionState.ENTERING_PIP, Bundle.EMPTY);
 
-        verifyZeroInteractions(mPictureInPictureUiStateConsumer);
+        verifyNoMoreInteractions(mPictureInPictureUiStateConsumer);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
index 75f6bda..4e8812d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/GroupedTaskInfoTest.kt
@@ -21,6 +21,7 @@
 import android.graphics.Rect
 import android.os.Parcel
 import android.testing.AndroidTestingRunner
+import android.view.Display.DEFAULT_DISPLAY
 import android.window.IWindowContainerToken
 import android.window.WindowContainerToken
 import androidx.test.filters.SmallTest
@@ -281,7 +282,8 @@
         val task2 = createTaskInfo(id = 2)
 
         val taskInfo = GroupedTaskInfo.forDeskTasks(
-            /* deskId = */ 500, listOf(task1, task2), setOf())
+            /* deskId = */ 500, DEFAULT_DISPLAY, listOf(task1, task2), setOf()
+        )
 
         assertThat(taskInfo.deskId).isEqualTo(500)
         assertThat(taskInfo.getTaskById(1)).isEqualTo(task1)
@@ -335,6 +337,7 @@
     ): GroupedTaskInfo {
         return GroupedTaskInfo.forDeskTasks(
             deskId,
+            DEFAULT_DISPLAY,
             freeformTaskIds.map { createTaskInfo(it) }.toList(),
             minimizedTaskIds.toSet())
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicyTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicyTest.kt
index 5ac6800..12785c0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicyTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/shared/desktopmode/DesktopModeCompatPolicyTest.kt
@@ -42,6 +42,7 @@
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.ArgumentMatchers.anyString
 import org.mockito.kotlin.any
 import org.mockito.kotlin.eq
@@ -87,7 +88,7 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_MODALS_FULLSCREEN_WITH_PERMISSION)
     fun testIsTopActivityExemptWithPermission_onlyTransparentActivitiesInStack() {
-        allowOverlayPermission(arrayOf(SYSTEM_ALERT_WINDOW))
+        allowOverlayPermissionForAllUsers(arrayOf(SYSTEM_ALERT_WINDOW))
         assertTrue(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
             createFreeformTask(/* displayId */ 0)
                 .apply {
@@ -101,7 +102,7 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_MODALS_FULLSCREEN_WITH_PERMISSION)
     fun testIsTopActivityExemptWithNoPermission_onlyTransparentActivitiesInStack() {
-        allowOverlayPermission(arrayOf())
+        allowOverlayPermissionForAllUsers(arrayOf())
         assertFalse(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
             createFreeformTask(/* displayId */ 0)
                 .apply {
@@ -115,7 +116,7 @@
     @Test
     @EnableFlags(Flags.FLAG_ENABLE_MODALS_FULLSCREEN_WITH_PERMISSION)
     fun testIsTopActivityExemptCachedPermissionCheckIsUsed() {
-        allowOverlayPermission(arrayOf())
+        allowOverlayPermissionForAllUsers(arrayOf())
         assertFalse(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
             createFreeformTask(/* displayId */ 0)
                 .apply {
@@ -123,6 +124,7 @@
                     isTopActivityNoDisplay = false
                     numActivities = 1
                     baseActivity = baseActivityTest
+                    userId = 10
                 }))
         assertFalse(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
             createFreeformTask(/* displayId */ 0)
@@ -131,10 +133,26 @@
                     isTopActivityNoDisplay = false
                     numActivities = 1
                     baseActivity = baseActivityTest
+                    userId = 10
                 }))
-        verify(packageManager, times(1)).getPackageInfo(
+        assertFalse(desktopModeCompatPolicy.isTopActivityExemptFromDesktopWindowing(
+            createFreeformTask(/* displayId */ 0)
+                .apply {
+                    isActivityStackTransparent = true
+                    isTopActivityNoDisplay = false
+                    numActivities = 1
+                    baseActivity = baseActivityTest
+                    userId = 0
+                }))
+        verify(packageManager, times(1)).getPackageInfoAsUser(
             eq("com.test.dummypackage"),
-            eq(PackageManager.GET_PERMISSIONS)
+            eq(PackageManager.GET_PERMISSIONS),
+            eq(10)
+        )
+        verify(packageManager, times(1)).getPackageInfoAsUser(
+            eq("com.test.dummypackage"),
+            eq(PackageManager.GET_PERMISSIONS),
+            eq(0)
         )
     }
 
@@ -284,13 +302,14 @@
             }
         }
 
-    fun allowOverlayPermission(permissions: Array<String>) {
+    fun allowOverlayPermissionForAllUsers(permissions: Array<String>) {
         val packageInfo = mock<PackageInfo>()
         packageInfo.requestedPermissions = permissions
         whenever(
-            packageManager.getPackageInfo(
+            packageManager.getPackageInfoAsUser(
                 anyString(),
-                eq(PackageManager.GET_PERMISSIONS)
+                eq(PackageManager.GET_PERMISSIONS),
+                anyInt(),
             )
         ).thenReturn(packageInfo)
     }
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelperTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelperTests.kt
new file mode 100644
index 0000000..23751b6
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitMultiDisplayHelperTests.kt
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.splitscreen
+
+import android.app.ActivityManager
+import android.hardware.display.DisplayManager
+import android.view.Display
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.wm.shell.ShellTestCase
+import com.android.wm.shell.common.split.SplitLayout
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+/**
+ * Unit tests for [SplitMultiDisplayHelper].
+ */
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SplitMultiDisplayHelperTests : ShellTestCase() {
+
+    private lateinit var splitMultiDisplayHelper: SplitMultiDisplayHelper
+
+    @Mock
+    private lateinit var mockDisplayManager: DisplayManager
+    @Mock
+    private lateinit var mockSplitLayout: SplitLayout
+    @Mock
+    private lateinit var mockDisplay1: Display
+    @Mock
+    private lateinit var mockDisplay2: Display
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        mockDisplay1 = mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY) ?: mock(Display::class.java)
+        mockDisplay2 = mockDisplayManager.getDisplay(Display.DEFAULT_DISPLAY + 1) ?: mock(Display::class.java)
+
+        `when`(mockDisplay1.displayId).thenReturn(Display.DEFAULT_DISPLAY)
+        `when`(mockDisplay2.displayId).thenReturn(Display.DEFAULT_DISPLAY + 1)
+
+        splitMultiDisplayHelper = SplitMultiDisplayHelper(mockDisplayManager)
+    }
+
+    @Test
+    fun getDisplayIds_noDisplays_returnsEmptyList() {
+        `when`(mockDisplayManager.displays).thenReturn(emptyArray())
+
+        val displayIds = splitMultiDisplayHelper.getDisplayIds()
+
+        assertThat(displayIds).isEmpty()
+    }
+
+    @Test
+    fun getDisplayIds_singleDisplay_returnsCorrectId() {
+        `when`(mockDisplayManager.displays).thenReturn(arrayOf(mockDisplay1))
+
+        val displayIds = splitMultiDisplayHelper.getDisplayIds()
+
+        assertThat(displayIds).containsExactly(Display.DEFAULT_DISPLAY)
+    }
+
+    @Test
+    fun getDisplayIds_multiDisplays_returnsCorrectIds() {
+        `when`(mockDisplayManager.displays).thenReturn(arrayOf(mockDisplay1, mockDisplay2))
+
+        val displayIds = splitMultiDisplayHelper.getDisplayIds()
+
+        assertThat(displayIds).containsExactly(Display.DEFAULT_DISPLAY, Display.DEFAULT_DISPLAY + 1)
+    }
+
+    @Test
+    fun swapDisplayTaskHierarchy_validDisplays_swapsHierarchies() {
+        val rootTaskInfo1 = ActivityManager.RunningTaskInfo().apply { taskId = 1 }
+        val rootTaskInfo2 = ActivityManager.RunningTaskInfo().apply { taskId = 2 }
+
+        splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo1)
+        splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY + 1, rootTaskInfo2)
+
+        splitMultiDisplayHelper.swapDisplayTaskHierarchy(Display.DEFAULT_DISPLAY, Display.DEFAULT_DISPLAY + 1)
+
+        assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY)).isEqualTo(rootTaskInfo2)
+        assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY + 1)).isEqualTo(rootTaskInfo1)
+    }
+
+    @Test
+    fun swapDisplayTaskHierarchy_invalidFirstDisplayId_doesNothing() {
+        val rootTaskInfo2 = ActivityManager.RunningTaskInfo().apply { taskId = 2 }
+
+        splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY + 1, rootTaskInfo2)
+
+        splitMultiDisplayHelper.swapDisplayTaskHierarchy(Display.INVALID_DISPLAY, Display.DEFAULT_DISPLAY + 1)
+
+        assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.INVALID_DISPLAY)).isNull()
+        assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY + 1)).isEqualTo(rootTaskInfo2)
+    }
+
+    @Test
+    fun swapDisplayTaskHierarchy_invalidSecondDisplayId_doesNothing() {
+        val rootTaskInfo1 = ActivityManager.RunningTaskInfo().apply { taskId = 1 }
+
+        splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo1)
+
+        splitMultiDisplayHelper.swapDisplayTaskHierarchy(Display.DEFAULT_DISPLAY, Display.INVALID_DISPLAY)
+
+        assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY)).isEqualTo(rootTaskInfo1)
+        assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.INVALID_DISPLAY)).isNull()
+    }
+
+    @Test
+    fun swapDisplayTaskHierarchy_sameDisplayId_doesNothing() {
+        val rootTaskInfo1 = ActivityManager.RunningTaskInfo().apply { taskId = 1 }
+
+        splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo1)
+
+        splitMultiDisplayHelper.swapDisplayTaskHierarchy(Display.DEFAULT_DISPLAY, Display.DEFAULT_DISPLAY)
+
+        assertThat(splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY)).isEqualTo(rootTaskInfo1)
+    }
+
+    @Test
+    fun getDisplayRootTaskInfo_validDisplayId_returnsRootTaskInfo() {
+        val rootTaskInfo = ActivityManager.RunningTaskInfo().apply { taskId = 123 }
+
+        splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo)
+
+        val retrievedRootTaskInfo = splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY)
+
+        assertThat(retrievedRootTaskInfo).isEqualTo(rootTaskInfo)
+    }
+
+    @Test
+    fun getDisplayRootTaskInfo_invalidDisplayId_returnsNull() {
+        val retrievedRootTaskInfo = splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.INVALID_DISPLAY)
+
+        assertThat(retrievedRootTaskInfo).isNull()
+    }
+
+    @Test
+    fun setDisplayRootTaskInfo_setsRootTaskInfo() {
+        val rootTaskInfo = ActivityManager.RunningTaskInfo().apply { taskId = 456 }
+
+        splitMultiDisplayHelper.setDisplayRootTaskInfo(Display.DEFAULT_DISPLAY, rootTaskInfo)
+        val retrievedRootTaskInfo = splitMultiDisplayHelper.getDisplayRootTaskInfo(Display.DEFAULT_DISPLAY)
+
+        assertThat(retrievedRootTaskInfo).isEqualTo(rootTaskInfo)
+    }
+}
\ No newline at end of file
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 5dff218..077b355 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
@@ -571,7 +571,8 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    @DisableFlags({Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+            Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX})
     public void testRequestEnterSplit_didNotEnterSplitSelect_doesNotApplyTransaction() {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         mStageCoordinator.registerSplitSelectListener(
@@ -585,7 +586,8 @@
     }
 
     @Test
-    @DisableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND)
+    @DisableFlags({Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND,
+            Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX})
     public void testRequestEnterSplit_enteredSplitSelect_appliesTransaction() {
         final WindowContainerTransaction wct = new WindowContainerTransaction();
         mStageCoordinator.registerSplitSelectListener(
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 a122c38..55bff09 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
@@ -222,7 +222,7 @@
 
     @Test
     @EnableFlags({FLAG_ENABLE_DRAG_TO_DESKTOP_INCOMING_TRANSITIONS_BUGFIX})
-    public void startDragToDesktopAborted_doesNotTriggerCallback() throws RemoteException {
+    public void startDragToDesktopAborted_triggersCallback() throws RemoteException {
         TransitionInfo info = mock(TransitionInfo.class);
         TransitionInfo.Change change = mock(TransitionInfo.Change.class);
         ActivityManager.RunningTaskInfo taskInfo = mock(ActivityManager.RunningTaskInfo.class);
@@ -239,7 +239,7 @@
 
         mHomeTransitionObserver.onTransitionFinished(transition, /* aborted= */ true);
 
-        verify(mListener, never()).onHomeVisibilityChanged(/* isVisible= */ anyBoolean());
+        verify(mListener).onHomeVisibilityChanged(/* isVisible= */ true);
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
index 067dcec..b1f9241 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelAppHandleOnlyTest.kt
@@ -28,6 +28,7 @@
 import android.view.Display
 import android.view.Display.DEFAULT_DISPLAY
 import android.view.SurfaceControl
+import android.view.WindowManager.TRANSIT_CHANGE
 import androidx.test.filters.SmallTest
 import com.android.dx.mockito.inline.extended.ExtendedMockito.anyBoolean
 import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
@@ -109,7 +110,7 @@
         onTaskOpening(task, taskSurface)
         assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
         task.setActivityType(ACTIVITY_TYPE_UNDEFINED)
-        onTaskChanging(task, taskSurface)
+        onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
 
         assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
         verify(decoration).close()
@@ -165,7 +166,7 @@
 
         setLargeScreen(false)
         setUpMockDecorationForTask(task)
-        onTaskChanging(task, taskSurface)
+        onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
         assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
     }
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
index d69509f..ad3426e 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTests.kt
@@ -51,6 +51,7 @@
 import android.view.View
 import android.view.ViewRootImpl
 import android.view.WindowInsets.Type.statusBars
+import android.view.WindowManager.TRANSIT_CHANGE
 import android.window.WindowContainerTransaction
 import android.window.WindowContainerTransaction.HierarchyOp
 import androidx.test.filters.SmallTest
@@ -134,7 +135,7 @@
 
         task.setWindowingMode(WINDOWING_MODE_UNDEFINED)
         task.setActivityType(ACTIVITY_TYPE_UNDEFINED)
-        onTaskChanging(task, taskSurface)
+        onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
 
         assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
         verify(decoration).close()
@@ -149,12 +150,12 @@
         val taskSurface = SurfaceControl()
         setUpMockDecorationForTask(task)
 
-        onTaskChanging(task, taskSurface)
+        onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
         assertFalse(windowDecorByTaskIdSpy.contains(task.taskId))
 
         task.setWindowingMode(WINDOWING_MODE_FREEFORM)
         task.setActivityType(ACTIVITY_TYPE_STANDARD)
-        onTaskChanging(task, taskSurface)
+        onTaskChanging(task, taskSurface, TRANSIT_CHANGE)
         assertTrue(windowDecorByTaskIdSpy.contains(task.taskId))
     }
 
@@ -758,20 +759,6 @@
     }
 
     @Test
-    fun testDecor_onClickToSplitScreen_disposesStatusBarInputLayer() {
-        val toSplitScreenListenerCaptor = forClass(Function0::class.java)
-                as ArgumentCaptor<Function0<Unit>>
-        val decor = createOpenTaskDecoration(
-            windowingMode = WINDOWING_MODE_MULTI_WINDOW,
-            onToSplitScreenClickListenerCaptor = toSplitScreenListenerCaptor
-        )
-
-        toSplitScreenListenerCaptor.value.invoke()
-
-        verify(decor).disposeStatusBarInputLayer()
-    }
-
-    @Test
     fun testDecor_onClickToOpenBrowser_closeMenus() {
         val openInBrowserListenerCaptor = forClass(Consumer::class.java)
                 as ArgumentCaptor<Consumer<Intent>>
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
index a1f40fd..4c9c2f1 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DesktopModeWindowDecorViewModelTestsBase.kt
@@ -84,6 +84,7 @@
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier
 import com.android.wm.shell.windowdecor.tiling.DesktopTilingDecorViewModel
+import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder
 import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder
 import org.junit.After
 import org.mockito.Mockito
@@ -125,6 +126,7 @@
     protected val mockShellController = mock<ShellController>()
     protected val testShellExecutor = TestShellExecutor()
     protected val mockAppHeaderViewHolderFactory = mock<AppHeaderViewHolder.Factory>()
+    protected val mockAppHandleViewHolderFactory = mock<AppHandleViewHolder.Factory>()
     protected val mockRootTaskDisplayAreaOrganizer = mock<RootTaskDisplayAreaOrganizer>()
     protected val mockShellCommandHandler = mock<ShellCommandHandler>()
     protected val mockWindowManager = mock<IWindowManager>()
@@ -222,6 +224,7 @@
             mockInputMonitorFactory,
             transactionFactory,
             mockAppHeaderViewHolderFactory,
+            mockAppHandleViewHolderFactory,
             mockRootTaskDisplayAreaOrganizer,
             windowDecorByTaskIdSpy,
             mockInteractionJankMonitor,
@@ -331,7 +334,7 @@
             mockDesktopModeWindowDecorFactory.create(
                 any(), any(), any(), any(), any(), any(), any(), eq(task), any(), any(), any(),
                 any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(),
-                any(), any(), any())
+                any(), any(), any(), any())
         ).thenReturn(decoration)
         decoration.mTaskInfo = task
         whenever(decoration.user).thenReturn(mockUserHandle)
@@ -353,12 +356,17 @@
         )
     }
 
-    protected fun onTaskChanging(task: RunningTaskInfo, leash: SurfaceControl = SurfaceControl()) {
+    protected fun onTaskChanging(
+        task: RunningTaskInfo,
+        leash: SurfaceControl = SurfaceControl(),
+        changeMode: Int
+    ) {
         desktopModeWindowDecorViewModel.onTaskChanging(
             task,
             leash,
             StubTransaction(),
-            StubTransaction()
+            StubTransaction(),
+            changeMode
         )
     }
 
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 8783249..f7b9c335 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
@@ -59,6 +59,7 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
 import android.content.res.TypedArray;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -115,6 +116,7 @@
 import com.android.wm.shell.windowdecor.common.WindowDecorTaskResourceLoader;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHost;
 import com.android.wm.shell.windowdecor.common.viewhost.WindowDecorViewHostSupplier;
+import com.android.wm.shell.windowdecor.viewholder.AppHandleViewHolder;
 import com.android.wm.shell.windowdecor.viewholder.AppHeaderViewHolder;
 
 import kotlin.Unit;
@@ -171,6 +173,9 @@
     private static final boolean DEFAULT_HAS_GLOBAL_FOCUS = true;
     private static final boolean DEFAULT_SHOULD_IGNORE_CORNER_RADIUS = false;
     private static final boolean DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS = false;
+    private static final boolean DEFAULT_IS_RECENTS_TRANSITION_RUNNING = false;
+    private static final boolean DEFAULT_IS_MOVING_TO_BACK = false;
+
 
     @Mock
     private DisplayController mMockDisplayController;
@@ -191,8 +196,12 @@
     @Mock
     private AppHeaderViewHolder.Factory mMockAppHeaderViewHolderFactory;
     @Mock
+    private AppHandleViewHolder.Factory mMockAppHandleViewHolderFactory;
+    @Mock
     private AppHeaderViewHolder mMockAppHeaderViewHolder;
     @Mock
+    private AppHandleViewHolder mMockAppHandleViewHolder;
+    @Mock
     private RootTaskDisplayAreaOrganizer mMockRootTaskDisplayAreaOrganizer;
     @Mock
     private Supplier<SurfaceControl.Transaction> mMockTransactionSupplier;
@@ -301,6 +310,9 @@
         when(mMockAppHeaderViewHolderFactory
                 .create(any(), any(), any(), any(), any(), any(), any(), any(), any()))
                 .thenReturn(mMockAppHeaderViewHolder);
+        when(mMockAppHandleViewHolderFactory
+                .create(any(), any(), any(), any(), any()))
+                .thenReturn(mMockAppHandleViewHolder);
         when(mMockDesktopUserRepositories.getCurrent()).thenReturn(mDesktopRepository);
         when(mMockDesktopUserRepositories.getProfile(anyInt())).thenReturn(mDesktopRepository);
         when(mMockWindowDecorViewHostSupplier.acquire(any(), eq(defaultDisplay)))
@@ -330,7 +342,8 @@
     }
 
     @Test
-    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreSetForFreeform() {
+    @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreSetForFreeform_dynamicDisabled() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
         RelayoutParams relayoutParams = new RelayoutParams();
@@ -342,7 +355,8 @@
     }
 
     @Test
-    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForFullscreen() {
+    @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForFullscreen_dynamicDisabled() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
         RelayoutParams relayoutParams = new RelayoutParams();
@@ -353,7 +367,8 @@
     }
 
     @Test
-    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForSplit() {
+    @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForSplit_dynamicDisabled() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         RelayoutParams relayoutParams = new RelayoutParams();
@@ -364,7 +379,8 @@
     }
 
     @Test
-    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersSetForFreeform() {
+    @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersSetForFreeform_dynamicDisabled() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
         fillRoundedCornersResources(/* fillValue= */ 30);
@@ -376,7 +392,8 @@
     }
 
     @Test
-    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForFullscreen() {
+    @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForFullscreen_dynamicDisabled() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
         fillRoundedCornersResources(/* fillValue= */ 30);
@@ -388,7 +405,8 @@
     }
 
     @Test
-    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForSplit() {
+    @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForSplit_dynamicDisabled() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
         fillRoundedCornersResources(/* fillValue= */ 30);
@@ -400,7 +418,8 @@
     }
 
     @Test
-    public void updateRelayoutParams_shouldIgnoreCornerRadius_roundedCornersNotSet() {
+    @DisableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_shouldIgnoreCornerRadius_roundedCornersNotSet_dynamicDisabled() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
         taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
         fillRoundedCornersResources(/* fillValue= */ 30);
@@ -421,12 +440,115 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 /* shouldIgnoreCornerRadius= */ true,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mCornerRadius).isEqualTo(INVALID_CORNER_RADIUS);
     }
 
     @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreSetForFreeform() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        RelayoutParams relayoutParams = new RelayoutParams();
+
+        updateRelayoutParams(relayoutParams, taskInfo);
+
+        assertThat(relayoutParams.mShadowRadiusId).isNotEqualTo(Resources.ID_NULL);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForFullscreen() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        RelayoutParams relayoutParams = new RelayoutParams();
+
+        updateRelayoutParams(relayoutParams, taskInfo);
+
+        assertThat(relayoutParams.mShadowRadiusId).isEqualTo(Resources.ID_NULL);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_windowShadowsAreNotSetForSplit() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        RelayoutParams relayoutParams = new RelayoutParams();
+
+        updateRelayoutParams(relayoutParams, taskInfo);
+
+        assertThat(relayoutParams.mShadowRadiusId).isEqualTo(Resources.ID_NULL);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersSetForFreeform() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        RelayoutParams relayoutParams = new RelayoutParams();
+
+        updateRelayoutParams(relayoutParams, taskInfo);
+
+        assertThat(relayoutParams.mShadowRadiusId).isNotEqualTo(Resources.ID_NULL);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForFullscreen() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        RelayoutParams relayoutParams = new RelayoutParams();
+
+        updateRelayoutParams(relayoutParams, taskInfo);
+
+        assertThat(relayoutParams.mCornerRadiusId).isEqualTo(Resources.ID_NULL);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_noSysPropFlagsSet_roundedCornersNotSetForSplit() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_MULTI_WINDOW);
+        RelayoutParams relayoutParams = new RelayoutParams();
+
+        updateRelayoutParams(relayoutParams, taskInfo);
+
+        assertThat(relayoutParams.mCornerRadiusId).isEqualTo(Resources.ID_NULL);
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX)
+    public void updateRelayoutParams_shouldIgnoreCornerRadius_roundedCornersNotSet() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+        RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                mMockSplitScreenController,
+                DEFAULT_APPLY_START_TRANSACTION_ON_DRAW,
+                DEFAULT_SHOULD_SET_TASK_POSITIONING_AND_CROP,
+                DEFAULT_IS_STATUSBAR_VISIBLE,
+                DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED,
+                DEFAULT_IS_IN_FULL_IMMERSIVE_MODE,
+                DEFAULT_IS_DRAGGING,
+                new InsetsState(),
+                DEFAULT_HAS_GLOBAL_FOCUS,
+                mExclusionRegion,
+                /* shouldIgnoreCornerRadius= */ true,
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
+
+        assertThat(relayoutParams.mCornerRadiusId).isEqualTo(Resources.ID_NULL);
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_ENABLE_APP_HEADER_WITH_TASK_DENSITY)
     public void updateRelayoutParams_appHeader_usesTaskDensity() {
         final int systemDensity = mTestableContext.getOrCreateTestableResources().getResources()
@@ -623,7 +745,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                /* shouldExcludeCaptionFromAppBounds */ true);
+                /* shouldExcludeCaptionFromAppBounds */ true,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         // Force consuming flags are disabled.
         assertThat((relayoutParams.mInsetSourceFlags & FLAG_FORCE_CONSUMING) == 0).isTrue();
@@ -658,7 +782,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat((relayoutParams.mInsetSourceFlags & FLAG_FORCE_CONSUMING) != 0).isTrue();
         assertThat(
@@ -737,7 +863,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         // Takes status bar inset as padding, ignores caption bar inset.
         assertThat(relayoutParams.mCaptionTopPadding).isEqualTo(50);
@@ -765,7 +893,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mIsInsetSource).isFalse();
     }
@@ -792,7 +922,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         // Header is always shown because it's assumed the status bar is always visible.
         assertThat(relayoutParams.mIsCaptionVisible).isTrue();
@@ -819,7 +951,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mIsCaptionVisible).isTrue();
     }
@@ -845,7 +979,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mIsCaptionVisible).isFalse();
     }
@@ -871,7 +1007,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mIsCaptionVisible).isFalse();
     }
@@ -898,7 +1036,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mIsCaptionVisible).isTrue();
 
@@ -917,7 +1057,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mIsCaptionVisible).isFalse();
     }
@@ -944,7 +1086,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mIsCaptionVisible).isTrue();
     }
@@ -971,7 +1115,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
 
         assertThat(relayoutParams.mIsCaptionVisible).isFalse();
     }
@@ -1002,6 +1148,65 @@
         assertThat(relayoutParams.mAsyncViewHost).isFalse();
     }
 
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX)
+    public void updateRelayoutParams_handle_movingToBack_captionNotVisible() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        final RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                mMockSplitScreenController,
+                DEFAULT_APPLY_START_TRANSACTION_ON_DRAW,
+                DEFAULT_SHOULD_SET_TASK_POSITIONING_AND_CROP,
+                DEFAULT_IS_STATUSBAR_VISIBLE,
+                DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED,
+                DEFAULT_IS_IN_FULL_IMMERSIVE_MODE,
+                DEFAULT_IS_DRAGGING,
+                new InsetsState(),
+                DEFAULT_HAS_GLOBAL_FOCUS,
+                mExclusionRegion,
+                DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                /* isMovingToBack= */ true);
+
+        assertThat(relayoutParams.mIsCaptionVisible).isFalse();
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_ENABLE_INPUT_LAYER_TRANSITION_FIX)
+    public void updateRelayoutParams_handle_inRecentsTransition_captionNotVisible() {
+        final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
+        taskInfo.configuration.windowConfiguration.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+        final RelayoutParams relayoutParams = new RelayoutParams();
+
+        DesktopModeWindowDecoration.updateRelayoutParams(
+                relayoutParams,
+                mTestableContext,
+                taskInfo,
+                mMockSplitScreenController,
+                DEFAULT_APPLY_START_TRANSACTION_ON_DRAW,
+                DEFAULT_SHOULD_SET_TASK_POSITIONING_AND_CROP,
+                DEFAULT_IS_STATUSBAR_VISIBLE,
+                DEFAULT_IS_KEYGUARD_VISIBLE_AND_OCCLUDED,
+                DEFAULT_IS_IN_FULL_IMMERSIVE_MODE,
+                DEFAULT_IS_DRAGGING,
+                new InsetsState(),
+                DEFAULT_HAS_GLOBAL_FOCUS,
+                mExclusionRegion,
+                DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                /* isRecentsTransitionRunning= */ true,
+                DEFAULT_IS_MOVING_TO_BACK);
+
+        assertThat(relayoutParams.mIsCaptionVisible).isFalse();
+    }
+
     @Test
     public void relayout_fullscreenTask_appliesTransactionImmediately() {
         final ActivityManager.RunningTaskInfo taskInfo = createTaskInfo(/* visible= */ true);
@@ -1633,7 +1838,9 @@
                 DEFAULT_HAS_GLOBAL_FOCUS,
                 mExclusionRegion,
                 DEFAULT_SHOULD_IGNORE_CORNER_RADIUS,
-                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS);
+                DEFAULT_SHOULD_EXCLUDE_CAPTION_FROM_APP_BOUNDS,
+                DEFAULT_IS_RECENTS_TRANSITION_RUNNING,
+                DEFAULT_IS_MOVING_TO_BACK);
     }
 
     private DesktopModeWindowDecoration createWindowDecoration(
@@ -1676,9 +1883,9 @@
                 taskInfo, mMockSurfaceControl, mMockHandler, mMainExecutor,
                 mMockMainCoroutineDispatcher, mMockBgCoroutineScope, mBgExecutor,
                 mMockChoreographer, mMockSyncQueue, mMockAppHeaderViewHolderFactory,
-                mMockRootTaskDisplayAreaOrganizer, mMockGenericLinksParser,
-                mMockAssistContentRequester, SurfaceControl.Builder::new, mMockTransactionSupplier,
-                WindowContainerTransaction::new, SurfaceControl::new,
+                mMockAppHandleViewHolderFactory, mMockRootTaskDisplayAreaOrganizer,
+                mMockGenericLinksParser, mMockAssistContentRequester, SurfaceControl.Builder::new,
+                mMockTransactionSupplier, WindowContainerTransaction::new, SurfaceControl::new,
                 new WindowManagerWrapper(mMockWindowManager), mMockSurfaceControlViewHostFactory,
                 mMockWindowDecorViewHostSupplier, maximizeMenuFactory, mMockHandleMenuFactory,
                 mMockMultiInstanceHelper, mMockCaptionHandleRepository, mDesktopModeEventLogger,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt
index 7341e09..3600997 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/DragResizeInputListenerTest.kt
@@ -40,11 +40,13 @@
 import com.google.common.truth.Truth.assertThat
 import java.util.function.Consumer
 import java.util.function.Supplier
+import org.junit.After
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.any
 import org.mockito.ArgumentMatchers.anyInt
 import org.mockito.kotlin.anyOrNull
+import org.mockito.kotlin.argThat
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
 import org.mockito.kotlin.verify
@@ -63,6 +65,15 @@
     private val testBgExecutor = TestShellExecutor()
     private val mockWindowSession = mock<IWindowSession>()
     private val mockInputEventReceiver = mock<TaskResizeInputEventReceiver>()
+    private val inputChannel = mock<InputChannel>()
+    private val sinkInputChannel = mock<InputChannel>()
+    private val decorationSurface = SurfaceControl.Builder().setName("decoration surface").build()
+    private val createdSurfaces = ArrayList<SurfaceControl>()
+
+    @After
+    fun tearDown() {
+        decorationSurface.release()
+    }
 
     @Test
     fun testGrantInputChannelOffMainThread() {
@@ -73,6 +84,35 @@
     }
 
     @Test
+    fun testGrantInputChannelAfterDecorSurfaceReleased() {
+        // Keep tracking the underlying surface that the decorationSurface points to.
+        val forVerification = SurfaceControl(decorationSurface, "forVerification")
+        try {
+            create()
+            decorationSurface.release()
+            testBgExecutor.flushAll()
+
+            verify(mockWindowSession)
+                .grantInputChannel(
+                    anyInt(),
+                    argThat<SurfaceControl> { isValid && isSameSurface(forVerification) },
+                    any(),
+                    anyOrNull(),
+                    anyInt(),
+                    anyInt(),
+                    anyInt(),
+                    anyInt(),
+                    anyOrNull(),
+                    any(),
+                    any(),
+                    any(),
+                )
+        } finally {
+            forVerification.release()
+        }
+    }
+
+    @Test
     fun testInitializationCallback_waitsForBgSetup() {
         val inputListener = create()
 
@@ -143,6 +183,40 @@
         verify(mockWindowSession).remove(inputListener.mSinkClientToken)
     }
 
+    @Test
+    fun testClose_afterBgSetup_disposesOfInputChannels() {
+        val inputListener = create()
+        testBgExecutor.flushAll()
+        inputListener.close()
+        testMainExecutor.flushAll()
+        verify(inputChannel).dispose()
+        verify(sinkInputChannel).dispose()
+    }
+
+    @Test
+    fun testClose_beforeBgSetup_releaseSurfaces() {
+        val inputListener = create()
+        inputListener.close()
+        testBgExecutor.flushAll()
+        testMainExecutor.flushAll()
+
+        assertThat(createdSurfaces).hasSize(1)
+        assertThat(createdSurfaces[0].isValid).isFalse()
+    }
+
+    @Test
+    fun testClose_afterBgSetup_releaseSurfaces() {
+        val inputListener = create()
+        testBgExecutor.flushAll()
+        inputListener.close()
+        testMainExecutor.flushAll()
+        testBgExecutor.flushAll()
+
+        assertThat(createdSurfaces).hasSize(2)
+        assertThat(createdSurfaces[0].isValid).isFalse()
+        assertThat(createdSurfaces[1].isValid).isFalse()
+    }
+
     private fun verifyNoInputChannelGrantRequests() {
         verify(mockWindowSession, never())
             .grantInputChannel(
@@ -172,12 +246,26 @@
             TestHandler(Looper.getMainLooper()),
             mock<Choreographer>(),
             Display.DEFAULT_DISPLAY,
-            mock<SurfaceControl>(),
+            decorationSurface,
             mock<DragPositioningCallback>(),
-            { SurfaceControl.Builder() },
-            { StubTransaction() },
+            {
+                object : SurfaceControl.Builder() {
+                    override fun build(): SurfaceControl {
+                        return super.build().also { createdSurfaces.add(it) }
+                    }
+                }
+            },
+            {
+                object : StubTransaction() {
+                    override fun remove(sc: SurfaceControl): SurfaceControl.Transaction {
+                        return super.remove(sc).also { sc.release() }
+                    }
+                }
+            },
             mock<DisplayController>(),
             mock<DesktopModeEventLogger>(),
+            inputChannel,
+            sinkInputChannel,
         )
 
     private class TestInitializationCallback : Runnable {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt
index a6b0770..24a46aa 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/MultiDisplayVeiledResizeTaskPositionerTest.kt
@@ -63,6 +63,7 @@
 import org.mockito.Mockito.never
 import org.mockito.Mockito.times
 import org.mockito.Mockito.verify
+import org.mockito.Mockito.verifyNoInteractions
 import org.mockito.Mockito.`when`
 import org.mockito.Mockito.`when` as whenever
 import org.mockito.MockitoAnnotations
@@ -210,6 +211,7 @@
                 eq(taskPositioner),
             )
         verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
+        verifyNoInteractions(mockMultiDisplayDragMoveIndicatorController)
     }
 
     @Test
@@ -248,6 +250,7 @@
 
         verify(mockDesktopWindowDecoration, never()).showResizeVeil(any())
         verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
+        verify(mockMultiDisplayDragMoveIndicatorController).onDragEnd(eq(TASK_ID), any())
         Assert.assertEquals(rectAfterEnd, endBounds)
     }
 
@@ -268,6 +271,7 @@
 
         verify(spyDisplayLayout0, never()).localPxToGlobalDp(any(), any())
         verify(spyDisplayLayout0, never()).globalDpToLocalPx(any(), any())
+        verify(mockMultiDisplayDragMoveIndicatorController).onDragEnd(eq(TASK_ID), any())
     }
 
     @Test
@@ -290,6 +294,7 @@
 
         verify(mockDesktopWindowDecoration, never()).showResizeVeil(any())
         verify(mockDesktopWindowDecoration, never()).hideResizeVeil()
+        verify(mockMultiDisplayDragMoveIndicatorController).onDragEnd(eq(TASK_ID), any())
         Assert.assertEquals(rectAfterEnd, endBounds)
     }
 
@@ -346,6 +351,7 @@
                 },
                 eq(taskPositioner),
             )
+        verifyNoInteractions(mockMultiDisplayDragMoveIndicatorController)
     }
 
     @Test
@@ -559,6 +565,17 @@
     }
 
     @Test
+    fun testClose() = runOnUiThread {
+        verify(mockDisplayController, times(1))
+            .addDisplayWindowListener(eq(taskPositioner))
+
+        taskPositioner.close()
+
+        verify(mockDisplayController, times(1))
+            .removeDisplayWindowListener(eq(taskPositioner))
+    }
+
+    @Test
     fun testIsResizingOrAnimatingResizeSet() = runOnUiThread {
         Assert.assertFalse(taskPositioner.isResizingOrAnimating)
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
index fa3d3e4..011c8f0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/ResizeVeilTest.kt
@@ -52,7 +52,7 @@
 import org.mockito.kotlin.never
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
-import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.verifyNoMoreInteractions
 import org.mockito.kotlin.whenever
 
 
@@ -216,7 +216,7 @@
 
         veil.hideVeil()
 
-        verifyZeroInteractions(mockTransaction)
+        verifyNoMoreInteractions(mockTransaction)
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
index 9a2e2fa..c691dc7 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/WindowDecorationTests.java
@@ -61,7 +61,8 @@
 import android.graphics.Region;
 import android.os.Handler;
 import android.os.LocaleList;
-import android.testing.AndroidTestingRunner;
+import android.platform.test.annotations.UsesFlags;
+import android.platform.test.flag.junit.FlagsParameterization;
 import android.util.DisplayMetrics;
 import android.view.AttachedSurfaceControl;
 import android.view.Display;
@@ -78,6 +79,7 @@
 
 import androidx.test.filters.SmallTest;
 
+import com.android.window.flags.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
 import com.android.wm.shell.ShellTestCase;
 import com.android.wm.shell.TestRunningTaskInfoBuilder;
@@ -96,6 +98,9 @@
 import org.mockito.Mock;
 import org.mockito.Mockito;
 
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4;
+import platform.test.runner.parameterized.Parameters;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Locale;
@@ -108,7 +113,8 @@
  * atest WMShellUnitTests:WindowDecorationTests
  */
 @SmallTest
-@RunWith(AndroidTestingRunner.class)
+@RunWith(ParameterizedAndroidJunit4.class)
+@UsesFlags(com.android.window.flags.Flags.class)
 public class WindowDecorationTests extends ShellTestCase {
     private static final Rect TASK_BOUNDS = new Rect(100, 300, 400, 400);
     private static final Point TASK_POSITION_IN_PARENT = new Point(40, 60);
@@ -116,6 +122,12 @@
     private static final int SHADOW_RADIUS = 10;
     private static final int STATUS_BAR_INSET_SOURCE_ID = 0;
 
+    @Parameters(name = "{0}")
+    public static List<FlagsParameterization> getParams() {
+        return FlagsParameterization.allCombinationsOf(
+                Flags.FLAG_ENABLE_DYNAMIC_RADIUS_COMPUTATION_BUGFIX);
+    }
+
     private final WindowDecoration.RelayoutResult<TestView> mRelayoutResult =
             new WindowDecoration.RelayoutResult<>();
 
@@ -156,6 +168,10 @@
     private WindowDecoration.RelayoutParams mRelayoutParams = new WindowDecoration.RelayoutParams();
     private int mCaptionMenuWidthId;
 
+    public WindowDecorationTests(FlagsParameterization flags) {
+        mSetFlagsRule.setFlagsParameterization(flags);
+    }
+
     @Before
     public void setUp() {
         mMockSurfaceControlStartT = createMockSurfaceControlTransaction();
@@ -165,8 +181,13 @@
         mRelayoutParams.mLayoutResId = 0;
         mRelayoutParams.mCaptionHeightId = R.dimen.test_freeform_decor_caption_height;
         mCaptionMenuWidthId = R.dimen.test_freeform_decor_caption_menu_width;
-        mRelayoutParams.mShadowRadius = SHADOW_RADIUS;
-        mRelayoutParams.mCornerRadius = CORNER_RADIUS;
+        if (Flags.enableDynamicRadiusComputationBugfix()) {
+            mRelayoutParams.mShadowRadiusId = R.dimen.test_freeform_shadow_radius;
+            mRelayoutParams.mCornerRadiusId = R.dimen.test_freeform_corner_radius;
+        } else {
+            mRelayoutParams.mShadowRadius = SHADOW_RADIUS;
+            mRelayoutParams.mCornerRadius = CORNER_RADIUS;
+        }
 
         when(mMockDisplayController.getDisplay(Display.DEFAULT_DISPLAY))
                 .thenReturn(mock(Display.class));
@@ -282,9 +303,21 @@
                 any(),
                 anyInt());
 
-        verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
-        verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
-        verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, SHADOW_RADIUS);
+        if (Flags.enableDynamicRadiusComputationBugfix()) {
+            final int cornerRadius = WindowDecoration.loadDimensionPixelSize(
+                    windowDecor.mDecorWindowContext.getResources(),
+                    mRelayoutParams.mCornerRadiusId);
+            verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, cornerRadius);
+            verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, cornerRadius);
+            final int shadowRadius = WindowDecoration.loadDimensionPixelSize(
+                    windowDecor.mDecorWindowContext.getResources(),
+                    mRelayoutParams.mShadowRadiusId);
+            verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, shadowRadius);
+        } else {
+            verify(mMockSurfaceControlStartT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
+            verify(mMockSurfaceControlFinishT).setCornerRadius(mMockTaskSurface, CORNER_RADIUS);
+            verify(mMockSurfaceControlStartT).setShadowRadius(mMockTaskSurface, SHADOW_RADIUS);
+        }
 
         assertEquals(300, mRelayoutResult.mWidth);
         assertEquals(100, mRelayoutResult.mHeight);
@@ -826,6 +859,18 @@
     }
 
     @Test
+    public void testClose_withTaskDragResizerSet_callResizerClose() {
+        final TestWindowDecoration windowDecor = createWindowDecoration(
+                new TestRunningTaskInfoBuilder().build());
+        final TaskDragResizer taskDragResizer = mock(TaskDragResizer.class);
+        windowDecor.setTaskDragResizer(taskDragResizer);
+
+        windowDecor.close();
+
+        verify(taskDragResizer).close();
+    }
+
+    @Test
     public void testRelayout_captionFrameChanged_insetsReapplied() {
         final Display defaultDisplay = mock(Display.class);
         doReturn(defaultDisplay).when(mMockDisplayController)
@@ -1186,7 +1231,8 @@
         }
 
         @Override
-        public void setTaskFocusState(boolean focused) {}
+        public void setTaskFocusState(boolean focused) {
+        }
     }
 
     private class TestWindowDecoration extends WindowDecoration<TestView> {
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoaderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoaderTest.kt
index c8ccac3..714d062 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoaderTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/common/WindowDecorTaskResourceLoaderTest.kt
@@ -54,7 +54,7 @@
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.spy
 import org.mockito.kotlin.verify
-import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.verifyNoMoreInteractions
 import org.mockito.kotlin.whenever
 
 /**
@@ -125,7 +125,7 @@
 
         loader.getName(task)
 
-        verifyZeroInteractions(
+        verifyNoMoreInteractions(
             mockPackageManager,
             mockIconProvider,
             mockHeaderIconFactory,
@@ -165,7 +165,7 @@
 
         loader.getHeaderIcon(task)
 
-        verifyZeroInteractions(mockPackageManager, mockIconProvider, mockHeaderIconFactory)
+        verifyNoMoreInteractions(mockPackageManager, mockIconProvider, mockHeaderIconFactory)
     }
 
     @Test
@@ -187,7 +187,7 @@
 
         loader.getVeilIcon(task)
 
-        verifyZeroInteractions(mockPackageManager, mockIconProvider, mockVeilIconFactory)
+        verifyNoMoreInteractions(mockPackageManager, mockIconProvider, mockVeilIconFactory)
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
index 646ec21..9e148e5 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingDecorViewModelTest.kt
@@ -28,6 +28,7 @@
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.common.SyncTransactionQueue
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger
+import com.android.wm.shell.desktopmode.DesktopRepository
 import com.android.wm.shell.desktopmode.DesktopTasksController
 import com.android.wm.shell.desktopmode.DesktopTestHelpers.createFreeformTask
 import com.android.wm.shell.desktopmode.DesktopUserRepositories
@@ -63,6 +64,7 @@
     private val transitionsMock: Transitions = mock()
     private val shellTaskOrganizerMock: ShellTaskOrganizer = mock()
     private val userRepositories: DesktopUserRepositories = mock()
+    private val desktopRepository: DesktopRepository = mock()
     private val desktopModeEventLogger: DesktopModeEventLogger = mock()
     private val toggleResizeDesktopTaskTransitionHandlerMock:
         ToggleResizeDesktopTaskTransitionHandler =
@@ -105,6 +107,7 @@
         whenever(contextMock.createContextAsUser(any(), any())).thenReturn(context)
         whenever(contextMock.resources).thenReturn(resourcesMock)
         whenever(resourcesMock.getDimensionPixelSize(any())).thenReturn(10)
+        whenever(userRepositories.current).thenReturn(desktopRepository)
     }
 
     @Test
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
index e4424f3..e5f8d7d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/tiling/DesktopTilingWindowDecorationTest.kt
@@ -653,6 +653,64 @@
         verify(context, never()).getApplicationContext()
     }
 
+    @Test
+    fun addLeftTiledTask_updatesTaskRepository_whenLeftTileInitializedOrBroken() {
+        val task1 = createVisibleTask()
+        val stableBounds = STABLE_BOUNDS_MOCK
+        whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
+        whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
+            (i.arguments.first() as Rect).set(stableBounds)
+        }
+        whenever(context.resources).thenReturn(resources)
+        whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width)
+        whenever(tiledTaskHelper.taskInfo).thenReturn(task1)
+        whenever(tiledTaskHelper.desktopModeWindowDecoration).thenReturn(desktopWindowDecoration)
+
+        tilingDecoration.onAppTiled(
+            task1,
+            desktopWindowDecoration,
+            DesktopTasksController.SnapPosition.LEFT,
+            BOUNDS,
+        )
+
+        verify(desktopRepository, times(1)).addLeftTiledTask(displayId, task1.taskId)
+        verify(desktopRepository, never()).addRightTiledTask(displayId, task1.taskId)
+
+        tilingDecoration.removeTaskIfTiled(task1.taskId)
+
+        verify(desktopRepository, times(1)).removeLeftTiledTask(displayId)
+        verify(desktopRepository, never()).removeRightTiledTask(displayId)
+    }
+
+    @Test
+    fun addRightTiledTask_updatesTaskRepository_whenRightTileInitializedOrBroken() {
+        val task1 = createVisibleTask()
+        val stableBounds = STABLE_BOUNDS_MOCK
+        whenever(displayController.getDisplayLayout(any())).thenReturn(displayLayout)
+        whenever(displayLayout.getStableBounds(any())).thenAnswer { i ->
+            (i.arguments.first() as Rect).set(stableBounds)
+        }
+        whenever(context.resources).thenReturn(resources)
+        whenever(resources.getDimensionPixelSize(any())).thenReturn(split_divider_width)
+        whenever(tiledTaskHelper.taskInfo).thenReturn(task1)
+        whenever(tiledTaskHelper.desktopModeWindowDecoration).thenReturn(desktopWindowDecoration)
+
+        tilingDecoration.onAppTiled(
+            task1,
+            desktopWindowDecoration,
+            DesktopTasksController.SnapPosition.RIGHT,
+            BOUNDS,
+        )
+
+        verify(desktopRepository, times(1)).addRightTiledTask(displayId, task1.taskId)
+        verify(desktopRepository, never()).addLeftTiledTask(displayId, task1.taskId)
+
+        tilingDecoration.removeTaskIfTiled(task1.taskId)
+
+        verify(desktopRepository, times(1)).removeRightTiledTask(displayId)
+        verify(desktopRepository, never()).removeLeftTiledTask(displayId)
+    }
+
     private fun initTiledTaskHelperMock(taskInfo: ActivityManager.RunningTaskInfo) {
         whenever(tiledTaskHelper.bounds).thenReturn(BOUNDS)
         whenever(tiledTaskHelper.taskInfo).thenReturn(taskInfo)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt
new file mode 100644
index 0000000..bc4865a
--- /dev/null
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/windowdecor/viewholder/AppHandleViewHolderTest.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.graphics.Point
+import android.os.Handler
+import android.testing.AndroidTestingRunner
+import android.view.View
+import android.widget.ImageButton
+import androidx.test.filters.SmallTest
+import com.android.internal.policy.SystemBarUtils
+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.runner.RunWith
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.spy
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+import kotlin.test.Test
+
+/**
+ * Tests for [AppHandleViewHolder].
+ *
+ * Build/Install/Run:
+ * atest WMShellUnitTests:AppHandleViewHolderTest
+ */
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class AppHandleViewHolderTest : ShellTestCase() {
+
+    companion object {
+        private const val CAPTION_WIDTH = 500
+        private const val CAPTION_HEIGHT = 100
+    }
+
+    private val mockView = mock<View>()
+    private val mockImageButton = mock<ImageButton>()
+    private val mockOnTouchListener = mock<View.OnTouchListener>()
+    private val mockOnClickListener = mock<View.OnClickListener>()
+    private val mockWindowManagerWrapper = mock<WindowManagerWrapper>()
+    private val mockHandler = mock<Handler>()
+    private val mockTaskInfo = mock<RunningTaskInfo>()
+
+    @Before
+    fun setup() {
+        whenever(mockView.context).thenReturn(mContext)
+        whenever(mockView.requireViewById<View>(R.id.desktop_mode_caption))
+            .thenReturn(mockView)
+        whenever(mockView.requireViewById<ImageButton>(R.id.caption_handle))
+            .thenReturn(mockImageButton)
+    }
+
+    @Test
+    fun statusBarInputLayer_disposedWhenCaptionBelowStatusBar() {
+        val appHandleViewHolder: AppHandleViewHolder = spy(createAppHandleViewHolder())
+        val captionPosition = Point(0, SystemBarUtils.getStatusBarHeight(mContext) + 10)
+
+        appHandleViewHolder.bindData(
+            AppHandleViewHolder.HandleData(
+                taskInfo = mockTaskInfo,
+                position = captionPosition,
+                width = CAPTION_WIDTH,
+                height = CAPTION_HEIGHT,
+                showInputLayer = false
+            )
+        )
+
+        verify(appHandleViewHolder).disposeStatusBarInputLayer()
+    }
+
+    private fun createAppHandleViewHolder(): AppHandleViewHolder {
+        return AppHandleViewHolder(
+            mockView,
+            mockOnTouchListener,
+            mockOnClickListener,
+            mockWindowManagerWrapper,
+            mockHandler
+        )
+    }
+}
diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp
index 5a4cff0..4e820b6 100644
--- a/libs/androidfw/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -453,7 +453,7 @@
 {
     assert(mFp == NULL);    // no reopen
     assert(!mMap.has_value());
-    assert(dataMap != NULL);
+    assert(dataMap.data());
 
     mMap = std::move(dataMap);
     mStart = -1;            // not used
@@ -798,7 +798,7 @@
 {
     assert(mFd < 0);        // no re-open
     assert(!mMap.has_value());
-    assert(dataMap != NULL);
+    assert(dataMap.data());
 
     mMap = std::move(dataMap);
     mStart = -1;        // not used
diff --git a/libs/hostgraphics/include/gui/BufferItemConsumer.h b/libs/hostgraphics/include/gui/BufferItemConsumer.h
index 5c96c82..b9ff0a77 100644
--- a/libs/hostgraphics/include/gui/BufferItemConsumer.h
+++ b/libs/hostgraphics/include/gui/BufferItemConsumer.h
@@ -48,6 +48,10 @@
         return mConsumer->acquireBuffer(item, presentWhen, 0);
     }
 
+    status_t attachBuffer(BufferItem*, const sp<GraphicBuffer>&) {
+        return INVALID_OPERATION;
+    }
+
     status_t releaseBuffer(const BufferItem& item,
                            const sp<Fence>& releaseFence = Fence::NO_FENCE) {
         return OK;
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index a892e88..ab1be7e 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -139,6 +139,7 @@
                 "libandroidfw",
                 "libcrypto",
                 "libsync",
+                "libgui",
                 "libui",
                 "aconfig_text_flags_c_lib",
                 "aconfig_view_accessibility_flags_c_lib",
diff --git a/libs/hwui/WebViewFunctorManager.cpp b/libs/hwui/WebViewFunctorManager.cpp
index 9d16ee8..7e1eb70 100644
--- a/libs/hwui/WebViewFunctorManager.cpp
+++ b/libs/hwui/WebViewFunctorManager.cpp
@@ -16,6 +16,7 @@
 
 #include "WebViewFunctorManager.h"
 
+#include <gui/SurfaceComposerClient.h>
 #include <log/log.h>
 #include <private/hwui/WebViewFunctor.h>
 #include <utils/Trace.h>
@@ -43,7 +44,7 @@
 
     static ASurfaceControl* getSurfaceControl() {
         ALOG_ASSERT(sCurrentFunctor);
-        return sCurrentFunctor->getSurfaceControl();
+        return reinterpret_cast<ASurfaceControl*>(sCurrentFunctor->getSurfaceControl());
     }
     static void mergeTransaction(ASurfaceTransaction* transaction) {
         ALOG_ASSERT(sCurrentFunctor);
@@ -129,12 +130,12 @@
     renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
     if (!activeContext) return false;
 
-    ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
+    sp<SurfaceControl> rootSurfaceControl = activeContext->getSurfaceControl();
     if (!rootSurfaceControl) return false;
 
     int32_t rgid = activeContext->getSurfaceControlGenerationId();
     if (mParentSurfaceControlGenerationId != rgid) {
-        reparentSurfaceControl(rootSurfaceControl);
+        reparentSurfaceControl(reinterpret_cast<ASurfaceControl*>(rootSurfaceControl.get()));
         mParentSurfaceControlGenerationId = rgid;
     }
 
@@ -210,33 +211,35 @@
     mCallbacks.removeOverlays(mFunctor, mData, currentFunctor.mergeTransaction);
     if (mSurfaceControl) {
         reparentSurfaceControl(nullptr);
-        auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
-        funcs.releaseFunc(mSurfaceControl);
         mSurfaceControl = nullptr;
     }
 }
 
 ASurfaceControl* WebViewFunctor::getSurfaceControl() {
     ATRACE_NAME("WebViewFunctor::getSurfaceControl");
-    if (mSurfaceControl != nullptr) return mSurfaceControl;
+    if (mSurfaceControl != nullptr) {
+        return reinterpret_cast<ASurfaceControl*>(mSurfaceControl.get());
+    }
 
     renderthread::CanvasContext* activeContext = renderthread::CanvasContext::getActiveContext();
     LOG_ALWAYS_FATAL_IF(activeContext == nullptr, "Null active canvas context!");
 
-    ASurfaceControl* rootSurfaceControl = activeContext->getSurfaceControl();
+    sp<SurfaceControl> rootSurfaceControl = activeContext->getSurfaceControl();
     LOG_ALWAYS_FATAL_IF(rootSurfaceControl == nullptr, "Null root surface control!");
 
-    auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
     mParentSurfaceControlGenerationId = activeContext->getSurfaceControlGenerationId();
-    mSurfaceControl = funcs.createFunc(rootSurfaceControl, "Webview Overlay SurfaceControl");
-    ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
+
+    SurfaceComposerClient* client = rootSurfaceControl->getClient().get();
+    mSurfaceControl = client->createSurface(
+            String8("Webview Overlay SurfaceControl"), 0 /* width */, 0 /* height */,
+            // Format is only relevant for buffer queue layers.
+            PIXEL_FORMAT_UNKNOWN /* format */, ISurfaceComposerClient::eFXSurfaceBufferState,
+            rootSurfaceControl->getHandle());
+
     activeContext->prepareSurfaceControlForWebview();
-    funcs.transactionSetZOrderFunc(transaction, mSurfaceControl, -1);
-    funcs.transactionSetVisibilityFunc(transaction, mSurfaceControl,
-                                       ASURFACE_TRANSACTION_VISIBILITY_SHOW);
-    funcs.transactionApplyFunc(transaction);
-    funcs.transactionDeleteFunc(transaction);
-    return mSurfaceControl;
+    SurfaceComposerClient::Transaction transaction;
+    transaction.setLayer(mSurfaceControl, -1).show(mSurfaceControl).apply();
+    return reinterpret_cast<ASurfaceControl*>(mSurfaceControl.get());
 }
 
 void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {
@@ -249,8 +252,7 @@
         done = activeContext->mergeTransaction(transaction, mSurfaceControl);
     }
     if (!done) {
-        auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
-        funcs.transactionApplyFunc(transaction);
+        reinterpret_cast<SurfaceComposerClient::Transaction*>(transaction)->apply();
     }
 }
 
@@ -258,11 +260,10 @@
     ATRACE_NAME("WebViewFunctor::reparentSurfaceControl");
     if (mSurfaceControl == nullptr) return;
 
-    auto funcs = renderthread::RenderThread::getInstance().getASurfaceControlFunctions();
-    ASurfaceTransaction* transaction = funcs.transactionCreateFunc();
-    funcs.transactionReparentFunc(transaction, mSurfaceControl, parent);
-    mergeTransaction(transaction);
-    funcs.transactionDeleteFunc(transaction);
+    SurfaceComposerClient::Transaction transaction;
+    transaction.reparent(mSurfaceControl, sp<SurfaceControl>::fromExisting(
+                                                  reinterpret_cast<SurfaceControl*>(parent)));
+    mergeTransaction(reinterpret_cast<ASurfaceTransaction*>(&transaction));
 }
 
 void WebViewFunctor::reportRenderingThreads(const pid_t* thread_ids, size_t size) {
diff --git a/libs/hwui/WebViewFunctorManager.h b/libs/hwui/WebViewFunctorManager.h
index ec17640..ac16f91 100644
--- a/libs/hwui/WebViewFunctorManager.h
+++ b/libs/hwui/WebViewFunctorManager.h
@@ -25,7 +25,11 @@
 #include <mutex>
 #include <vector>
 
-namespace android::uirenderer {
+namespace android {
+
+class SurfaceControl;
+
+namespace uirenderer {
 
 class WebViewFunctorManager;
 
@@ -100,7 +104,9 @@
     bool mHasContext = false;
     bool mCreatedHandle = false;
     int32_t mParentSurfaceControlGenerationId = 0;
-    ASurfaceControl* mSurfaceControl = nullptr;
+#ifdef __ANDROID__
+    sp<SurfaceControl> mSurfaceControl = nullptr;
+#endif
     std::vector<pid_t> mRenderingThreads;
 };
 
@@ -126,4 +132,5 @@
     std::vector<sp<WebViewFunctor::Handle>> mActiveFunctors;
 };
 
-}  // namespace android::uirenderer
+}  // namespace uirenderer
+}  // namespace android
diff --git a/libs/hwui/aconfig/hwui_flags.aconfig b/libs/hwui/aconfig/hwui_flags.aconfig
index d3fc91b..b3badd0 100644
--- a/libs/hwui/aconfig/hwui_flags.aconfig
+++ b/libs/hwui/aconfig/hwui_flags.aconfig
@@ -203,4 +203,11 @@
   description: "Initialize GraphicBufferAllocater on ViewRootImpl init, to avoid blocking on init during buffer allocation, improving app launch latency."
   bug: "389908734"
   is_fixed_read_only: true
+}
+
+flag {
+  name: "bitmap_parcel_ashmem_as_immutable"
+  namespace: "system_performance"
+  description: "Whether to parcel implicit copies of bitmaps to ashmem as immutable"
+  bug: "400807118"
 }
\ No newline at end of file
diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp
index 27d4ac7..104ece6 100644
--- a/libs/hwui/jni/Bitmap.cpp
+++ b/libs/hwui/jni/Bitmap.cpp
@@ -28,8 +28,18 @@
 #include "SkRefCnt.h"
 #include "SkStream.h"
 #include "SkTypes.h"
+#include "android/binder_parcel.h"
 #include "android_nio_utils.h"
 
+#ifdef __ANDROID__
+#include <com_android_graphics_hwui_flags.h>
+namespace hwui_flags = com::android::graphics::hwui::flags;
+#else
+namespace hwui_flags {
+constexpr bool bitmap_parcel_ashmem_as_immutable() { return false; }
+}
+#endif
+
 #define DEBUG_PARCEL 0
 
 static jclass   gBitmap_class;
@@ -841,6 +851,23 @@
 #endif
 }
 
+// Returns whether this bitmap should be written to the parcel as mutable.
+static bool shouldParcelAsMutable(SkBitmap& bitmap, AParcel* parcel) {
+    // If the bitmap is immutable, then parcel as immutable.
+    if (bitmap.isImmutable()) {
+        return false;
+    }
+
+    if (!hwui_flags::bitmap_parcel_ashmem_as_immutable()) {
+        return true;
+    }
+
+    // If we're going to copy the bitmap to ashmem and write that to the parcel,
+    // then parcel as immutable, since we won't be mutating the bitmap after
+    // writing it to the parcel.
+    return !shouldUseAshmem(parcel, bitmap.computeByteSize());
+}
+
 static jboolean Bitmap_writeToParcel(JNIEnv* env, jobject, jlong bitmapHandle, jint density,
                                      jobject parcel) {
 #ifdef __linux__ // Only Linux support parcel
@@ -855,7 +882,7 @@
     auto bitmapWrapper = reinterpret_cast<BitmapWrapper*>(bitmapHandle);
     bitmapWrapper->getSkBitmap(&bitmap);
 
-    p.writeInt32(!bitmap.isImmutable());
+    p.writeInt32(shouldParcelAsMutable(bitmap, p.get()));
     p.writeInt32(bitmap.colorType());
     p.writeInt32(bitmap.alphaType());
     SkColorSpace* colorSpace = bitmap.colorSpace();
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index cfec24b..009974b 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -53,6 +53,7 @@
 #include <src/image/SkImage_Base.h>
 #include <thread/CommonPool.h>
 #ifdef __ANDROID__
+#include <gui/SurfaceControl.h>
 #include <ui/GraphicBufferAllocator.h>
 #endif
 #include <utils/Color.h>
@@ -217,9 +218,11 @@
 
 static void android_view_ThreadedRenderer_setSurfaceControl(JNIEnv* env, jobject clazz,
         jlong proxyPtr, jlong surfaceControlPtr) {
+#ifdef __ANDROID__
     RenderProxy* proxy = reinterpret_cast<RenderProxy*>(proxyPtr);
-    ASurfaceControl* surfaceControl = reinterpret_cast<ASurfaceControl*>(surfaceControlPtr);
-    proxy->setSurfaceControl(surfaceControl);
+    SurfaceControl* surfaceControl = reinterpret_cast<SurfaceControl*>(surfaceControlPtr);
+    proxy->setSurfaceControl(sp<SurfaceControl>::fromExisting(surfaceControl));
+#endif
 }
 
 static jboolean android_view_ThreadedRenderer_pause(JNIEnv* env, jobject clazz,
@@ -684,7 +687,7 @@
 
 class CopyRequestAdapter : public CopyRequest {
 public:
-    CopyRequestAdapter(JavaVM* vm, jobject jCopyRequest, Rect srcRect)
+    CopyRequestAdapter(JavaVM* vm, jobject jCopyRequest, ::android::uirenderer::Rect srcRect)
             : CopyRequest(srcRect), mRefHolder(vm, jCopyRequest) {}
 
     virtual SkBitmap getDestinationBitmap(int srcWidth, int srcHeight) override {
@@ -710,8 +713,9 @@
                                                           jobject jCopyRequest) {
     JavaVM* vm = nullptr;
     LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM");
-    auto copyRequest = std::make_shared<CopyRequestAdapter>(vm, env->NewGlobalRef(jCopyRequest),
-                                                            Rect(left, top, right, bottom));
+    auto copyRequest = std::make_shared<CopyRequestAdapter>(
+            vm, env->NewGlobalRef(jCopyRequest),
+            ::android::uirenderer::Rect(left, top, right, bottom));
     ANativeWindow* window = fromSurface(env, jsurface);
     RenderProxy::copySurfaceInto(window, std::move(copyRequest));
     ANativeWindow_release(window);
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index dc669a5..aa8cbd1 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -175,6 +175,8 @@
     if (stream->isValid()) {
         mOpenMultiPicStream = std::move(stream);
         mSerialContext.reset(new SkSharingSerialContext());
+        // passing the GrDirectContext to the SerialContext allows us to raster/serialize GPU images
+        mSerialContext->setDirectContext(mRenderThread.getGrContext());
         SkSerialProcs procs;
         procs.fImageProc = SkSharingSerialContext::serializeImage;
         procs.fImageCtx = mSerialContext.get();
diff --git a/libs/hwui/platform/host/WebViewFunctorManager.cpp b/libs/hwui/platform/host/WebViewFunctorManager.cpp
index 4ba206b..66646b2 100644
--- a/libs/hwui/platform/host/WebViewFunctorManager.cpp
+++ b/libs/hwui/platform/host/WebViewFunctorManager.cpp
@@ -45,7 +45,7 @@
 void WebViewFunctor::removeOverlays() {}
 
 ASurfaceControl* WebViewFunctor::getSurfaceControl() {
-    return mSurfaceControl;
+    return nullptr;
 }
 
 void WebViewFunctor::mergeTransaction(ASurfaceTransaction* transaction) {}
diff --git a/libs/hwui/platform/host/renderthread/RenderThread.cpp b/libs/hwui/platform/host/renderthread/RenderThread.cpp
index f9d0f47..ece4530 100644
--- a/libs/hwui/platform/host/renderthread/RenderThread.cpp
+++ b/libs/hwui/platform/host/renderthread/RenderThread.cpp
@@ -27,8 +27,6 @@
 static bool gHasRenderThreadInstance = false;
 static JVMAttachHook gOnStartHook = nullptr;
 
-ASurfaceControlFunctions::ASurfaceControlFunctions() {}
-
 bool RenderThread::hasInstance() {
     return gHasRenderThreadInstance;
 }
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index b248c4b..d5ac993 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -18,6 +18,12 @@
 
 #include <apex/window.h>
 #include <fcntl.h>
+
+#ifdef __ANDROID__
+#include <gui/ITransactionCompletedListener.h>
+#include <gui/SurfaceComposerClient.h>
+#endif
+
 #include <gui/TraceUtils.h>
 #include <strings.h>
 #include <sys/stat.h>
@@ -165,7 +171,9 @@
     stopDrawing();
     setHardwareBuffer(nullptr);
     setSurface(nullptr);
+#ifdef __ANDROID__
     setSurfaceControl(nullptr);
+#endif
     freePrefetchedLayers();
     destroyHardwareResources();
     mAnimationContext->destroy();
@@ -220,10 +228,15 @@
     setupPipelineSurface();
 }
 
-void CanvasContext::setSurfaceControl(ASurfaceControl* surfaceControl) {
-    if (surfaceControl == mSurfaceControl) return;
+#ifdef __ANDROID__
+sp<SurfaceControl> CanvasContext::getSurfaceControl() const {
+    return mSurfaceControl;
+}
+#endif
 
-    auto funcs = mRenderThread.getASurfaceControlFunctions();
+void CanvasContext::setSurfaceControl(sp<SurfaceControl> surfaceControl) {
+#ifdef __ANDROID__
+    if (surfaceControl == mSurfaceControl) return;
 
     if (surfaceControl == nullptr) {
         setASurfaceTransactionCallback(nullptr);
@@ -231,17 +244,23 @@
     }
 
     if (mSurfaceControl != nullptr) {
-        funcs.unregisterListenerFunc(this, &onSurfaceStatsAvailable);
-        funcs.releaseFunc(mSurfaceControl);
+        TransactionCompletedListener::getInstance()->removeSurfaceStatsListener(
+                this, reinterpret_cast<void*>(onSurfaceStatsAvailable));
     }
-    mSurfaceControl = surfaceControl;
+
+    mSurfaceControl = std::move(surfaceControl);
     mSurfaceControlGenerationId++;
-    mExpectSurfaceStats = surfaceControl != nullptr;
+    mExpectSurfaceStats = mSurfaceControl != nullptr;
     if (mExpectSurfaceStats) {
-        funcs.acquireFunc(mSurfaceControl);
-        funcs.registerListenerFunc(surfaceControl, mSurfaceControlGenerationId, this,
-                                   &onSurfaceStatsAvailable);
+        SurfaceStatsCallback callback = [generationId = mSurfaceControlGenerationId](
+                                                void* callback_context, nsecs_t, const sp<Fence>&,
+                                                const SurfaceStats& surfaceStats) {
+            onSurfaceStatsAvailable(callback_context, generationId, surfaceStats);
+        };
+        TransactionCompletedListener::getInstance()->addSurfaceStatsListener(
+                this, reinterpret_cast<void*>(onSurfaceStatsAvailable), mSurfaceControl, callback);
     }
+#endif
 }
 
 void CanvasContext::setupPipelineSurface() {
@@ -896,17 +915,26 @@
 }
 
 void CanvasContext::onSurfaceStatsAvailable(void* context, int32_t surfaceControlId,
-                                            ASurfaceControlStats* stats) {
+                                            const SurfaceStats& stats) {
+#ifdef __ANDROID__
     auto* instance = static_cast<CanvasContext*>(context);
 
-    const ASurfaceControlFunctions& functions =
-            instance->mRenderThread.getASurfaceControlFunctions();
+    nsecs_t gpuCompleteTime = -1L;
+    if (const auto* fence = std::get_if<sp<Fence>>(&stats.acquireTimeOrFence)) {
+        // We got a fence instead of the acquire time due to latching unsignaled.
+        // Ideally the client could just get the acquire time directly from
+        // the fence instead of calling this function which needs to block.
+        (*fence)->waitForever("acquireFence");
+        gpuCompleteTime = (*fence)->getSignalTime();
+    } else {
+        gpuCompleteTime = std::get<int64_t>(stats.acquireTimeOrFence);
+    }
 
-    nsecs_t gpuCompleteTime = functions.getAcquireTimeFunc(stats);
     if (gpuCompleteTime == Fence::SIGNAL_TIME_PENDING) {
         gpuCompleteTime = -1;
     }
-    uint64_t frameNumber = functions.getFrameNumberFunc(stats);
+
+    uint64_t frameNumber = stats.eventStats.frameNumber;
 
     FrameInfo* frameInfo = instance->getFrameInfoFromLastFew(frameNumber, surfaceControlId);
 
@@ -919,6 +947,7 @@
         instance->mJankTracker.finishFrame(*frameInfo, instance->mFrameMetricsReporter, frameNumber,
                                            surfaceControlId);
     }
+#endif
 }
 
 // Called by choreographer to do an RT-driven animation
@@ -1140,10 +1169,11 @@
     return ScopedActiveContext::getActiveContext();
 }
 
-bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control) {
+bool CanvasContext::mergeTransaction(ASurfaceTransaction* transaction,
+                                     const sp<SurfaceControl>& control) {
     if (!mASurfaceTransactionCallback) return false;
     return std::invoke(mASurfaceTransactionCallback, reinterpret_cast<int64_t>(transaction),
-                       reinterpret_cast<int64_t>(control), getFrameNumber());
+                       reinterpret_cast<int64_t>(control.get()), getFrameNumber());
 }
 
 void CanvasContext::prepareSurfaceControlForWebview() {
diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h
index 3de8e05..655aeba 100644
--- a/libs/hwui/renderthread/CanvasContext.h
+++ b/libs/hwui/renderthread/CanvasContext.h
@@ -50,6 +50,9 @@
 #include "utils/RingBuffer.h"
 
 namespace android {
+
+class SurfaceStats;
+
 namespace uirenderer {
 
 class AnimationContext;
@@ -121,7 +124,9 @@
      */
     GrDirectContext* getGrContext() const { return mRenderThread.getGrContext(); }
 
-    ASurfaceControl* getSurfaceControl() const { return mSurfaceControl; }
+#ifdef __ANDROID__
+    sp<SurfaceControl> getSurfaceControl() const;
+#endif
     int32_t getSurfaceControlGenerationId() const { return mSurfaceControlGenerationId; }
 
     // Won't take effect until next EGLSurface creation
@@ -129,7 +134,7 @@
 
     void setHardwareBuffer(AHardwareBuffer* buffer);
     void setSurface(ANativeWindow* window, bool enableTimeout = true);
-    void setSurfaceControl(ASurfaceControl* surfaceControl);
+    void setSurfaceControl(sp<SurfaceControl> surfaceControl);
     bool pauseSurface();
     void setStopped(bool stopped);
     bool isStopped() { return mStopped || !hasOutputTarget(); }
@@ -207,7 +212,7 @@
 
     // Called when SurfaceStats are available.
     static void onSurfaceStatsAvailable(void* context, int32_t surfaceControlId,
-                                        ASurfaceControlStats* stats);
+                                        const SurfaceStats& stats);
 
     void setASurfaceTransactionCallback(
             const std::function<bool(int64_t, int64_t, int64_t)>& callback) {
@@ -218,7 +223,7 @@
         mBufferParams = params;
     }
 
-    bool mergeTransaction(ASurfaceTransaction* transaction, ASurfaceControl* control);
+    bool mergeTransaction(ASurfaceTransaction* transaction, const sp<SurfaceControl>& control);
 
     void setPrepareSurfaceControlForWebviewCallback(const std::function<void()>& callback) {
         mPrepareSurfaceControlForWebviewCallback = callback;
@@ -286,7 +291,9 @@
     std::unique_ptr<ReliableSurface> mNativeSurface;
     // The SurfaceControl reference is passed from ViewRootImpl, can be set to
     // NULL to remove the reference
-    ASurfaceControl* mSurfaceControl = nullptr;
+#ifdef __ANDROID__
+    sp<SurfaceControl> mSurfaceControl = nullptr;
+#endif
     // id to track surface control changes and WebViewFunctor uses it to determine
     // whether reparenting is needed also used by FrameMetricsReporter to determine
     // if a frame is from an "old" surface (i.e. one that existed before the
diff --git a/libs/hwui/renderthread/ReliableSurface.cpp b/libs/hwui/renderthread/ReliableSurface.cpp
index 64d38b9..01e8010 100644
--- a/libs/hwui/renderthread/ReliableSurface.cpp
+++ b/libs/hwui/renderthread/ReliableSurface.cpp
@@ -149,9 +149,25 @@
         return AHardwareBuffer_to_ANativeWindowBuffer(mScratchBuffer.get());
     }
 
+    int width = -1;
+    int result = mWindow->query(mWindow, NATIVE_WINDOW_DEFAULT_WIDTH, &width);
+    if (result != OK || width < 0) {
+        ALOGW("Failed to query window default width: %s (%d) value=%d", strerror(-result), result,
+              width);
+        width = 1;
+    }
+
+    int height = -1;
+    result = mWindow->query(mWindow, NATIVE_WINDOW_DEFAULT_HEIGHT, &height);
+    if (result != OK || height < 0) {
+        ALOGW("Failed to query window default height: %s (%d) value=%d", strerror(-result), result,
+              height);
+        height = 1;
+    }
+
     AHardwareBuffer_Desc desc = AHardwareBuffer_Desc{
-            .width = 1,
-            .height = 1,
+            .width = static_cast<uint32_t>(width),
+            .height = static_cast<uint32_t>(height),
             .layers = 1,
             .format = mFormat,
             .usage = mUsage,
@@ -160,9 +176,9 @@
     };
 
     AHardwareBuffer* newBuffer;
-    int result = AHardwareBuffer_allocate(&desc, &newBuffer);
+    result = AHardwareBuffer_allocate(&desc, &newBuffer);
 
-    if (result != NO_ERROR) {
+    if (result != OK) {
         // Allocate failed, that sucks
         ALOGW("Failed to allocate scratch buffer, error=%d", result);
         return nullptr;
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index ebfd8fde9..e4be5fa 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -21,6 +21,11 @@
 #include <SkPicture.h>
 #include <gui/TraceUtils.h>
 #include <pthread.h>
+
+#ifdef __ANDROID__
+#include <gui/SurfaceControl.h>
+#endif
+
 #include <ui/GraphicBufferAllocator.h>
 
 #include "DeferredLayerUpdater.h"
@@ -115,17 +120,12 @@
     });
 }
 
-void RenderProxy::setSurfaceControl(ASurfaceControl* surfaceControl) {
-    auto funcs = mRenderThread.getASurfaceControlFunctions();
-    if (surfaceControl) {
-        funcs.acquireFunc(surfaceControl);
-    }
-    mRenderThread.queue().post([this, control = surfaceControl, funcs]() mutable {
-        mContext->setSurfaceControl(control);
-        if (control) {
-            funcs.releaseFunc(control);
-        }
+void RenderProxy::setSurfaceControl(sp<SurfaceControl> surfaceControl) {
+#ifdef __ANDROID__
+    mRenderThread.queue().post([this, control = std::move(surfaceControl)]() mutable {
+        mContext->setSurfaceControl(std::move(control));
     });
+#endif
 }
 
 void RenderProxy::allocateBuffers() {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index ad6d54b..23b3ebd 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -20,7 +20,6 @@
 #include <SkRefCnt.h>
 #include <android/hardware_buffer.h>
 #include <android/native_window.h>
-#include <android/surface_control.h>
 #include <cutils/compiler.h>
 #include <utils/Functor.h>
 
@@ -39,6 +38,7 @@
 
 namespace android {
 class GraphicBuffer;
+class SurfaceControl;
 class Surface;
 
 namespace uirenderer {
@@ -80,7 +80,7 @@
     void setName(const char* name);
     void setHardwareBuffer(AHardwareBuffer* buffer);
     void setSurface(ANativeWindow* window, bool enableTimeout = true);
-    void setSurfaceControl(ASurfaceControl* surfaceControl);
+    void setSurfaceControl(sp<SurfaceControl> surfaceControl);
     void allocateBuffers();
     bool pause();
     void setStopped(bool stopped);
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 6ab8e4e..5e40424 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -55,66 +55,6 @@
 
 static JVMAttachHook gOnStartHook = nullptr;
 
-ASurfaceControlFunctions::ASurfaceControlFunctions() {
-    void* handle_ = dlopen("libandroid.so", RTLD_NOW | RTLD_NODELETE);
-    createFunc = (ASC_create)dlsym(handle_, "ASurfaceControl_create");
-    LOG_ALWAYS_FATAL_IF(createFunc == nullptr,
-                        "Failed to find required symbol ASurfaceControl_create!");
-
-    acquireFunc = (ASC_acquire) dlsym(handle_, "ASurfaceControl_acquire");
-    LOG_ALWAYS_FATAL_IF(acquireFunc == nullptr,
-            "Failed to find required symbol ASurfaceControl_acquire!");
-
-    releaseFunc = (ASC_release) dlsym(handle_, "ASurfaceControl_release");
-    LOG_ALWAYS_FATAL_IF(releaseFunc == nullptr,
-            "Failed to find required symbol ASurfaceControl_release!");
-
-    registerListenerFunc = (ASC_registerSurfaceStatsListener) dlsym(handle_,
-            "ASurfaceControl_registerSurfaceStatsListener");
-    LOG_ALWAYS_FATAL_IF(registerListenerFunc == nullptr,
-            "Failed to find required symbol ASurfaceControl_registerSurfaceStatsListener!");
-
-    unregisterListenerFunc = (ASC_unregisterSurfaceStatsListener) dlsym(handle_,
-            "ASurfaceControl_unregisterSurfaceStatsListener");
-    LOG_ALWAYS_FATAL_IF(unregisterListenerFunc == nullptr,
-            "Failed to find required symbol ASurfaceControl_unregisterSurfaceStatsListener!");
-
-    getAcquireTimeFunc = (ASCStats_getAcquireTime) dlsym(handle_,
-            "ASurfaceControlStats_getAcquireTime");
-    LOG_ALWAYS_FATAL_IF(getAcquireTimeFunc == nullptr,
-            "Failed to find required symbol ASurfaceControlStats_getAcquireTime!");
-
-    getFrameNumberFunc = (ASCStats_getFrameNumber) dlsym(handle_,
-            "ASurfaceControlStats_getFrameNumber");
-    LOG_ALWAYS_FATAL_IF(getFrameNumberFunc == nullptr,
-            "Failed to find required symbol ASurfaceControlStats_getFrameNumber!");
-
-    transactionCreateFunc = (AST_create)dlsym(handle_, "ASurfaceTransaction_create");
-    LOG_ALWAYS_FATAL_IF(transactionCreateFunc == nullptr,
-                        "Failed to find required symbol ASurfaceTransaction_create!");
-
-    transactionDeleteFunc = (AST_delete)dlsym(handle_, "ASurfaceTransaction_delete");
-    LOG_ALWAYS_FATAL_IF(transactionDeleteFunc == nullptr,
-                        "Failed to find required symbol ASurfaceTransaction_delete!");
-
-    transactionApplyFunc = (AST_apply)dlsym(handle_, "ASurfaceTransaction_apply");
-    LOG_ALWAYS_FATAL_IF(transactionApplyFunc == nullptr,
-                        "Failed to find required symbol ASurfaceTransaction_apply!");
-
-    transactionReparentFunc = (AST_reparent)dlsym(handle_, "ASurfaceTransaction_reparent");
-    LOG_ALWAYS_FATAL_IF(transactionReparentFunc == nullptr,
-                        "Failed to find required symbol transactionReparentFunc!");
-
-    transactionSetVisibilityFunc =
-            (AST_setVisibility)dlsym(handle_, "ASurfaceTransaction_setVisibility");
-    LOG_ALWAYS_FATAL_IF(transactionSetVisibilityFunc == nullptr,
-                        "Failed to find required symbol ASurfaceTransaction_setVisibility!");
-
-    transactionSetZOrderFunc = (AST_setZOrder)dlsym(handle_, "ASurfaceTransaction_setZOrder");
-    LOG_ALWAYS_FATAL_IF(transactionSetZOrderFunc == nullptr,
-                        "Failed to find required symbol ASurfaceTransaction_setZOrder!");
-}
-
 void RenderThread::extendedFrameCallback(const AChoreographerFrameCallbackData* cbData,
                                          void* data) {
     RenderThread* rt = reinterpret_cast<RenderThread*>(data);
diff --git a/libs/hwui/renderthread/RenderThread.h b/libs/hwui/renderthread/RenderThread.h
index 86fddba..f733c7c 100644
--- a/libs/hwui/renderthread/RenderThread.h
+++ b/libs/hwui/renderthread/RenderThread.h
@@ -77,49 +77,6 @@
     virtual ~VsyncSource() {}
 };
 
-typedef ASurfaceControl* (*ASC_create)(ASurfaceControl* parent, const char* debug_name);
-typedef void (*ASC_acquire)(ASurfaceControl* control);
-typedef void (*ASC_release)(ASurfaceControl* control);
-
-typedef void (*ASC_registerSurfaceStatsListener)(ASurfaceControl* control, int32_t id,
-                                                 void* context,
-                                                 ASurfaceControl_SurfaceStatsListener func);
-typedef void (*ASC_unregisterSurfaceStatsListener)(void* context,
-                                                   ASurfaceControl_SurfaceStatsListener func);
-
-typedef int64_t (*ASCStats_getAcquireTime)(ASurfaceControlStats* stats);
-typedef uint64_t (*ASCStats_getFrameNumber)(ASurfaceControlStats* stats);
-
-typedef ASurfaceTransaction* (*AST_create)();
-typedef void (*AST_delete)(ASurfaceTransaction* transaction);
-typedef void (*AST_apply)(ASurfaceTransaction* transaction);
-typedef void (*AST_reparent)(ASurfaceTransaction* aSurfaceTransaction,
-                             ASurfaceControl* aSurfaceControl,
-                             ASurfaceControl* newParentASurfaceControl);
-typedef void (*AST_setVisibility)(ASurfaceTransaction* transaction,
-                                  ASurfaceControl* surface_control, int8_t visibility);
-typedef void (*AST_setZOrder)(ASurfaceTransaction* transaction, ASurfaceControl* surface_control,
-                              int32_t z_order);
-
-struct ASurfaceControlFunctions {
-    ASurfaceControlFunctions();
-
-    ASC_create createFunc;
-    ASC_acquire acquireFunc;
-    ASC_release releaseFunc;
-    ASC_registerSurfaceStatsListener registerListenerFunc;
-    ASC_unregisterSurfaceStatsListener unregisterListenerFunc;
-    ASCStats_getAcquireTime getAcquireTimeFunc;
-    ASCStats_getFrameNumber getFrameNumberFunc;
-
-    AST_create transactionCreateFunc;
-    AST_delete transactionDeleteFunc;
-    AST_apply transactionApplyFunc;
-    AST_reparent transactionReparentFunc;
-    AST_setVisibility transactionSetVisibilityFunc;
-    AST_setZOrder transactionSetZOrderFunc;
-};
-
 class ChoreographerSource;
 class DummyVsyncSource;
 
@@ -166,10 +123,6 @@
 
     void preload();
 
-    const ASurfaceControlFunctions& getASurfaceControlFunctions() {
-        return mASurfaceControlFunctions;
-    }
-
     void trimMemory(TrimLevel level);
     void trimCaches(CacheTrimLevel level);
 
@@ -244,7 +197,6 @@
     CacheManager* mCacheManager;
     sp<VulkanManager> mVkManager;
 
-    ASurfaceControlFunctions mASurfaceControlFunctions;
     std::mutex mJankDataMutex;
 };
 
diff --git a/location/java/android/location/flags/location.aconfig b/location/java/android/location/flags/location.aconfig
index f8eb418..f26e72f 100644
--- a/location/java/android/location/flags/location.aconfig
+++ b/location/java/android/location/flags/location.aconfig
@@ -167,6 +167,7 @@
     namespace: "location"
     description: "Flag for GNSS assistance interface"
     bug: "209078566"
+    is_exported: true
 }
 
 flag {
@@ -186,3 +187,21 @@
     bug: "398254728"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "limit_fused_gps"
+    namespace: "location"
+    description: "Limits when GPS can be used for fused location requests"
+    bug: "401885179"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
+
+flag {
+    name: "gnss_assistance_interface_jni"
+    namespace: "location"
+    description: "Flag for GNSS assistance interface JNI"
+    bug: "209078566"
+}
+
diff --git a/media/java/android/media/AudioDeviceVolumeManager.java b/media/java/android/media/AudioDeviceVolumeManager.java
index 56d3df3..311d64f 100644
--- a/media/java/android/media/AudioDeviceVolumeManager.java
+++ b/media/java/android/media/AudioDeviceVolumeManager.java
@@ -29,6 +29,7 @@
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SystemApi;
+import android.annotation.TestApi;
 import android.content.Context;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -52,6 +53,127 @@
 
     private static final String TAG = "AudioDeviceVolumeManager";
 
+    /**
+     * @hide
+     * Volume behavior for an audio device that has no particular volume behavior set. Invalid as
+     * an argument to {@link #setDeviceVolumeBehavior(AudioDeviceAttributes, int)} and should not
+     * be returned by {@link #getDeviceVolumeBehavior(AudioDeviceAttributes)}.
+     */
+    public static final int DEVICE_VOLUME_BEHAVIOR_UNSET = -1;
+    /**
+     * @hide
+     * Volume behavior for an audio device where a software attenuation is applied
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+    public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0;
+    /**
+     * @hide
+     * Volume behavior for an audio device where the volume is always set to provide no attenuation
+     *     nor gain (e.g. unit gain).
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+    public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1;
+    /**
+     * @hide
+     * Volume behavior for an audio device where the volume is either set to muted, or to provide
+     *     no attenuation nor gain (e.g. unit gain).
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+    public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2;
+    /**
+     * @hide
+     * Volume behavior for an audio device where no software attenuation is applied, and
+     *     the volume is kept synchronized between the host and the device itself through a
+     *     device-specific protocol such as BT AVRCP.
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+    public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3;
+    /**
+     * @hide
+     * Volume behavior for an audio device where no software attenuation is applied, and
+     *     the volume is kept synchronized between the host and the device itself through a
+     *     device-specific protocol (such as for hearing aids), based on the audio mode (e.g.
+     *     normal vs in phone call).
+     * @see AudioManager#setMode(int)
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+    public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4;
+
+    /**
+     * @hide
+     * A variant of {@link #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE} where the host cannot reliably set
+     * the volume percentage of the audio device. Specifically, {@link AudioManager#setStreamVolume}
+     * will have no effect, or an unreliable effect.
+     */
+    @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+    public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5;
+
+    /** @hide */
+    @IntDef({
+            DEVICE_VOLUME_BEHAVIOR_VARIABLE,
+            DEVICE_VOLUME_BEHAVIOR_FULL,
+            DEVICE_VOLUME_BEHAVIOR_FIXED,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DeviceVolumeBehavior {}
+
+    /** @hide */
+    @IntDef({
+            DEVICE_VOLUME_BEHAVIOR_UNSET,
+            DEVICE_VOLUME_BEHAVIOR_VARIABLE,
+            DEVICE_VOLUME_BEHAVIOR_FULL,
+            DEVICE_VOLUME_BEHAVIOR_FIXED,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DeviceVolumeBehaviorState {}
+
+    /**
+     * Variants of absolute volume behavior that are set in for absolute volume management.
+     * @hide
+     */
+    @IntDef({
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AbsoluteDeviceVolumeBehavior {}
+
+    /**
+     * @hide
+     * Throws IAE on an invalid volume behavior value
+     * @param volumeBehavior behavior value to check
+     */
+    public static void enforceValidVolumeBehavior(int volumeBehavior) {
+        switch (volumeBehavior) {
+            case DEVICE_VOLUME_BEHAVIOR_VARIABLE:
+            case DEVICE_VOLUME_BEHAVIOR_FULL:
+            case DEVICE_VOLUME_BEHAVIOR_FIXED:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
+                return;
+            default:
+                throw new IllegalArgumentException("Illegal volume behavior " + volumeBehavior);
+        }
+    }
+
     /** @hide
      * Indicates no special treatment in the handling of the volume adjustment */
     public static final int ADJUST_MODE_NORMAL = 0;
@@ -158,7 +280,7 @@
                 android.Manifest.permission.BLUETOOTH_PRIVILEGED })
         public void register(boolean register, @NonNull AudioDeviceAttributes device,
                 @NonNull List<VolumeInfo> volumes, boolean handlesVolumeAdjustment,
-                @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
+                @AbsoluteDeviceVolumeBehavior int behavior) {
             try {
                 getService().registerDeviceVolumeDispatcherForAbsoluteVolume(register,
                         this, mPackageName,
@@ -204,6 +326,94 @@
 
     /**
      * @hide
+     * Sets the volume behavior for an audio output device.
+     * @see #DEVICE_VOLUME_BEHAVIOR_VARIABLE
+     * @see #DEVICE_VOLUME_BEHAVIOR_FULL
+     * @see #DEVICE_VOLUME_BEHAVIOR_FIXED
+     * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE
+     * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE
+     * @param device the device to be affected
+     * @param deviceVolumeBehavior one of the device behaviors
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            Manifest.permission.MODIFY_AUDIO_ROUTING,
+            Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
+    })
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+    public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+            @DeviceVolumeBehavior int deviceVolumeBehavior) {
+        // verify arguments (validity of device type is enforced in server)
+        Objects.requireNonNull(device);
+        enforceValidVolumeBehavior(deviceVolumeBehavior);
+        // communicate with service
+        final IAudioService service = getService();
+        try {
+            service.setDeviceVolumeBehavior(device, deviceVolumeBehavior, mPackageName);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns the volume device behavior for the given audio device
+     * @param device the audio device
+     * @return the volume behavior for the device
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            Manifest.permission.MODIFY_AUDIO_ROUTING,
+            Manifest.permission.QUERY_AUDIO_STATE,
+            Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
+    })
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
+    public @DeviceVolumeBehavior int getDeviceVolumeBehavior(
+            @NonNull AudioDeviceAttributes device) {
+        // verify arguments (validity of device type is enforced in server)
+        Objects.requireNonNull(device);
+        // communicate with service
+        final IAudioService service = getService();
+        try {
+            return service.getDeviceVolumeBehavior(device);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns {@code true} if the volume device behavior is {@link #DEVICE_VOLUME_BEHAVIOR_FULL}.
+     */
+    @TestApi
+    @RequiresPermission(anyOf = {
+            Manifest.permission.MODIFY_AUDIO_ROUTING,
+            Manifest.permission.QUERY_AUDIO_STATE,
+            Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
+    })
+    @SuppressWarnings("UnflaggedApi")  // @TestApi without associated feature.
+    public boolean isFullVolumeDevice() {
+        final AudioAttributes attributes = new AudioAttributes.Builder()
+                .setUsage(AudioAttributes.USAGE_MEDIA)
+                .build();
+        List<AudioDeviceAttributes> devices;
+        final IAudioService service = getService();
+        try {
+            devices = service.getDevicesForAttributes(attributes);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+
+        for (AudioDeviceAttributes device : devices) {
+            if (getDeviceVolumeBehavior(device) == DEVICE_VOLUME_BEHAVIOR_FULL) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @hide
      * Configures a device to use absolute volume model, and registers a listener for receiving
      * volume updates to apply on that device
      * @param device the audio device set to absolute volume mode
@@ -297,7 +507,7 @@
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
         baseSetDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
-                handlesVolumeAdjustment, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+                handlesVolumeAdjustment, DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
     }
 
     /**
@@ -355,12 +565,12 @@
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
         baseSetDeviceAbsoluteMultiVolumeBehavior(device, volumes, executor, vclistener,
-                handlesVolumeAdjustment, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+                handlesVolumeAdjustment, DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
     }
 
     /**
      * Base method for configuring a device to use absolute volume behavior, or one of its variants.
-     * See {@link AudioManager.AbsoluteDeviceVolumeBehavior} for a list of allowed behaviors.
+     * See {@link AbsoluteDeviceVolumeBehavior} for a list of allowed behaviors.
      *
      * @param behavior the variant of absolute device volume behavior to adopt
      */
@@ -372,7 +582,7 @@
             @NonNull @CallbackExecutor Executor executor,
             @NonNull OnAudioDeviceVolumeChangedListener vclistener,
             boolean handlesVolumeAdjustment,
-            @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
+            @AbsoluteDeviceVolumeBehavior int behavior) {
         Objects.requireNonNull(device);
         Objects.requireNonNull(volumes);
         Objects.requireNonNull(executor);
@@ -417,7 +627,7 @@
          */
         void onDeviceVolumeBehaviorChanged(
                 @NonNull AudioDeviceAttributes device,
-                @AudioManager.DeviceVolumeBehavior int volumeBehavior);
+                @DeviceVolumeBehavior int volumeBehavior);
     }
 
     /**
@@ -580,19 +790,19 @@
      * @param behavior one of the volume behaviors defined in AudioManager
      * @return a string for the given behavior
      */
-    public static String volumeBehaviorName(@AudioManager.DeviceVolumeBehavior int behavior) {
+    public static String volumeBehaviorName(@DeviceVolumeBehavior int behavior) {
         switch (behavior) {
-            case AudioManager.DEVICE_VOLUME_BEHAVIOR_VARIABLE:
+            case DEVICE_VOLUME_BEHAVIOR_VARIABLE:
                 return "DEVICE_VOLUME_BEHAVIOR_VARIABLE";
-            case AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL:
+            case DEVICE_VOLUME_BEHAVIOR_FULL:
                 return "DEVICE_VOLUME_BEHAVIOR_FULL";
-            case AudioManager.DEVICE_VOLUME_BEHAVIOR_FIXED:
+            case DEVICE_VOLUME_BEHAVIOR_FIXED:
                 return "DEVICE_VOLUME_BEHAVIOR_FIXED";
-            case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
                 return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE";
-            case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
                 return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE";
-            case AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
                 return "DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY";
             default:
                 return "invalid volume behavior " + behavior;
@@ -611,7 +821,7 @@
 
         @Override
         public void dispatchDeviceVolumeBehaviorChanged(@NonNull AudioDeviceAttributes device,
-                @AudioManager.DeviceVolumeBehavior int volumeBehavior) {
+                @DeviceVolumeBehavior int volumeBehavior) {
             mDeviceVolumeBehaviorChangedListenerMgr.callListeners((listener) ->
                     listener.onDeviceVolumeBehaviorChanged(device, volumeBehavior));
         }
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 32af7c6..4aba491 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -19,6 +19,7 @@
 import static android.companion.virtual.VirtualDeviceParams.DEVICE_POLICY_DEFAULT;
 import static android.companion.virtual.VirtualDeviceParams.POLICY_TYPE_AUDIO;
 import static android.content.Context.DEVICE_ID_DEFAULT;
+import static android.media.audio.Flags.FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT;
 import static android.media.audio.Flags.autoPublicVolumeApiHardening;
 import static android.media.audio.Flags.cacheGetStreamMinMaxVolume;
 import static android.media.audio.Flags.cacheGetStreamVolume;
@@ -6659,24 +6660,30 @@
      * @hide
      * Volume behavior for an audio device where a software attenuation is applied
      * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_VARIABLE} instead
      */
     @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
     public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0;
     /**
      * @hide
      * Volume behavior for an audio device where the volume is always set to provide no attenuation
      *     nor gain (e.g. unit gain).
      * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_FULL} instead
      */
     @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
     public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1;
     /**
      * @hide
      * Volume behavior for an audio device where the volume is either set to muted, or to provide
      *     no attenuation nor gain (e.g. unit gain).
      * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_FIXED} instead
      */
     @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
     public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2;
     /**
      * @hide
@@ -6684,8 +6691,10 @@
      *     the volume is kept synchronized between the host and the device itself through a
      *     device-specific protocol such as BT AVRCP.
      * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_ABSOLUTE} instead
      */
     @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
     public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3;
     /**
      * @hide
@@ -6695,8 +6704,11 @@
      *     normal vs in phone call).
      * @see #setMode(int)
      * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE}
+     * instead
      */
     @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
     public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4;
 
     /**
@@ -6704,8 +6716,11 @@
      * A variant of {@link #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE} where the host cannot reliably set
      * the volume percentage of the audio device. Specifically, {@link #setStreamVolume} will have
      * no effect, or an unreliable effect.
+     * @deprecated use {@link AudioDeviceVolumeManager#DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY}
+     * instead
      */
     @SystemApi
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
     public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY = 5;
 
     /** @hide */
@@ -6720,49 +6735,6 @@
     @Retention(RetentionPolicy.SOURCE)
     public @interface DeviceVolumeBehavior {}
 
-    /** @hide */
-    @IntDef({
-            DEVICE_VOLUME_BEHAVIOR_UNSET,
-            DEVICE_VOLUME_BEHAVIOR_VARIABLE,
-            DEVICE_VOLUME_BEHAVIOR_FULL,
-            DEVICE_VOLUME_BEHAVIOR_FIXED,
-            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
-            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
-            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface DeviceVolumeBehaviorState {}
-
-    /**
-     * Variants of absolute volume behavior that are set in {@link AudioDeviceVolumeManager}.
-     * @hide
-     */
-    @IntDef({
-            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
-            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY,
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface AbsoluteDeviceVolumeBehavior {}
-
-    /**
-     * @hide
-     * Throws IAE on an invalid volume behavior value
-     * @param volumeBehavior behavior value to check
-     */
-    public static void enforceValidVolumeBehavior(int volumeBehavior) {
-        switch (volumeBehavior) {
-            case DEVICE_VOLUME_BEHAVIOR_VARIABLE:
-            case DEVICE_VOLUME_BEHAVIOR_FULL:
-            case DEVICE_VOLUME_BEHAVIOR_FIXED:
-            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
-            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
-            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY:
-                return;
-            default:
-                throw new IllegalArgumentException("Illegal volume behavior " + volumeBehavior);
-        }
-    }
-
     /**
      * @hide
      * Sets the volume behavior for an audio output device.
@@ -6773,17 +6745,21 @@
      * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE
      * @param device the device to be affected
      * @param deviceVolumeBehavior one of the device behaviors
+     *
+     * @deprecated use
+     * {@link AudioDeviceVolumeManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)} instead
      */
     @SystemApi
     @RequiresPermission(anyOf = {
             Manifest.permission.MODIFY_AUDIO_ROUTING,
             Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
     })
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
             @DeviceVolumeBehavior int deviceVolumeBehavior) {
         // verify arguments (validity of device type is enforced in server)
         Objects.requireNonNull(device);
-        enforceValidVolumeBehavior(deviceVolumeBehavior);
+        AudioDeviceVolumeManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
         // communicate with service
         final IAudioService service = getService();
         try {
@@ -6810,6 +6786,8 @@
      * Returns the volume device behavior for the given audio device
      * @param device the audio device
      * @return the volume behavior for the device
+     * @deprecated use
+     * {@link AudioDeviceVolumeManager#getDeviceVolumeBehavior(AudioDeviceAttributes)} instead
      */
     @SystemApi
     @RequiresPermission(anyOf = {
@@ -6817,6 +6795,7 @@
             Manifest.permission.QUERY_AUDIO_STATE,
             Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
     })
+    @FlaggedApi(FLAG_UNIFY_ABSOLUTE_VOLUME_MANAGEMENT)
     public @DeviceVolumeBehavior
     int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
         // verify arguments (validity of device type is enforced in server)
@@ -6836,29 +6815,6 @@
     }
 
     /**
-     * @hide
-     * Returns {@code true} if the volume device behavior is {@link #DEVICE_VOLUME_BEHAVIOR_FULL}.
-     */
-    @TestApi
-    @RequiresPermission(anyOf = {
-            Manifest.permission.MODIFY_AUDIO_ROUTING,
-            Manifest.permission.QUERY_AUDIO_STATE,
-            Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED
-    })
-    public boolean isFullVolumeDevice() {
-        final AudioAttributes attributes = new AudioAttributes.Builder()
-                .setUsage(AudioAttributes.USAGE_MEDIA)
-                .build();
-        final List<AudioDeviceAttributes> devices = getDevicesForAttributes(attributes);
-        for (AudioDeviceAttributes device : devices) {
-            if (getDeviceVolumeBehavior(device) == DEVICE_VOLUME_BEHAVIOR_FULL) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
      * Indicate wired accessory connection state change.
      * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
      * @param state  new connection state: 1 connected, 0 disconnected
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index f3b21bf..3b560b7 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -219,13 +219,14 @@
     private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
     private static final int MAX_SUPPORTED_INSTANCES_LIMIT = 256;
 
-    private static final class LazyHolder {
-        private static final Range<Integer> SIZE_RANGE = Process.is64Bit()
-                ? Range.create(1, 32768)
-                : Range.create(1, MediaProperties.resolution_limit_32bit().orElse(4096));
-    }
-    private static Range<Integer> getSizeRange() {
-        return LazyHolder.SIZE_RANGE;
+    private static Range<Integer> SIZE_RANGE;
+    private static synchronized Range<Integer> getSizeRange() {
+        if (SIZE_RANGE == null) {
+            SIZE_RANGE = Process.is64Bit()
+                    ? Range.create(1, 32768)
+                    : Range.create(1, MediaProperties.resolution_limit_32bit().orElse(4096));
+        }
+        return SIZE_RANGE;
     }
 
     // found stuff that is not supported by framework (=> this should not happen)
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 7af78b8..03bcc6a 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -1299,6 +1299,7 @@
      * start() or before setOutputFormat().
      * @throws IOException if prepare fails otherwise.
      */
+    @RequiresPermission(value = android.Manifest.permission.RECORD_AUDIO, conditional = true)
     public void prepare() throws IllegalStateException, IOException
     {
         if (mPath != null) {
@@ -1337,6 +1338,7 @@
      * @throws IllegalStateException if it is called before
      * prepare() or when the camera is already in use by another app.
      */
+    @RequiresPermission(value = android.Manifest.permission.RECORD_AUDIO, conditional = true)
     public native void start() throws IllegalStateException;
 
     /**
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index b57476f..6e0821f 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -183,7 +183,17 @@
             appContext.registerReceiver(new VolumeChangeReceiver(),
                     new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
 
-            mDisplayService.registerDisplayListener(this, mHandler);
+            if (com.android.server.display.feature.flags.Flags
+                    .displayListenerPerformanceImprovements()
+                    && com.android.server.display.feature.flags.Flags
+                    .delayImplicitRrRegistrationUntilRrAccessed()) {
+                mDisplayService.registerDisplayListener(this, mHandler,
+                        DisplayManager.EVENT_TYPE_DISPLAY_ADDED
+                                | DisplayManager.EVENT_TYPE_DISPLAY_CHANGED
+                                | DisplayManager.EVENT_TYPE_DISPLAY_REMOVED);
+            } else {
+                mDisplayService.registerDisplayListener(this, mHandler);
+            }
 
             AudioRoutesInfo newAudioRoutes = null;
             try {
diff --git a/media/java/android/media/flags/media_better_together.aconfig b/media/java/android/media/flags/media_better_together.aconfig
index 48e2f4e..c9ec31b 100644
--- a/media/java/android/media/flags/media_better_together.aconfig
+++ b/media/java/android/media/flags/media_better_together.aconfig
@@ -163,6 +163,13 @@
 }
 
 flag {
+  name: "enable_output_switcher_redesign"
+  namespace: "media_better_together"
+  description: "Enables visual update for the Media Output Switcher"
+  bug: "388296370"
+}
+
+flag {
     name: "enable_prevention_of_keep_alive_route_providers"
     namespace: "media_solutions"
     description: "Enables mechanisms to prevent route providers from keeping malicious apps alive."
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/AudioManagerUnitTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/AudioManagerUnitTest.java
index 6089f42..f65c7ef 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/AudioManagerUnitTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/AudioManagerUnitTest.java
@@ -28,7 +28,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.companion.virtual.VirtualDeviceManager;
@@ -56,7 +56,7 @@
         audioManager.playSoundEffect(FX_KEY_CLICK);
 
         // We expect no interactions with VDM when running on default device.
-        verifyZeroInteractions(mockVdm);
+        verifyNoMoreInteractions(mockVdm);
     }
 
     @Test
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 1c7f1f3..c133b77 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -51,10 +51,8 @@
     <string name="consent_no" msgid="2640796915611404382">"Ez eman baimenik"</string>
     <string name="consent_cancel" msgid="5655005528379285841">"Utzi"</string>
     <string name="consent_back" msgid="2560683030046918882">"Atzera"</string>
-    <!-- no translation found for downward_arrow_action (2327165938832076333) -->
-    <skip />
-    <!-- no translation found for downward_arrow (2292427714411156088) -->
-    <skip />
+    <string name="downward_arrow_action" msgid="2327165938832076333">"Egin behera zerrendan"</string>
+    <string name="downward_arrow" msgid="2292427714411156088">"Beheranzko gezia"</string>
     <string name="permission_expand" msgid="893185038020887411">"Zabaldu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
     <string name="permission_collapse" msgid="3320833884220844084">"Tolestu <xliff:g id="PERMISSION_TYPE">%1$s</xliff:g>"</string>
     <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"&lt;strong&gt;<xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; gailuan dituzten baimen berberak eman nahi dizkiezu &lt;strong&gt;<xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g>&lt;/strong&gt; gailuko aplikazioei?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index ce23be8..bc9ad8d 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -25,7 +25,7 @@
     <string name="discovery_mixed" msgid="7071466134150760127">"Bluetooth e wifi"</string>
     <string name="profile_name_watch" msgid="576290739483672360">"reloxo"</string>
     <string name="chooser_title_non_profile" msgid="6035023914517087400">"Escolle un dispositivo para que o xestione a aplicación &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt;"</string>
-    <string name="chooser_title" msgid="2235819929238267637">"Escolle o perfil (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) que queiras configurar"</string>
+    <string name="chooser_title" msgid="2235819929238267637">"Escolle o <xliff:g id="PROFILE_NAME">%1$s</xliff:g> que queiras configurar"</string>
     <string name="single_device_title" msgid="4199861437545438606">"Buscando <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
     <string name="summary_watch" msgid="8134580124808507407">"Esta aplicación poderá sincronizar información (por exemplo, o nome de quen chama) e acceder a estes permisos do dispositivo (<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>)"</string>
     <string name="confirmation_title_glasses" msgid="8288346850537727333">"Queres permitir que &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; xestione o dispositivo (&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;)?"</string>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index 1e299b7..cf65bc9 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -19,7 +19,7 @@
     <string name="app_label" msgid="4470785958457506021">"ניהול מכשיר מותאם"</string>
     <string name="confirmation_title" msgid="2244241995958340998">"‏לאפשר לאפליקציה &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; לגשת אל &lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt;?"</string>
     <string name="message_discovery_soft_timeout" msgid="473346859407859161">"צריך לוודא שה-<xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> מופעל ב<xliff:g id="DEVICE_TYPE">%1$s</xliff:g>, ושה<xliff:g id="PROFILE_NAME">%3$s</xliff:g> בקרבת מקום."</string>
-    <string name="message_discovery_hard_timeout" msgid="677514663495711424">"לא נמצאו מכשירים. אפשר לנסות שוב מאוחר יותר."</string>
+    <string name="message_discovery_hard_timeout" msgid="677514663495711424">"לא נמצאו מכשירים. כדאי לנסות שוב עוד מעט."</string>
     <string name="discovery_bluetooth" msgid="5693557668470016164">"Bluetooth"</string>
     <string name="discovery_wifi" msgid="1551782459721758773">"Wi-Fi"</string>
     <string name="discovery_mixed" msgid="7071466134150760127">"‏חיבור Wi-Fi ו-Bluetooth"</string>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index 2503826..6697a15 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -18,7 +18,7 @@
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
     <string name="app_label" msgid="4470785958457506021">"கம்பேனியன் சாதன நிர்வாகி"</string>
     <string name="confirmation_title" msgid="2244241995958340998">"&lt;strong&gt;<xliff:g id="DEVICE_NAME">%2$s</xliff:g>&lt;/strong&gt; சாதனத்தை அணுக &lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; ஆப்ஸை அனுமதிக்கவா?"</string>
-    <string name="message_discovery_soft_timeout" msgid="473346859407859161">"இந்த <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> சாதனத்தின் <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ஆன் செய்யப்பட்டு, அதன் அருகில் உங்கள் <xliff:g id="PROFILE_NAME">%3$s</xliff:g> இருப்பதை உறுதிசெய்துகொள்ளவும்."</string>
+    <string name="message_discovery_soft_timeout" msgid="473346859407859161">"இந்த <xliff:g id="DEVICE_TYPE">%1$s</xliff:g> <xliff:g id="DISCOVERY_METHOD">%2$s</xliff:g> ஆக இருக்க வேண்டும். உங்கள் <xliff:g id="PROFILE_NAME">%3$s</xliff:g> அருகில் இருக்க வேண்டும்."</string>
     <string name="message_discovery_hard_timeout" msgid="677514663495711424">"சாதனங்கள் எதுவும் கண்டறியப்படவில்லை. பிறகு முயலவும்."</string>
     <string name="discovery_bluetooth" msgid="5693557668470016164">"புளூடூத்"</string>
     <string name="discovery_wifi" msgid="1551782459721758773">"வைஃபை"</string>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 01fc767..7f2671c 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -45,7 +45,7 @@
     <string name="title_sensor_device_streaming" msgid="2395553261097861497">"&lt;strong&gt;<xliff:g id="APP_NAME">%1$s</xliff:g>&lt;/strong&gt; uygulamasının, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ve &lt;strong&gt;<xliff:g id="DEVICE_NAME">%3$s</xliff:g>&lt;/strong&gt; cihazları arasında ses ve sistem özelliklerini aktarmasına izin verilsin mi?"</string>
     <string name="summary_sensor_device_streaming" msgid="3413105061195145547">"<xliff:g id="APP_NAME_0">%1$s</xliff:g> uygulaması; <xliff:g id="DEVICE_NAME_1">%3$s</xliff:g> cihazınızda oynatılan her şeye erişebilecek.&lt;br/&gt;&lt;br/&gt;<xliff:g id="APP_NAME_2">%1$s</xliff:g> uygulaması bu iznin erişimini kaldırana kadar sesleri <xliff:g id="DEVICE_NAME_3">%3$s</xliff:g> cihazına aktarabilecek."</string>
     <string name="helper_summary_sensor_device_streaming" msgid="8860174545653786353">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması, <xliff:g id="DEVICE_NAME">%2$s</xliff:g> için cihazlarınız arasında ses ve sistem özelliklerini aktarma izni istiyor."</string>
-    <string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
+    <string name="profile_name_generic" msgid="6851028682723034988">"Cihaz"</string>
     <string name="summary_generic" msgid="1761976003668044801">"Bu uygulama, arayan kişinin adı gibi bilgileri telefonunuz ve seçili cihaz arasında senkronize edebilir"</string>
     <string name="consent_yes" msgid="8344487259618762872">"İzin ver"</string>
     <string name="consent_no" msgid="2640796915611404382">"İzin verme"</string>
diff --git a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
index 8e52a00..a0e008c 100644
--- a/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
+++ b/packages/FusedLocation/src/com/android/location/fused/FusedLocationProvider.java
@@ -19,6 +19,7 @@
 import static android.content.Intent.ACTION_USER_SWITCHED;
 import static android.location.LocationManager.GPS_PROVIDER;
 import static android.location.LocationManager.NETWORK_PROVIDER;
+import static android.location.LocationRequest.QUALITY_HIGH_ACCURACY;
 import static android.location.LocationRequest.QUALITY_LOW_POWER;
 import static android.location.provider.ProviderProperties.ACCURACY_FINE;
 import static android.location.provider.ProviderProperties.POWER_USAGE_LOW;
@@ -34,6 +35,7 @@
 import android.location.LocationListener;
 import android.location.LocationManager;
 import android.location.LocationRequest;
+import android.location.flags.Flags;
 import android.location.provider.LocationProviderBase;
 import android.location.provider.ProviderProperties;
 import android.location.provider.ProviderRequest;
@@ -61,6 +63,9 @@
                 .build();
 
     private static final long MAX_LOCATION_COMPARISON_NS = 11 * 1000000000L; // 11 seconds
+    // Maximum request interval at which we will activate GPS (because GPS sometimes consumes
+    // excessive power with large intervals).
+    private static final long MAX_GPS_INTERVAL_MS = 5 * 1000; // 5 seconds
 
     private final Object mLock = new Object();
 
@@ -165,8 +170,13 @@
             mNlpPresent = mLocationManager.hasProvider(NETWORK_PROVIDER);
         }
 
+        boolean requestAllowsGps =
+                Flags.limitFusedGps()
+                    ? mRequest.getQuality() == QUALITY_HIGH_ACCURACY
+                        && mRequest.getIntervalMillis() <= MAX_GPS_INTERVAL_MS
+                    : !mNlpPresent || mRequest.getQuality() < QUALITY_LOW_POWER;
         long gpsInterval =
-                mGpsPresent && (!mNlpPresent || mRequest.getQuality() < QUALITY_LOW_POWER)
+                mGpsPresent && requestAllowsGps
                         ? mRequest.getIntervalMillis() : INTERVAL_DISABLED;
         long networkInterval = mNlpPresent ? mRequest.getIntervalMillis() : INTERVAL_DISABLED;
 
diff --git a/packages/PackageInstaller/TEST_MAPPING b/packages/PackageInstaller/TEST_MAPPING
index 5033101..716845c 100644
--- a/packages/PackageInstaller/TEST_MAPPING
+++ b/packages/PackageInstaller/TEST_MAPPING
@@ -23,6 +23,28 @@
       ]
     },
     {
+      "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases",
+      "options":[
+          {
+            "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+            "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
+    },
+    {
+      "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases",
+      "options":[
+          {
+            "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+            "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
+    },
+    {
       "name": "CtsPackageInstallerCUJMultiUsersTestCases",
       "options":[
         {
@@ -120,6 +142,28 @@
       ]
     },
     {
+      "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases",
+      "options":[
+          {
+            "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+            "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
+    },
+    {
+      "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases",
+      "options":[
+          {
+            "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+            "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
+    },
+    {
       "name": "CtsPackageInstallerCUJMultiUsersTestCases",
       "options":[
         {
diff --git a/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java b/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
index be711ac..89e5372 100644
--- a/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
+++ b/packages/SettingsLib/ButtonPreference/src/com/android/settingslib/widget/ButtonPreference.java
@@ -27,6 +27,7 @@
 import android.widget.LinearLayout;
 
 import androidx.annotation.GravityInt;
+import androidx.annotation.IntDef;
 import androidx.preference.Preference;
 import androidx.preference.PreferenceViewHolder;
 
@@ -34,21 +35,46 @@
 
 import com.google.android.material.button.MaterialButton;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
 /**
  * A preference handled a button
  */
 public class ButtonPreference extends Preference implements GroupSectionDividerMixin {
 
+    public static final int TYPE_FILLED = 0;
+    public static final int TYPE_TONAL = 1;
+    public static final int TYPE_OUTLINE = 2;
+
+    @IntDef({TYPE_FILLED, TYPE_TONAL, TYPE_OUTLINE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {
+    }
+
+    public static final int SIZE_NORMAL = 0;
+    public static final int SIZE_LARGE = 1;
+    public static final int SIZE_EXTRA_LARGE = 2;
+
+    @IntDef({SIZE_NORMAL, SIZE_LARGE, SIZE_EXTRA_LARGE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Size {
+    }
+
     enum ButtonStyle {
-        FILLED_NORMAL(0, 0, R.layout.settingslib_expressive_button_filled),
-        FILLED_LARGE(0, 1, R.layout.settingslib_expressive_button_filled_large),
-        FILLED_EXTRA(0, 2, R.layout.settingslib_expressive_button_filled_extra),
-        TONAL_NORMAL(1, 0, R.layout.settingslib_expressive_button_tonal),
-        TONAL_LARGE(1, 1, R.layout.settingslib_expressive_button_tonal_large),
-        TONAL_EXTRA(1, 2, R.layout.settingslib_expressive_button_tonal_extra),
-        OUTLINE_NORMAL(2, 0, R.layout.settingslib_expressive_button_outline),
-        OUTLINE_LARGE(2, 1, R.layout.settingslib_expressive_button_outline_large),
-        OUTLINE_EXTRA(2, 2, R.layout.settingslib_expressive_button_outline_extra);
+        FILLED_NORMAL(TYPE_FILLED, SIZE_NORMAL, R.layout.settingslib_expressive_button_filled),
+        FILLED_LARGE(TYPE_FILLED, SIZE_LARGE, R.layout.settingslib_expressive_button_filled_large),
+        FILLED_EXTRA(TYPE_FILLED, SIZE_EXTRA_LARGE,
+                R.layout.settingslib_expressive_button_filled_extra),
+        TONAL_NORMAL(TYPE_TONAL, SIZE_NORMAL, R.layout.settingslib_expressive_button_tonal),
+        TONAL_LARGE(TYPE_TONAL, SIZE_LARGE, R.layout.settingslib_expressive_button_tonal_large),
+        TONAL_EXTRA(TYPE_TONAL, SIZE_EXTRA_LARGE,
+                R.layout.settingslib_expressive_button_tonal_extra),
+        OUTLINE_NORMAL(TYPE_OUTLINE, SIZE_NORMAL, R.layout.settingslib_expressive_button_outline),
+        OUTLINE_LARGE(TYPE_OUTLINE, SIZE_LARGE,
+                R.layout.settingslib_expressive_button_outline_large),
+        OUTLINE_EXTRA(TYPE_OUTLINE, SIZE_EXTRA_LARGE,
+                R.layout.settingslib_expressive_button_outline_extra);
 
         private final int mType;
         private final int mSize;
@@ -60,7 +86,7 @@
             this.mLayoutId = layoutId;
         }
 
-        static int getLayoutId(int type, int size) {
+        static int getLayoutId(@Type int type, @Size int size) {
             for (ButtonStyle style : values()) {
                 if (style.mType == type && style.mSize == size) {
                     return style.mLayoutId;
@@ -266,7 +292,7 @@
      *                 <li>2: extra large</li>
      *             </ul>
      */
-    public void setButtonStyle(int type, int size) {
+    public void setButtonStyle(@Type int type, @Size int size) {
         int layoutId = ButtonStyle.getLayoutId(type, size);
         setLayoutResource(layoutId);
         notifyChanged();
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml
index 3db0ac6..b1e42c0 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/res/layout-v36/settingslib_expressive_collapsing_toolbar_content_layout.xml
@@ -35,6 +35,7 @@
             android:layout_height="@dimen/settingslib_toolbar_layout_height"
             app:layout_scrollFlags="scroll|exitUntilCollapsed|snap"
             app:toolbarId="@id/action_bar"
+            app:maxLines="2"
             style="@style/SettingsLibCollapsingToolbarLayoutStyle.Expressive">
 
             <Toolbar
@@ -44,7 +45,24 @@
                 android:layout_marginStart="@dimen/settingslib_expressive_space_extrasmall4"
                 android:theme="?android:attr/actionBarTheme"
                 android:transitionName="shared_element_view"
-                app:layout_collapseMode="pin"/>
+                app:layout_collapseMode="pin">
+
+                <LinearLayout
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:paddingStart="@dimen/settingslib_expressive_space_extrasmall6"
+                    android:layout_marginEnd="@dimen/settingslib_expressive_space_small4"
+                    android:layout_gravity="end">
+
+                    <com.google.android.material.button.MaterialButton
+                        android:id="@+id/action_button"
+                        android:layout_width="wrap_content"
+                        android:layout_height="match_parent"
+                        style="@style/SettingsLibButtonStyle.Expressive.Filled"
+                        android:visibility="gone"/>
+                </LinearLayout>
+
+            </Toolbar>
 
         </com.google.android.material.appbar.CollapsingToolbarLayout>
     </com.google.android.material.appbar.AppBarLayout>
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
index feacecb..ec1df44 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarAppCompatActivity.java
@@ -24,6 +24,7 @@
 import android.view.ViewGroup;
 import android.widget.Toolbar;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
 
@@ -132,6 +133,29 @@
         setTitle(getText(titleId));
     }
 
+    /**
+     * Show/Hide the action button on the Toolbar.
+     * @param enabled true to show the button, otherwise it's hidden.
+     */
+    public void setActionButtonEnabled(boolean enabled) {
+        getToolbarDelegate().setActionButtonEnabled(enabled);
+    }
+
+    /** Set the icon to the action button */
+    public void setActionButtonIcon(@DrawableRes int drawableRes) {
+        getToolbarDelegate().setActionButtonIcon(this, drawableRes);
+    }
+
+    /** Set the text to the action button */
+    public void setActionButtonText(@Nullable CharSequence text) {
+        getToolbarDelegate().setActionButtonText(text);
+    }
+
+    /** Set the OnClick listener to the action button */
+    public void setActionButtonListener(@Nullable View.OnClickListener listener) {
+        getToolbarDelegate().setActionButtonOnClickListener(listener);
+    }
+
     @Override
     public boolean onSupportNavigateUp() {
         if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
index 0f9d94e..b1b8c98 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarBaseActivity.java
@@ -25,6 +25,7 @@
 import android.view.ViewGroup;
 import android.widget.Toolbar;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.Nullable;
 import androidx.fragment.app.FragmentActivity;
 
@@ -124,6 +125,29 @@
         setTitle(getText(titleId));
     }
 
+    /**
+     * Show/Hide the action button on the Toolbar.
+     * @param enabled true to show the button, otherwise it's hidden.
+     */
+    public void setActionButtonEnabled(boolean enabled) {
+        getToolbarDelegate().setActionButtonEnabled(enabled);
+    }
+
+    /** Set the icon to the action button */
+    public void setActionButtonIcon(@DrawableRes int drawableRes) {
+        getToolbarDelegate().setActionButtonIcon(this, drawableRes);
+    }
+
+    /** Set the text to the action button */
+    public void setActionButtonText(@Nullable CharSequence text) {
+        getToolbarDelegate().setActionButtonText(text);
+    }
+
+    /** Set the OnClick listener to the action button */
+    public void setActionButtonListener(@Nullable View.OnClickListener listener) {
+        getToolbarDelegate().setActionButtonOnClickListener(listener);
+    }
+
     @Override
     public boolean onNavigateUp() {
         if (getSupportFragmentManager().getBackStackEntryCount() > 0) {
diff --git a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
index de0d609..072b365 100644
--- a/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
+++ b/packages/SettingsLib/CollapsingToolbarBaseActivity/src/com/android/settingslib/collapsingtoolbar/CollapsingToolbarDelegate.java
@@ -33,6 +33,7 @@
 import android.widget.FrameLayout;
 import android.widget.Toolbar;
 
+import androidx.annotation.DrawableRes;
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.appcompat.app.AppCompatActivity;
@@ -42,6 +43,7 @@
 
 import com.google.android.material.appbar.AppBarLayout;
 import com.google.android.material.appbar.CollapsingToolbarLayout;
+import com.google.android.material.button.MaterialButton;
 
 /**
  * A delegate that allows to use the collapsing toolbar layout in hosts that doesn't want/need to
@@ -80,6 +82,8 @@
     private AppBarLayout mAppBarLayout;
     @NonNull
     private Toolbar mToolbar;
+    @Nullable
+    private MaterialButton mActionButton;
     @NonNull
     private FrameLayout mContentFrameLayout;
     @NonNull
@@ -154,6 +158,7 @@
         }
         autoSetCollapsingToolbarLayoutScrolling();
         mContentFrameLayout = view.findViewById(R.id.content_frame);
+        mActionButton = view.findViewById(R.id.action_button);
         if (activity instanceof AppCompatActivity) {
             Log.d(TAG, "onCreateView: from AppCompatActivity and sub-class.");
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
@@ -215,6 +220,42 @@
         }
     }
 
+    /**
+     * Show/Hide the action button on the Toolbar.
+     * @param enabled true to show the button, otherwise it's hidden.
+     */
+    public void setActionButtonEnabled(boolean enabled) {
+        if (mActionButton == null) {
+            return;
+        }
+        int visibility = enabled ? View.VISIBLE : View.GONE;
+        mActionButton.setVisibility(visibility);
+    }
+
+    /** Set the icon to the action button */
+    public void setActionButtonIcon(@NonNull Context context, @DrawableRes int drawableRes) {
+        if (mActionButton == null) {
+            return;
+        }
+        mActionButton.setIcon(context.getResources().getDrawable(drawableRes, context.getTheme()));
+    }
+
+    /** Set the text to the action button */
+    public void setActionButtonText(@Nullable CharSequence text) {
+        if (mActionButton == null) {
+            return;
+        }
+        mActionButton.setText(text);
+    }
+
+    /** Set the OnClick listener to the action button */
+    public void setActionButtonOnClickListener(@Nullable View.OnClickListener listener) {
+        if (mActionButton == null) {
+            return;
+        }
+        mActionButton.setOnClickListener(listener);
+    }
+
     /** Return an instance of CoordinatorLayout. */
     @Nullable
     public CoordinatorLayout getCoordinatorLayout() {
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
index 472ffa9..6dec2f9 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyValueStore.kt
@@ -17,6 +17,7 @@
 package com.android.settingslib.datastore
 
 import android.content.SharedPreferences
+import android.util.Log
 
 /** Interface of key-value store. */
 interface KeyValueStore : KeyedObservable<String> {
@@ -80,6 +81,27 @@
     fun setString(key: String, value: String?) = setValue(key, String::class.javaObjectType, value)
 }
 
+/** Delegation of [KeyValueStore]. */
+interface KeyValueStoreDelegate : KeyValueStore, KeyedObservableDelegate<String> {
+
+    /** [KeyValueStore] to delegate. */
+    val keyValueStoreDelegate: KeyValueStore
+
+    override val keyedObservableDelegate
+        get() = keyValueStoreDelegate
+
+    override fun contains(key: String) = keyValueStoreDelegate.contains(key)
+
+    override fun <T : Any> getDefaultValue(key: String, valueType: Class<T>) =
+        keyValueStoreDelegate.getDefaultValue(key, valueType)
+
+    override fun <T : Any> getValue(key: String, valueType: Class<T>) =
+        keyValueStoreDelegate.getValue(key, valueType) ?: getDefaultValue(key, valueType)
+
+    override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) =
+        keyValueStoreDelegate.setValue(key, valueType, value)
+}
+
 /** [SharedPreferences] based [KeyValueStore]. */
 interface SharedPreferencesKeyValueStore : KeyValueStore {
 
@@ -103,11 +125,11 @@
 
     @Suppress("UNCHECKED_CAST")
     override fun <T : Any> setValue(key: String, valueType: Class<T>, value: T?) {
+        val edit = sharedPreferences.edit()
         if (value == null) {
-            sharedPreferences.edit().remove(key).apply()
+            edit.remove(key).apply()
             return
         }
-        val edit = sharedPreferences.edit()
         when (valueType) {
             Boolean::class.javaObjectType -> edit.putBoolean(key, value as Boolean)
             Float::class.javaObjectType -> edit.putFloat(key, value as Float)
@@ -115,7 +137,7 @@
             Long::class.javaObjectType -> edit.putLong(key, value as Long)
             String::class.javaObjectType -> edit.putString(key, value as String)
             Set::class.javaObjectType -> edit.putStringSet(key, value as Set<String>)
-            else -> {}
+            else -> Log.e(LOG_TAG, "Unsupported $valueType for $key: $value")
         }
         edit.apply()
     }
diff --git a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt
index 07b1c9e..ff58bf7 100644
--- a/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt
+++ b/packages/SettingsLib/DataStore/src/com/android/settingslib/datastore/KeyedObserver.kt
@@ -116,8 +116,28 @@
 }
 
 /** Delegation of [KeyedObservable]. */
-open class KeyedObservableDelegate<K>(delegate: KeyedObservable<K>) :
-    KeyedObservable<K> by delegate
+interface KeyedObservableDelegate<K> : KeyedObservable<K> {
+
+    /** [KeyedObservable] to delegate. */
+    val keyedObservableDelegate: KeyedObservable<K>
+
+    override fun addObserver(observer: KeyedObserver<K?>, executor: Executor): Boolean =
+        keyedObservableDelegate.addObserver(observer, executor)
+
+    override fun addObserver(key: K, observer: KeyedObserver<K>, executor: Executor): Boolean =
+        keyedObservableDelegate.addObserver(key, observer, executor)
+
+    override fun removeObserver(observer: KeyedObserver<K?>): Boolean =
+        keyedObservableDelegate.removeObserver(observer)
+
+    override fun removeObserver(key: K, observer: KeyedObserver<K>): Boolean =
+        keyedObservableDelegate.removeObserver(key, observer)
+
+    override fun notifyChange(reason: Int): Unit = keyedObservableDelegate.notifyChange(reason)
+
+    override fun notifyChange(key: K, reason: Int): Unit =
+        keyedObservableDelegate.notifyChange(key, reason)
+}
 
 /** A thread safe implementation of [KeyedObservable]. */
 open class KeyedDataObservable<K> : KeyedObservable<K> {
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManager.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManager.kt
new file mode 100644
index 0000000..fdde3d3
--- /dev/null
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManager.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.devicestate
+
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK
+
+/**
+ * Interface for managing [DEVICE_STATE_ROTATION_LOCK] setting.
+ *
+ * It provides methods to register/unregister listeners for setting changes, update the setting for
+ * specific device states, retrieve the setting value, and check if rotation is locked for specific
+ * or all device states.
+ */
+interface DeviceStateAutoRotateSettingManager {
+    // TODO: b/397928958 - Rename all terms from rotationLock to autoRotate in all apis.
+
+    /** Listener for changes in device-state based auto rotate setting. */
+    interface DeviceStateAutoRotateSettingListener {
+        /** Called whenever the setting has changed. */
+        fun onSettingsChanged()
+    }
+
+    /** Register listener for changes to [DEVICE_STATE_ROTATION_LOCK] setting. */
+    fun registerListener(settingListener: DeviceStateAutoRotateSettingListener)
+
+    /** Unregister listener for changes to [DEVICE_STATE_ROTATION_LOCK] setting. */
+    fun unregisterListener(settingListener: DeviceStateAutoRotateSettingListener)
+
+    /**
+     * Write [deviceState]'s setting value as [autoRotate], for [DEVICE_STATE_ROTATION_LOCK] setting.
+     */
+    fun updateSetting(deviceState: Int, autoRotate: Boolean)
+
+    /** Get [DEVICE_STATE_ROTATION_LOCK] setting value for [deviceState]. */
+    fun getRotationLockSetting(deviceState: Int): Int
+
+    /** Returns true if auto-rotate setting is OFF for [deviceState]. */
+    fun isRotationLocked(deviceState: Int): Boolean
+
+    /** Returns true if the auto-rotate setting value for all device states is OFF. */
+    fun isRotationLockedForAllStates(): Boolean
+
+    /** Returns a list of device states and their respective auto rotate setting availability. */
+    fun getSettableDeviceStates(): List<SettableDeviceState>
+}
+
+/** Represents a device state and whether it has an auto-rotation setting. */
+data class SettableDeviceState(
+    /** Returns the device state associated with this object. */
+    val deviceState: Int,
+    /** Returns whether there is an auto-rotation setting for this device state. */
+    val isSettable: Boolean
+)
+
+
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerImpl.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerImpl.kt
new file mode 100644
index 0000000..0b6c6e2
--- /dev/null
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingManagerImpl.kt
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.settingslib.devicestate
+
+import android.content.Context
+import android.database.ContentObserver
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_LOCKED
+import android.util.Log
+import android.util.SparseIntArray
+import com.android.internal.R
+import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager.DeviceStateAutoRotateSettingListener
+import com.android.window.flags.Flags
+import java.util.concurrent.Executor
+
+/**
+ * Implementation of [DeviceStateAutoRotateSettingManager]. This implementation is a part of
+ * refactoring, it should be used when [Flags.FLAG_ENABLE_DEVICE_STATE_AUTO_ROTATE_SETTING_REFACTOR]
+ * is enabled.
+ */
+class DeviceStateAutoRotateSettingManagerImpl(
+    context: Context,
+    backgroundExecutor: Executor,
+    private val secureSettings: SecureSettings,
+    private val mainHandler: Handler,
+    private val posturesHelper: PosturesHelper,
+) : DeviceStateAutoRotateSettingManager {
+    // TODO: b/397928958 rename the fields and apis from rotationLock to autoRotate.
+
+    private val settingListeners: MutableList<DeviceStateAutoRotateSettingListener> =
+        mutableListOf()
+    private val fallbackPostureMap = SparseIntArray()
+    private val settableDeviceState: MutableList<SettableDeviceState> = mutableListOf()
+
+    private val autoRotateSettingValue: String
+        get() = secureSettings.getStringForUser(DEVICE_STATE_ROTATION_LOCK, UserHandle.USER_CURRENT)
+
+    init {
+        loadAutoRotateDeviceStates(context)
+        val contentObserver =
+            object : ContentObserver(mainHandler) {
+                override fun onChange(selfChange: Boolean) = notifyListeners()
+            }
+        backgroundExecutor.execute {
+            secureSettings.registerContentObserver(
+                DEVICE_STATE_ROTATION_LOCK, false, contentObserver, UserHandle.USER_CURRENT
+            )
+        }
+    }
+
+    override fun registerListener(settingListener: DeviceStateAutoRotateSettingListener) {
+        settingListeners.add(settingListener)
+    }
+
+    override fun unregisterListener(settingListener: DeviceStateAutoRotateSettingListener) {
+        if (!settingListeners.remove(settingListener)) {
+            Log.w(TAG, "Attempting to unregister a listener hadn't been registered")
+        }
+    }
+
+    override fun getRotationLockSetting(deviceState: Int): Int {
+        val devicePosture = posturesHelper.deviceStateToPosture(deviceState)
+        val serializedSetting = autoRotateSettingValue
+        val autoRotateSetting = extractSettingForDevicePosture(devicePosture, serializedSetting)
+
+        // If the setting is ignored for this posture, check the fallback posture.
+        if (autoRotateSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) {
+            val fallbackPosture =
+                fallbackPostureMap.get(devicePosture, DEVICE_STATE_ROTATION_LOCK_IGNORED)
+            return extractSettingForDevicePosture(fallbackPosture, serializedSetting)
+        }
+
+        return autoRotateSetting
+    }
+
+    override fun isRotationLocked(deviceState: Int) =
+        getRotationLockSetting(deviceState) == DEVICE_STATE_ROTATION_LOCK_LOCKED
+
+    override fun isRotationLockedForAllStates(): Boolean =
+        convertSerializedSettingToMap(autoRotateSettingValue).all { (_, value) ->
+            value == DEVICE_STATE_ROTATION_LOCK_LOCKED
+        }
+
+    override fun getSettableDeviceStates(): List<SettableDeviceState> = settableDeviceState
+
+    override fun updateSetting(deviceState: Int, autoRotate: Boolean) {
+        // TODO: b/350946537 - Create IPC to update the setting, and call it here.
+        throw UnsupportedOperationException("API updateSetting is not implemented yet")
+    }
+
+    private fun notifyListeners() =
+        settingListeners.forEach { listener -> listener.onSettingsChanged() }
+
+    private fun loadAutoRotateDeviceStates(context: Context) {
+        val perDeviceStateAutoRotateDefaults =
+            context.resources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults)
+        for (entry in perDeviceStateAutoRotateDefaults) {
+            entry.parsePostureEntry()?.let { (posture, autoRotate, fallbackPosture) ->
+                if (autoRotate == DEVICE_STATE_ROTATION_LOCK_IGNORED && fallbackPosture != null) {
+                    fallbackPostureMap.put(posture, fallbackPosture)
+                }
+                settableDeviceState.add(
+                    SettableDeviceState(posture, autoRotate != DEVICE_STATE_ROTATION_LOCK_IGNORED)
+                )
+            }
+        }
+    }
+
+    private fun convertSerializedSettingToMap(serializedSetting: String): Map<Int, Int> {
+        if (serializedSetting.isEmpty()) return emptyMap()
+        return try {
+            serializedSetting
+                .split(SEPARATOR_REGEX)
+                .hasEvenSize()
+                .chunked(2)
+                .mapNotNull(::parsePostureSettingPair)
+                .toMap()
+        } catch (e: Exception) {
+            Log.w(
+                TAG,
+                "Invalid format in serializedSetting=$serializedSetting: ${e.message}"
+            )
+            return emptyMap()
+        }
+    }
+
+    private fun List<String>.hasEvenSize(): List<String> {
+        if (this.size % 2 != 0) {
+            throw IllegalStateException("Odd number of elements in the list")
+        }
+        return this
+    }
+
+    private fun parsePostureSettingPair(settingPair: List<String>): Pair<Int, Int>? {
+        return settingPair.let { (keyStr, valueStr) ->
+            val key = keyStr.toIntOrNull()
+            val value = valueStr.toIntOrNull()
+            if (key != null && value != null && value in 0..2) {
+                key to value
+            } else {
+                Log.w(TAG, "Invalid key or value in pair: $keyStr, $valueStr")
+                null // Invalid pair, skip it
+            }
+        }
+    }
+
+    private fun extractSettingForDevicePosture(
+        devicePosture: Int,
+        serializedSetting: String
+    ): Int =
+        convertSerializedSettingToMap(serializedSetting)[devicePosture]
+            ?: DEVICE_STATE_ROTATION_LOCK_IGNORED
+
+    private fun String.parsePostureEntry(): Triple<Int, Int, Int?>? {
+        val values = split(SEPARATOR_REGEX)
+        if (values.size !in 2..3) { // It should contain 2 or 3 values.
+            Log.w(TAG, "Invalid number of values in entry: '$this'")
+            return null
+        }
+        return try {
+            val posture = values[0].toInt()
+            val rotationLockSetting = values[1].toInt()
+            val fallbackPosture = if (values.size == 3) values[2].toIntOrNull() else null
+            Triple(posture, rotationLockSetting, fallbackPosture)
+        } catch (e: NumberFormatException) {
+            Log.w(TAG, "Invalid number format in '$this': ${e.message}")
+            null
+        }
+    }
+
+    companion object {
+        private const val TAG = "DeviceStateAutoRotate"
+        private const val SEPARATOR_REGEX = ":"
+    }
+}
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingUtils.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingUtils.kt
new file mode 100644
index 0000000..4d1d292
--- /dev/null
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateAutoRotateSettingUtils.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+@file:JvmName("DeviceStateAutoRotateSettingUtils")
+
+package com.android.settingslib.devicestate
+
+import android.content.Context
+import com.android.internal.R
+
+/** Returns true if device-state based rotation lock settings are enabled. */
+object DeviceStateAutoRotateSettingUtils {
+    @JvmStatic
+    fun isDeviceStateRotationLockEnabled(context: Context) =
+        context.resources
+            .getStringArray(R.array.config_perDeviceStateRotationLockDefaults)
+            .isNotEmpty()
+}
+
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
index 635f690..deeba57 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
@@ -20,6 +20,8 @@
 import static android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_LOCKED;
 import static android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_UNLOCKED;
 
+import static com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager.DeviceStateAutoRotateSettingListener;
+
 import android.annotation.Nullable;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -43,7 +45,6 @@
 import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -58,7 +59,7 @@
     private static DeviceStateRotationLockSettingsManager sSingleton;
 
     private final Handler mMainHandler = new Handler(Looper.getMainLooper());
-    private final Set<DeviceStateRotationLockSettingsListener> mListeners = new HashSet<>();
+    private final Set<DeviceStateAutoRotateSettingListener> mListeners = new HashSet<>();
     private final SecureSettings mSecureSettings;
     private final PosturesHelper mPosturesHelper;
     private String[] mPostureRotationLockDefaults;
@@ -127,20 +128,20 @@
     }
 
     /**
-     * Registers a {@link DeviceStateRotationLockSettingsListener} to be notified when the settings
+     * Registers a {@link DeviceStateAutoRotateSettingListener} to be notified when the settings
      * change. Can be called multiple times with different listeners.
      */
-    public void registerListener(DeviceStateRotationLockSettingsListener runnable) {
+    public void registerListener(DeviceStateAutoRotateSettingListener runnable) {
         mListeners.add(runnable);
     }
 
     /**
-     * Unregisters a {@link DeviceStateRotationLockSettingsListener}. No-op if the given instance
+     * Unregisters a {@link DeviceStateAutoRotateSettingListener}. No-op if the given instance
      * was never registered.
      */
     public void unregisterListener(
-            DeviceStateRotationLockSettingsListener deviceStateRotationLockSettingsListener) {
-        if (!mListeners.remove(deviceStateRotationLockSettingsListener)) {
+            DeviceStateAutoRotateSettingListener deviceStateAutoRotateSettingListener) {
+        if (!mListeners.remove(deviceStateAutoRotateSettingListener)) {
             Log.w(TAG, "Attempting to unregister a listener hadn't been registered");
         }
     }
@@ -379,56 +380,8 @@
     }
 
     private void notifyListeners() {
-        for (DeviceStateRotationLockSettingsListener r : mListeners) {
+        for (DeviceStateAutoRotateSettingListener r : mListeners) {
             r.onSettingsChanged();
         }
     }
-
-    /** Listener for changes in device-state based rotation lock settings */
-    public interface DeviceStateRotationLockSettingsListener {
-        /** Called whenever the settings have changed. */
-        void onSettingsChanged();
-    }
-
-    /** Represents a device state and whether it has an auto-rotation setting. */
-    public static class SettableDeviceState {
-        private final int mDeviceState;
-        private final boolean mIsSettable;
-
-        SettableDeviceState(int deviceState, boolean isSettable) {
-            mDeviceState = deviceState;
-            mIsSettable = isSettable;
-        }
-
-        /** Returns the device state associated with this object. */
-        public int getDeviceState() {
-            return mDeviceState;
-        }
-
-        /** Returns whether there is an auto-rotation setting for this device state. */
-        public boolean isSettable() {
-            return mIsSettable;
-        }
-
-        @Override
-        public boolean equals(Object o) {
-            if (this == o) return true;
-            if (!(o instanceof SettableDeviceState)) return false;
-            SettableDeviceState that = (SettableDeviceState) o;
-            return mDeviceState == that.mDeviceState && mIsSettable == that.mIsSettable;
-        }
-
-        @Override
-        public int hashCode() {
-            return Objects.hash(mDeviceState, mIsSettable);
-        }
-
-        @Override
-        public String toString() {
-            return "SettableDeviceState{"
-                    + "mDeviceState=" + mDeviceState
-                    + ", mIsSettable=" + mIsSettable
-                    + '}';
-        }
-    }
 }
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/SecureSettings.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/SecureSettings.java
index 1052873..ea40e14 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/SecureSettings.java
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/SecureSettings.java
@@ -19,7 +19,7 @@
 import android.database.ContentObserver;
 
 /** Minimal wrapper interface around {@link android.provider.Settings.Secure} for easier testing. */
-interface SecureSettings {
+public interface SecureSettings {
 
     void putStringForUser(String name, String value, int userHandle);
 
diff --git a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
index 7bd4b3f..9d4c5c2 100644
--- a/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
+++ b/packages/SettingsLib/MainSwitchPreference/src/com/android/settingslib/widget/MainSwitchBar.java
@@ -113,8 +113,6 @@
             mSwitch.setOnCheckedChangeListener(this);
         }
 
-        setChecked(mSwitch.isChecked());
-
         if (attrs != null) {
             final TypedArray a = context.obtainStyledAttributes(attrs,
                     androidx.preference.R.styleable.Preference, 0 /*defStyleAttr*/,
@@ -130,8 +128,6 @@
             }
             a.recycle();
         }
-
-        setBackground(mSwitch.isChecked());
     }
 
     @Override
diff --git a/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml b/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml
index 686c148..112a69b 100644
--- a/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml
+++ b/packages/SettingsLib/SettingsTheme/res/values/styles_expressive.xml
@@ -262,4 +262,30 @@
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
     </style>
+
+    <style name="SettingsLibEntityHeaderContent">
+        <item name="android:layout_width">match_parent</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_centerHorizontal">true</item>
+        <item name="android:orientation">vertical</item>
+        <item name="android:gravity">center_horizontal</item>
+    </style>
+
+    <style name="SettingsLibEntityHeaderIcon">
+        <item name="android:layout_width">@dimen/settingslib_expressive_space_large3</item>
+        <item name="android:layout_height">@dimen/settingslib_expressive_space_large3</item>
+        <item name="android:scaleType">fitCenter</item>
+        <item name="android:antialias">true</item>
+    </style>
+
+    <style name="SettingsLibEntityHeaderTitle">
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginTop">@dimen/settingslib_expressive_space_small1</item>
+        <item name="android:singleLine">false</item>
+        <item name="android:gravity">center</item>
+        <item name="android:ellipsize">marquee</item>
+        <item name="android:textDirection">locale</item>
+        <item name="android:textAppearance">@style/TextAppearance.SettingsLib.TitleLarge.Emphasized</item>
+    </style>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java b/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java
index fe8e8b6..6d02c5d 100644
--- a/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java
+++ b/packages/SettingsLib/SliderPreference/src/com/android/settingslib/widget/SliderPreference.java
@@ -16,6 +16,8 @@
 
 package com.android.settingslib.widget;
 
+import static android.view.HapticFeedbackConstants.CLOCK_TICK;
+
 import android.content.Context;
 import android.content.res.ColorStateList;
 import android.content.res.Resources;
@@ -46,6 +48,9 @@
  */
 public class SliderPreference extends Preference {
     private static final String TAG = "SliderPreference";
+    public static final int HAPTIC_FEEDBACK_MODE_NONE = 0;
+    public static final int HAPTIC_FEEDBACK_MODE_ON_TICKS = 1;
+    public static final int HAPTIC_FEEDBACK_MODE_ON_ENDS = 2;
 
     private final int mTextStartId;
     private final int mTextEndId;
@@ -71,6 +76,8 @@
     private int mMin;
     private int mMax;
     private int mSliderIncrement;
+    private int mHapticFeedbackMode = HAPTIC_FEEDBACK_MODE_NONE;
+    private boolean mTickVisible = false;
     private boolean mAdjustable;
     private boolean mTrackingTouch;
     private CharSequence mSliderContentDescription;
@@ -265,6 +272,7 @@
         }
         if (mSliderIncrement != 0) {
             mSlider.setStepSize(mSliderIncrement);
+            mSlider.setTickVisible(mTickVisible);
         } else {
             mSliderIncrement = (int) (mSlider.getStepSize());
         }
@@ -442,6 +450,29 @@
     }
 
     /**
+     * Sets the haptic feedback mode. HAPTIC_FEEDBACK_MODE_ON_TICKS means to perform haptic feedback
+     * as the {@link Slider} value is updated; HAPTIC_FEEDBACK_MODE_ON_ENDS means to perform haptic
+     * feedback as the {@link Slider} value is equal to the min/max value.
+     *
+     * @param hapticFeedbackMode The haptic feedback mode.
+     */
+    public void setHapticFeedbackMode(int hapticFeedbackMode) {
+        mHapticFeedbackMode = hapticFeedbackMode;
+    }
+
+    /**
+     * Sets whether the tick marks are visible. Only used when the slider is in discrete mode.
+     *
+     * @param tickVisible The visibility of tick marks.
+     */
+    public void setTickVisible(boolean tickVisible) {
+        if (tickVisible != mTickVisible) {
+            mTickVisible = tickVisible;
+            notifyChanged();
+        }
+    }
+
+    /**
      * Gets whether the current {@link Slider} value is displayed to the user.
      *
      * @return Whether the current {@link Slider} value is displayed to the user
@@ -519,7 +550,16 @@
         if (sliderValue != mSliderValue) {
             if (callChangeListener(sliderValue)) {
                 setValueInternal(sliderValue, false);
-                // TODO: mHapticFeedbackMode
+                switch (mHapticFeedbackMode) {
+                    case HAPTIC_FEEDBACK_MODE_ON_TICKS:
+                        slider.performHapticFeedback(CLOCK_TICK);
+                        break;
+                    case HAPTIC_FEEDBACK_MODE_ON_ENDS:
+                        if (mSliderValue == mMax || mSliderValue == mMin) {
+                            slider.performHapticFeedback(CLOCK_TICK);
+                        }
+                        break;
+                }
             } else {
                 slider.setValue(mSliderValue);
             }
diff --git a/packages/SettingsLib/StatusBannerPreference/res/drawable/settingslib_expressive_icon_status_level_off.xml b/packages/SettingsLib/StatusBannerPreference/res/drawable/settingslib_expressive_icon_status_level_off.xml
new file mode 100644
index 0000000..6b534aa
--- /dev/null
+++ b/packages/SettingsLib/StatusBannerPreference/res/drawable/settingslib_expressive_icon_status_level_off.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+  Copyright (C) 2025 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="34dp"
+    android:height="42dp"
+    android:viewportWidth="34"
+    android:viewportHeight="42">
+    <path
+        android:pathData="M0.856,17.569C0.887,19.083 1.004,20.593 1.206,22.094C2.166,28.584 5.804,35.937 15.774,41.089C16.171,41.293 16.61,41.4 17.056,41.4C17.503,41.4 17.942,41.293 18.339,41.089C28.309,35.936 31.947,28.583 32.907,22.093C33.109,20.593 33.226,19.083 33.256,17.569V8.605C33.257,7.919 33.046,7.25 32.652,6.688C32.259,6.127 31.703,5.7 31.059,5.467L18.191,0.8C17.458,0.534 16.655,0.534 15.922,0.8L3.054,5.467C2.41,5.7 1.854,6.127 1.461,6.688C1.067,7.25 0.856,7.919 0.856,8.605V17.569Z"
+        android:fillColor="#D1C2CB"/>
+    <path
+        android:pathData="M15.067,24.333V10.733H18.933V24.333H15.067ZM15.067,31.267V27.433H18.933V31.267H15.067Z"
+        android:fillColor="@color/settingslib_materialColorSurfaceContainerLowest"/>
+</vector>
\ No newline at end of file
diff --git a/packages/SettingsLib/StatusBannerPreference/res/values/attrs.xml b/packages/SettingsLib/StatusBannerPreference/res/values/attrs.xml
index 54860d4..deda258 100644
--- a/packages/SettingsLib/StatusBannerPreference/res/values/attrs.xml
+++ b/packages/SettingsLib/StatusBannerPreference/res/values/attrs.xml
@@ -21,6 +21,7 @@
             <enum name="low" value="1"/>
             <enum name="medium" value="2"/>
             <enum name="high" value="3"/>
+            <enum name="off" value="4"/>
         </attr>
         <attr name="buttonLevel" format="enum">
             <enum name="generic" value="0"/>
diff --git a/packages/SettingsLib/StatusBannerPreference/res/values/colors.xml b/packages/SettingsLib/StatusBannerPreference/res/values/colors.xml
index 19181dd..abc458b 100644
--- a/packages/SettingsLib/StatusBannerPreference/res/values/colors.xml
+++ b/packages/SettingsLib/StatusBannerPreference/res/values/colors.xml
@@ -22,4 +22,5 @@
     <color name="settingslib_expressive_color_status_level_medium">#FCBD00</color>
     <!-- static palette red50 -->
     <color name="settingslib_expressive_color_status_level_high">#DB372D</color>
+    <color name="settingslib_expressive_color_status_level_off">#D1C2CB</color>
 </resources>
\ No newline at end of file
diff --git a/packages/SettingsLib/StatusBannerPreference/src/com/android/settingslib/widget/StatusBannerPreference.kt b/packages/SettingsLib/StatusBannerPreference/src/com/android/settingslib/widget/StatusBannerPreference.kt
index 1f8cfb5..eda281c 100644
--- a/packages/SettingsLib/StatusBannerPreference/src/com/android/settingslib/widget/StatusBannerPreference.kt
+++ b/packages/SettingsLib/StatusBannerPreference/src/com/android/settingslib/widget/StatusBannerPreference.kt
@@ -40,7 +40,8 @@
         GENERIC,
         LOW,
         MEDIUM,
-        HIGH
+        HIGH,
+        OFF
     }
     var iconLevel: BannerStatus = BannerStatus.GENERIC
         set(value) {
@@ -87,6 +88,7 @@
         1 -> BannerStatus.LOW
         2 -> BannerStatus.MEDIUM
         3 -> BannerStatus.HIGH
+        4 -> BannerStatus.OFF
         else -> BannerStatus.GENERIC
     }
 
@@ -104,7 +106,10 @@
         }
 
         (holder.findViewById(R.id.status_banner_button) as? MaterialButton)?.apply {
-            setBackgroundColor(getBackgroundColor(buttonLevel))
+            setBackgroundColor(
+                if (buttonLevel == BannerStatus.OFF) getBackgroundColor(BannerStatus.GENERIC)
+                else getBackgroundColor(buttonLevel)
+            )
             text = buttonText
             setOnClickListener(listener)
             visibility = if (listener != null) View.VISIBLE else View.GONE
@@ -143,6 +148,11 @@
                 R.color.settingslib_expressive_color_status_level_high
             )
 
+            BannerStatus.OFF -> ContextCompat.getColor(
+                context,
+                R.color.settingslib_expressive_color_status_level_off
+            )
+
             else -> ContextCompat.getColor(
                 context,
                 com.android.settingslib.widget.theme.R.color.settingslib_materialColorPrimary
@@ -167,6 +177,11 @@
                 R.drawable.settingslib_expressive_icon_status_level_high
             )
 
+            BannerStatus.OFF -> ContextCompat.getDrawable(
+                context,
+                R.drawable.settingslib_expressive_icon_status_level_off
+            )
+
             else -> null
         }
     }
@@ -188,6 +203,7 @@
                 R.drawable.settingslib_expressive_background_level_high
             )
 
+            // GENERIC and OFF are using the same background drawable.
             else -> ContextCompat.getDrawable(
                 context,
                 R.drawable.settingslib_expressive_background_generic
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
index 7f4bebc..3355266 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/Tile.java
@@ -46,6 +46,8 @@
 import android.text.TextUtils;
 import android.util.Log;
 
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
 
 import java.util.ArrayList;
@@ -326,6 +328,15 @@
         return false;
     }
 
+    /** Returns the icon color scheme. */
+    @Nullable
+    public String getIconColorScheme(@NonNull Context context) {
+        ensureMetadataNotStale(context);
+        return mMetaData != null
+                ? mMetaData.getString(TileUtils.META_DATA_PREFERENCE_ICON_COLOR_SCHEME, null)
+                : null;
+    }
+
     /** Whether the {@link Activity} should be launched in a separate task. */
     public boolean isNewTask() {
         if (mMetaData != null && mMetaData.containsKey(META_DATA_NEW_TASK)) {
diff --git a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
index ac0b9b4..d62ed2f 100644
--- a/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
+++ b/packages/SettingsLib/Tile/src/com/android/settingslib/drawer/TileUtils.java
@@ -135,6 +135,13 @@
     public static final String META_DATA_PREFERENCE_ICON = "com.android.settings.icon";
 
     /**
+     * Name of the meta-data item that should be set in the AndroidManifest.xml to specify the icon
+     * color scheme. Only available for preferences on the homepage.
+     */
+    public static final String META_DATA_PREFERENCE_ICON_COLOR_SCHEME =
+            "com.android.settings.icon_color_scheme";
+
+    /**
      * Name of the meta-data item that should be set in the AndroidManifest.xml
      * to specify the icon background color. The value may or may not be used by Settings app.
      */
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 58ddc72..f1859f2 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Beheer deur Beperkte Instellings"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Onbeskikbaar tydens oproepe"</string>
     <string name="disabled" msgid="8017887509554714950">"Gedeaktiveer"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Geaktiveer"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Toegelaat"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nie toegelaat nie"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Installeer onbekende apps"</string>
@@ -612,7 +611,7 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Hierdie foon"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
     <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analoog"</string>
-    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AANVULLENDE"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"Aanvullend"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Kan nie op hierdie toestel speel nie"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Gradeer rekening op om oor te skakel"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Kan nie aflaaie hier speel nie"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ingeboude luidspreker"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV-oudio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kan nie koppel nie. Skakel toestel af en weer aan"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedrade oudiotoestel"</string>
     <string name="help_label" msgid="3528360748637781274">"Hulp en terugvoer"</string>
     <string name="storage_category" msgid="2287342585424631813">"Berging"</string>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index 3844a4b..77009d74 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"በተገደበ ቅንብር ቁጥጥር የሚደረግበት"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"በጥሪዎች ጊዜ አይገኝም"</string>
     <string name="disabled" msgid="8017887509554714950">"ቦዝኗል"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ነቅቷል"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ይፈቀዳል"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"አይፈቀድም"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"ያልታወቁ መተግበሪያዎችን ይጫኑ"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"አብሮ የተሰራ ድምፅ ማውጫ"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"የTV ኦዲዮ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"መገናኘት ላይ ችግር። መሳሪያውን ያጥፉት እና እንደገና ያብሩት"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ባለገመድ የኦዲዮ መሣሪያ"</string>
     <string name="help_label" msgid="3528360748637781274">"እገዛ እና ግብረመልስ"</string>
     <string name="storage_category" msgid="2287342585424631813">"ማከማቻ"</string>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index 0d31c2e..a522e07 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"يتحكّم فيه إعداد محظور"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"غير متاح أثناء المكالمات"</string>
     <string name="disabled" msgid="8017887509554714950">"غير مفعّل"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"مفعّلة"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"تطبيق مسموح به"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"تطبيق غير مسموح به"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"تثبيت التطبيقات غير المعروفة"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"مكبِّر الصوت المُدمَج"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"صوت التلفزيون"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"حدثت مشكلة أثناء الاتصال. يُرجى إيقاف الجهاز ثم إعادة تشغيله."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"جهاز سماعي سلكي"</string>
     <string name="help_label" msgid="3528360748637781274">"المساعدة والملاحظات"</string>
     <string name="storage_category" msgid="2287342585424631813">"مساحة التخزين"</string>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 56f73df..0ed118b 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"প্ৰতিবন্ধিত ছেটিঙৰ দ্বাৰা নিয়ন্ত্ৰিত"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"কল চলি থকাৰ সময়ত উপলব্ধ নহয়"</string>
     <string name="disabled" msgid="8017887509554714950">"নিষ্ক্ৰিয়"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"সক্ষম কৰা আছে"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"অনুমতি দিয়া হৈছে"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"অনুমতি দিয়া হোৱা নাই"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"অজ্ঞাত এপ্ ইনষ্টল কৰক"</string>
@@ -612,7 +611,7 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"এই ফ’নটো"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
     <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"এনালগ"</string>
-    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"অক্স"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"এই ডিভাইচটো প্লে\' কৰিব নোৱাৰি"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"সলনি কৰিবলৈ একাউণ্ট আপগ্ৰে’ড কৰক"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ইয়াত ডাউনল’ডসমূহ প্লে’ কৰিব নোৱাৰি"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"বিল্ট-ইন স্পীকাৰ"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"টিভিৰ অডিঅ’"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"সংযোগ হোৱাত সমস্যা হৈছে। ডিভাইচটো অফ কৰি পুনৰ অন কৰক"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"তাঁৰযুক্ত অডিঅ’ ডিভাইচ"</string>
     <string name="help_label" msgid="3528360748637781274">"সহায় আৰু মতামত"</string>
     <string name="storage_category" msgid="2287342585424631813">"ষ্ট’ৰেজ"</string>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index b7dcfb8..6ba40f7 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Məhdudlaşdırılmış Ayar ilə nəzarət edilir"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Zənglər zamanı əlçatan deyil"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktiv"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Aktiv"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"İcazə verilib"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"İcazə verilməyib"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Tanınmayan tətbiqlərin quraşdırılması"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Daxili dinamik"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV audiosu"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Qoşulmaqla bağlı problem. Cihazı deaktiv edin, sonra yenidən aktiv edin"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio cihaz"</string>
     <string name="help_label" msgid="3528360748637781274">"Yardım və rəy"</string>
     <string name="storage_category" msgid="2287342585424631813">"Yaddaş"</string>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 97873e5..0ebeb55 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolišu ograničena podešavanja"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nedostupno tokom poziva"</string>
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Omogućeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dozvoljeno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dozvoljeno"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instaliranje nepoznatih aplikacija"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ugrađeni zvučnik"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvuk TV-a"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem pri povezivanju. Isključite uređaj, pa ga ponovo uključite"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
     <string name="storage_category" msgid="2287342585424631813">"Memorijski prostor"</string>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index 78a5eaf..8e1fd28 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Пад кіраваннем Абмежаванага наладжвання"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недаступна падчас выклікаў"</string>
     <string name="disabled" msgid="8017887509554714950">"Адключанае"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Уключана"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Дазволена"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Забаронена"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Усталёўка невядомых праграм"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Убудаваны дынамік"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аўдыя тэлевізара"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Праблема з падключэннем. Выключыце і зноў уключыце прыладу"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Правадная аўдыяпрылада"</string>
     <string name="help_label" msgid="3528360748637781274">"Даведка і водгукі"</string>
     <string name="storage_category" msgid="2287342585424631813">"Сховішча"</string>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 9fc0dea..bf10d1d 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Управлява се чрез ограничена настройка"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Заето по време на обаждания"</string>
     <string name="disabled" msgid="8017887509554714950">"Деактивирано"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Активирано"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Има разрешение"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Няма разрешение"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Инст. на неизвестни прилож."</string>
@@ -611,7 +610,7 @@
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Свързано устройство"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Този телефон"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
-    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогов"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналогов аудиоизход"</string>
     <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Възпроизвеждането не е възможно на това устройство"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Надстройте профила, за да превключите"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Вграден високоговорител"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аудио на телевизора"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"При свързването възникна проблем. Изключете устройството и го включете отново"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Аудиоустройство с кабел"</string>
     <string name="help_label" msgid="3528360748637781274">"Помощ и отзиви"</string>
     <string name="storage_category" msgid="2287342585424631813">"Хранилище"</string>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 79e4ed9..5f37d44 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"এটি বিধিনিষেধ সেটিং থেকে নিয়ন্ত্রণ করা হয়"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"কল চলাকালীন উপলভ্য হবে না"</string>
     <string name="disabled" msgid="8017887509554714950">"অক্ষম হয়েছে"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"চালু করা আছে"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"অনুমোদিত"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"অনুমোদিত নয়"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"অজানা অ্যাপ ইনস্টল করা"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"বিল্ট-ইন স্পিকার"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"টিভি অডিও"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"কানেক্ট করতে সমস্যা হচ্ছে। ডিভাইস বন্ধ করে আবার চালু করুন"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ওয়্যার অডিও ডিভাইস"</string>
     <string name="help_label" msgid="3528360748637781274">"সহায়তা ও মতামত"</string>
     <string name="storage_category" msgid="2287342585424631813">"স্টোরেজ"</string>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index d06ce34..8cc8199 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolira ograničena postavka"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nije dostupno tokom poziva"</string>
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Omogućeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dozvoljeno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dozvoljeno"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instaliranje nepoznatih aplikacija"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ugrađeni zvučnik"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvuk TV-a"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Došlo je do problema prilikom povezivanja. Isključite, pa ponovo uključite uređaj"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audio uređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
     <string name="storage_category" msgid="2287342585424631813">"Pohrana"</string>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index 776caae..ee683e5 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlat per l\'opció de configuració restringida"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"No està disponible durant les trucades"</string>
     <string name="disabled" msgid="8017887509554714950">"Desactivat"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Activat"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Amb permís"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Sense permís"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instal·la aplicacions desconegudes"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altaveu integrat"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Àudio de la televisió"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Hi ha hagut un problema amb la connexió. Apaga el dispositiu i torna\'l a encendre."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositiu d\'àudio amb cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda i suggeriments"</string>
     <string name="storage_category" msgid="2287342585424631813">"Emmagatzematge"</string>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index 02722fd..58cdc19 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Spravováno omezeným nastavením"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Při volání nedostupné"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktivováno"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Zapnuto"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Povoleno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Není povoleno"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalace neznámých aplikací"</string>
@@ -611,7 +610,7 @@
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Připojené zařízení"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Tento telefon"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
-    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogové"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogový výstup"</string>
     <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"V zařízení nelze přehrávat"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Účet je třeba upgradovat"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Vestavěný reproduktor"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvuk televize"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problém s připojením. Vypněte zařízení a znovu jej zapněte"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kabelové audiozařízení"</string>
     <string name="help_label" msgid="3528360748637781274">"Nápověda a zpětná vazba"</string>
     <string name="storage_category" msgid="2287342585424631813">"Úložiště"</string>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 4d37578..257f673 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Styres af en begrænset indstilling"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Kan ikke bruges under opkald"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktiveret"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Aktiveret"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Tilladt"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ikke tilladt"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Installer ukendte apps"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Indbygget højttaler"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV-lyd"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Der kunne ikke oprettes forbindelse. Sluk og tænd enheden"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhed med ledning"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjælp og feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Lager"</string>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index 3e57002..8bfaa0e 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Gesteuert durch eingeschränkte Einstellung"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Während Anrufen nicht verfügbar"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktiviert"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Aktiviert"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Zugelassen"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nicht zugelassen"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Installieren unbekannter Apps"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Integrierter Lautsprecher"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV‑Audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Verbindung kann nicht hergestellt werden. Schalte das Gerät aus und wieder ein."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Netzbetriebenes Audiogerät"</string>
     <string name="help_label" msgid="3528360748637781274">"Hilfe und Feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Speicher"</string>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index be11356..83fb6ff 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ελέγχεται από τη Ρύθμιση με περιορισμό"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Μη διαθέσιμη κατά τη διάρκεια κλήσεων"</string>
     <string name="disabled" msgid="8017887509554714950">"Απενεργοποιημένη"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Ενεργό"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Επιτρέπεται"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Δεν επιτρέπεται"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Εγκατ. άγνωστων εφ."</string>
@@ -611,7 +610,7 @@
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Συνδεδεμένη συσκευή"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Αυτό το τηλέφ."</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
-    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Αναλογικός"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Αναλογική έξοδος"</string>
     <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Δεν είναι δυνατή η αναπαραγωγή σε αυτήν τη συσκευή"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Αναβαθμίστε τον λογαριασμό για εναλλαγή"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ενσωματωμένο ηχείο"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Ήχος τηλεόρασης"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Πρόβλημα κατά τη σύνδεση. Απενεργοποιήστε τη συσκευή και ενεργοποιήστε την ξανά"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ενσύρματη συσκευή ήχου"</string>
     <string name="help_label" msgid="3528360748637781274">"Βοήθεια και σχόλια"</string>
     <string name="storage_category" msgid="2287342585424631813">"Αποθηκευτικός χώρος"</string>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index 8c819ac..e2e3851 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Unavailable during calls"</string>
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Enabled"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Install unknown apps"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in speaker"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 2faf2fe..002b104 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -627,6 +627,7 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in speaker"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV Audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off &amp; back on"</string>
+    <string name="bluetooth_key_missing_subtext" msgid="1003639333895028298">"Can’t connect"</string>
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index 8c819ac..e2e3851 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Unavailable during calls"</string>
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Enabled"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Install unknown apps"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in speaker"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index 8c819ac..e2e3851 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlled by restricted setting"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Unavailable during calls"</string>
     <string name="disabled" msgid="8017887509554714950">"Disabled"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Enabled"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Allowed"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Not allowed"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Install unknown apps"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in speaker"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem connecting. Turn device off and back on"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Help and feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index 224ad41..17909f9 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Función controlada por configuración restringida"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"No disponible durante llamadas"</string>
     <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Habilitada"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Con permiso"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"No permitida"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalar apps desconocidas"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Bocina integrada"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio de la TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Error al establecer la conexión. Apaga el dispositivo y vuelve a encenderlo."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
     <string name="storage_category" msgid="2287342585424631813">"Almacenamiento"</string>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index 66d81d2..536f099 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlado por ajustes restringidos"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"No disponible durante las llamadas"</string>
     <string name="disabled" msgid="8017887509554714950">"Inhabilitada"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Habilitado"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorizadas"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"No autorizadas"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalar aplicaciones desconocidas"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altavoz integrado"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio de la televisión"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"No se ha podido conectar; reinicia el dispositivo"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Ayuda y comentarios"</string>
     <string name="storage_category" msgid="2287342585424631813">"Almacenamiento"</string>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index 59e1e4b..86ccf28 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Haldavad piiranguga seaded"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Pole kõnede ajal saadaval"</string>
     <string name="disabled" msgid="8017887509554714950">"Keelatud"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Lubatud"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Lubatud"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Pole lubatud"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Tundmatute rakenduste installimine"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Sisseehitatud kõlar"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Teleri heli"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem ühendamisel. Lülitage seade välja ja uuesti sisse"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Juhtmega heliseade"</string>
     <string name="help_label" msgid="3528360748637781274">"Abi ja tagasiside"</string>
     <string name="storage_category" msgid="2287342585424631813">"Salvestusruum"</string>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 6fd7e24..4de40f5 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -628,6 +628,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Bozgorailu integratua"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Telebistako audioa"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Arazo bat izan da konektatzean. Itzali gailua eta pitz ezazu berriro."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio-gailu kableduna"</string>
     <string name="help_label" msgid="3528360748637781274">"Laguntza eta iritziak"</string>
     <string name="storage_category" msgid="2287342585424631813">"Biltegiratzea"</string>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index d42a7a0..f3fa38b 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"با تنظیم «حالت محدود» کنترل می‌شود"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"درطول تماس دردسترس نیست"</string>
     <string name="disabled" msgid="8017887509554714950">"غیر فعال شد"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"فعال"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"مجاز بودن"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"مجاز نبودن"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"نصب برنامه‌های ناشناس"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"بلندگوی داخلی"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"صدای تلویزیون"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"مشکل در اتصال. دستگاه را خاموش و دوباره روشن کنید"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"دستگاه صوتی سیمی"</string>
     <string name="help_label" msgid="3528360748637781274">"راهنما و بازخورد"</string>
     <string name="storage_category" msgid="2287342585424631813">"فضای ذخیره‌سازی"</string>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index a66c8cf3..e212f09 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -539,11 +539,10 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Rajoitettujen asetusten mukaisesti"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ei käytettävissä puhelujen aikana"</string>
     <string name="disabled" msgid="8017887509554714950">"Pois päältä"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Käytössä"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Sallittu"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ei sallittu"</string>
-    <string name="install_other_apps" msgid="3232595082023199454">"Tuntemattomien sovellusten asentaminen"</string>
+    <string name="install_other_apps" msgid="3232595082023199454">"Asenna tuntemattomia sovelluksia"</string>
     <string name="home" msgid="973834627243661438">"Asetusten etusivu"</string>
   <string-array name="battery_labels">
     <item msgid="7878690469765357158">"0 %"</item>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Sisäänrakennettu kaiutin"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV:n audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Yhteysvirhe. Sammuta laite ja käynnistä se uudelleen."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Langallinen äänilaite"</string>
     <string name="help_label" msgid="3528360748637781274">"Ohjeet ja palaute"</string>
     <string name="storage_category" msgid="2287342585424631813">"Tallennustila"</string>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index f332208..7c3c844 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Contrôlé par les paramètres restreints"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponible pendant les appels"</string>
     <string name="disabled" msgid="8017887509554714950">"Désactivée"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Activé"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorisée"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Non autorisée"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Installer les applis inconnues"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Haut-parleur intégré"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Sortie audio du téléviseur"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez et rallumez l\'appareil"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio à câble"</string>
     <string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
     <string name="storage_category" msgid="2287342585424631813">"Stockage"</string>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index 4cc8a9a..1053e15 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Contrôlé par les paramètres restreints"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponible pendant les appels"</string>
     <string name="disabled" msgid="8017887509554714950">"Désactivée"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Activé"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorisé"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Non autorisé"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Installation d\'applis inconnues"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Haut-parleur intégré"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problème de connexion. Éteignez l\'appareil, puis rallumez-le"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Appareil audio filaire"</string>
     <string name="help_label" msgid="3528360748637781274">"Aide et commentaires"</string>
     <string name="storage_category" msgid="2287342585424631813">"Stockage"</string>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index b7a6abc..618dd62 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Baixo o control de opcións restrinxidas"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Non dispoñible durante as chamadas"</string>
     <string name="disabled" msgid="8017887509554714950">"Desactivada"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Opción activada"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Permiso concedido"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Permiso non concedido"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalar aplicacións descoñecidas"</string>
@@ -610,9 +609,9 @@
     <string name="media_transfer_external_device_name" msgid="2588672258721846418">"Dispositivo externo"</string>
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo conectado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este teléfono"</string>
-    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
-    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analóxica"</string>
-    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
+    <string name="media_transfer_digital_line_name" msgid="312091711951124301">"Conexión S/PDIF"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Conexión analóxica"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"Conexión AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Non se pode reproducir contido neste dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Cambia a conta a un plan superior para facer a modificación"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Non se poden reproducir as descargas neste dispositivo"</string>
@@ -626,8 +625,10 @@
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Conectado mediante ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Conectado mediante eARC"</string>
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altofalante integrado"</string>
-    <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio da televisión"</string>
+    <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Saída de audio da televisión"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Produciuse un problema coa conexión. Apaga e acende o dispositivo."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de audio con cable"</string>
     <string name="help_label" msgid="3528360748637781274">"Axuda e comentarios"</string>
     <string name="storage_category" msgid="2287342585424631813">"Almacenamento"</string>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index aa27f2a..9f8fc10 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"પ્રતિબંધિત સેટિંગ દ્વારા નિયંત્રિત"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"કૉલ દરમિયાન અનુપલબ્ધ"</string>
     <string name="disabled" msgid="8017887509554714950">"બંધ કરી"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ચાલુ છે"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"મંજૂરી છે"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"મંજૂરી નથી"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"અજાણી ઍપ ઇન્સ્ટૉલ કરો"</string>
@@ -612,7 +611,7 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"આ ફોન"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
     <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"એનાલોગ"</string>
-    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ઑગ્ઝિલરી"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"આ ડિવાઇસ પર ચલાવી શકતા નથી"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"સ્વિચ કરવા માટે એકાઉન્ટ અપગ્રેડ કરો"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ડાઉનલોડ કરેલું કન્ટેન્ટ અહીં ચલાવી શકતા નથી"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"બિલ્ટ-ઇન સ્પીકર"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ટીવીનો ઑડિયો"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"કનેક્ટ કરવામાં સમસ્યા આવી રહી છે. ડિવાઇસને બંધ કરીને ફરી ચાલુ કરો"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"વાયરવાળો ઑડિયો ડિવાઇસ"</string>
     <string name="help_label" msgid="3528360748637781274">"સહાય અને પ્રતિસાદ"</string>
     <string name="storage_category" msgid="2287342585424631813">"સ્ટોરેજ"</string>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index 7c4d64f..cb6e3c9 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"इसे पाबंदी मोड वाली सेटिंग से कंट्रोल किया जाता है"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"कॉल के दौरान उपलब्ध नहीं है"</string>
     <string name="disabled" msgid="8017887509554714950">"बंद किया गया"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"चालू है"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"अनुमति है"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"अनुमति नहीं है"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"अनजान ऐप्लिकेशन इंस्टॉल करने की अनुमति"</string>
@@ -612,7 +611,7 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"यह फ़ोन"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
     <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ऐनालॉग"</string>
-    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ऑक्स"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"सहायक डिवाइस"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"इस डिवाइस पर मीडिया नहीं चलाया जा सकता"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"प्रीमियम खाते में स्विच करने के लिए, अपना खाता अपग्रेड करें"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"डाउनलोड किए गए वीडियो यहां नहीं चलाए जा सकते"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"डिवाइस में पहले से मौजूद स्पीकर"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"टीवी ऑडियो"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्ट करने में समस्या हो रही है. डिवाइस को बंद करके चालू करें"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर वाला ऑडियो डिवाइस"</string>
     <string name="help_label" msgid="3528360748637781274">"सहायता और सुझाव"</string>
     <string name="storage_category" msgid="2287342585424631813">"डिवाइस का स्टोरेज"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index ba5650f..10863cf 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolira ograničena postavka"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nije dostupno tijekom poziva"</string>
     <string name="disabled" msgid="8017887509554714950">"Onemogućeno"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Omogućeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dopušteno"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nije dopušteno"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalacija nepoznatih aplikacija"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ugrađeni zvučnik"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV zvuk"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem s povezivanjem. Isključite i ponovo uključite uređaj"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žičani audiouređaj"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoć i povratne informacije"</string>
     <string name="storage_category" msgid="2287342585424631813">"Pohrana"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index faeec8d..104e4bc 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Korlátozott beállítás vezérli"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nem áll rendelkezésre hívások közben"</string>
     <string name="disabled" msgid="8017887509554714950">"Letiltva"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Engedélyezve"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Engedélyezett"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nem engedélyezett"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Ismeretlen alkalmazások telepítése"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Beépített hangszóró"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Tévés hangkimenet"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sikertelen csatlakozás. Kapcsolja ki az eszközt, majd kapcsolja be újra."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vezetékes audioeszköz"</string>
     <string name="help_label" msgid="3528360748637781274">"Súgó és visszajelzés"</string>
     <string name="storage_category" msgid="2287342585424631813">"Tárhely"</string>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index f2b2267..a5a15f9 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Կառավարվում է սահմանափակ ռեժիմի կարգավորումներով"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Զանգի ընթացքում հասանելի չէ"</string>
     <string name="disabled" msgid="8017887509554714950">"Կասեցված է"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Միացված է"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Թույլատրված է"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Արգելված"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Անհայտ հավելվածների տեղադրում"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ներկառուցված բարձրախոս"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Հեռուստացույցի աուդիո"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Կապի խնդիր կա: Սարքն անջատեք և նորից միացրեք:"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Լարով աուդիո սարք"</string>
     <string name="help_label" msgid="3528360748637781274">"Օգնություն և հետադարձ կապ"</string>
     <string name="storage_category" msgid="2287342585424631813">"Տարածք"</string>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 7af3de0..c8d7481 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Dikontrol oleh Setelan Terbatas"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Tidak tersedia selama panggilan berlangsung"</string>
     <string name="disabled" msgid="8017887509554714950">"Dinonaktifkan"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Aktif"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Diizinkan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Tidak diizinkan"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instal aplikasi tidak dikenal"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Speaker bawaan"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ada masalah saat menghubungkan. Nonaktifkan perangkat &amp; aktifkan kembali"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Perangkat audio berkabel"</string>
     <string name="help_label" msgid="3528360748637781274">"Bantuan &amp; masukan"</string>
     <string name="storage_category" msgid="2287342585424631813">"Penyimpanan"</string>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index e6ef20f..f85c20b 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Stýrt af takmarkaði stillingu"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ekki í boði á meðan á símtölum stendur"</string>
     <string name="disabled" msgid="8017887509554714950">"Óvirkt"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Kveikt"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Heimilað"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ekki heimilað"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Setja upp óþekkt forrit"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Innbyggður hátalari"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Sjónvarpshljóð"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Vandamál í tengingu. Slökktu og kveiktu á tækinu"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Snúrutengt hljómtæki"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjálp og ábendingar"</string>
     <string name="storage_category" msgid="2287342585424631813">"Geymsla"</string>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index 24e7a4c..1b31ae0 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Gestita tramite impostazioni con restrizioni"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Non disponibile durante le chiamate"</string>
     <string name="disabled" msgid="8017887509554714950">"Disattivato"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Attivata"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorizzazione concessa"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Autorizzazione non concessa"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Installa app sconosciute"</string>
@@ -611,7 +610,7 @@
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo connesso"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Questo smartphone"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
-    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogico"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analogica"</string>
     <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Impossibile riprodurre su questo dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Esegui l\'upgrade dell\'account per cambiare"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altoparlante integrato"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio della TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema di connessione. Spegni e riaccendi il dispositivo"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo audio cablato"</string>
     <string name="help_label" msgid="3528360748637781274">"Guida e feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Archiviazione"</string>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 82d9043..0da5795 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"בשליטה של הגדרה מוגבלת"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ההעדפה הזו לא זמינה במהלך שיחות"</string>
     <string name="disabled" msgid="8017887509554714950">"מושבת"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"מופעלת"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"מורשה"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"לא מורשה"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"התקנת אפליקציות לא מוכרות"</string>
@@ -611,7 +610,7 @@
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"המכשיר המחובר"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"הטלפון הזה"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
-    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"אנלוגי"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"חיבור אנלוגי"</string>
     <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"לא ניתן להפעיל במכשיר"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"יש לשדרג חשבון כדי לעבור"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"רמקול מובנה"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"אודיו בטלוויזיה"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"יש בעיה בחיבור. עליך לכבות את המכשיר ולהפעיל אותו מחדש"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"התקן אודיו חוטי"</string>
     <string name="help_label" msgid="3528360748637781274">"עזרה ומשוב"</string>
     <string name="storage_category" msgid="2287342585424631813">"אחסון"</string>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 79438fa..78c16de 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"制限付き設定によって管理されています"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"通話中は利用できません"</string>
     <string name="disabled" msgid="8017887509554714950">"無効"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"有効"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"許可"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"許可しない"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"不明なアプリのインストール"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"内蔵スピーカー"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV オーディオ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"接続エラーです。デバイスを OFF にしてから ON に戻してください"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線オーディオ デバイス"</string>
     <string name="help_label" msgid="3528360748637781274">"ヘルプとフィードバック"</string>
     <string name="storage_category" msgid="2287342585424631813">"ストレージ"</string>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index ea01938..a7599be 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"კონტროლდება შეზღუდული რეჟიმის პარამეტრით"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"მიუწვდომელია ზარების განხორციელებისას"</string>
     <string name="disabled" msgid="8017887509554714950">"გამორთული"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ჩართულია"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"დაშვებულია"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"დაუშვებელია"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"უცნობი აპების ინსტალაცია"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ჩაშენებული დინამიკი"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV Audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"დაკავშირებისას წარმოიქმნა პრობლემა. გამორთეთ და კვლავ ჩართეთ მოწყობილობა"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"სადენიანი აუდიო მოწყობილობა"</string>
     <string name="help_label" msgid="3528360748637781274">"დახმარება და გამოხმაურება"</string>
     <string name="storage_category" msgid="2287342585424631813">"საცავი"</string>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index 16b7c22..65ad80a 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Шектелген параметрлер арқылы басқарылады."</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Қоңырау шалу кезінде қолжетімді емес."</string>
     <string name="disabled" msgid="8017887509554714950">"Өшірілген"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Қосулы"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Рұқсат берілген"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Рұқсат етілмеген"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Белгісіз қолданбаларды орнату"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ендірілген динамик"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Теледидардың аудио шығысы"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Байланыс орнату қатесі шығуып жатыр. Құрылғыны өшіріп, қайта қосыңыз."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Сымды аудио құрылғысы"</string>
     <string name="help_label" msgid="3528360748637781274">"Анықтама және пікір"</string>
     <string name="storage_category" msgid="2287342585424631813">"Жад"</string>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index de93ee9..b8a8355 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"គ្រប់គ្រងដោយការកំណត់ដែលបានរឹតបន្តឹង"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"មិនអាច​ប្រើបានទេ​អំឡុងពេល​ហៅទូរសព្ទ"</string>
     <string name="disabled" msgid="8017887509554714950">"បិទ"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"បាន​បើក"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"បាន​អនុញ្ញាត"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"មិន​បានអនុញ្ញាត​"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"ដំឡើងកម្មវិធីដែលមិនស្គាល់"</string>
@@ -625,9 +624,11 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"បានភ្ជាប់តាមរយៈ ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"បានភ្ជាប់តាមរយៈ eARC"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ឧបករណ៍បំពងសំឡេង​ភ្ជាប់មកជាមួយ"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ឧបករណ៍សំឡេងមកជាមួយ"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"សំឡេងទូរទស្សន៍"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"មាន​បញ្ហា​ក្នុងការ​ភ្ជាប់។ បិទ រួច​បើក​ឧបករណ៍​វិញ"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ឧបករណ៍​សំឡេងប្រើខ្សែ"</string>
     <string name="help_label" msgid="3528360748637781274">"ជំនួយ និងមតិកែលម្អ"</string>
     <string name="storage_category" msgid="2287342585424631813">"ទំហំផ្ទុក"</string>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index 4c4ea64..4a8a413 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ನಿರ್ಬಂಧಿಸಲಾದ ಸೆಟ್ಟಿಂಗ್ ಮೂಲಕ ನಿಯಂತ್ರಿಸಲಾಗುತ್ತದೆ"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ಕರೆಗಳ ಸಮಯದಲ್ಲಿ ಲಭ್ಯವಿಲ್ಲ"</string>
     <string name="disabled" msgid="8017887509554714950">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ಅನುಮತಿಸಲಾಗಿದೆ"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ಅನುಮತಿ ಇಲ್ಲ"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"ಅಪರಿಚಿತ ಆ್ಯಪ್‍‍ಗಳನ್ನು ಇನ್‌ಸ್ಟಾಲ್ ಮಾಡಿ"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ಅಂತರ್ ನಿರ್ಮಿತ ಧ್ವನಿ ವರ್ಧಕ"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV ಆಡಿಯೊ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ಕನೆಕ್ಟ್ ಮಾಡುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ ಸಾಧನವನ್ನು ಆಫ್ ಮಾಡಿ ಹಾಗೂ ನಂತರ ಪುನಃ ಆನ್ ಮಾಡಿ"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ವೈರ್ ಹೊಂದಿರುವ ಆಡಿಯೋ ಸಾಧನ"</string>
     <string name="help_label" msgid="3528360748637781274">"ಸಹಾಯ ಮತ್ತು ಪ್ರತಿಕ್ರಿಯೆ"</string>
     <string name="storage_category" msgid="2287342585424631813">"ಸಂಗ್ರಹಣೆ"</string>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 0488543..ee99beb 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"제한된 설정으로 제어됨"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"통화 중에는 사용할 수 없습니다."</string>
     <string name="disabled" msgid="8017887509554714950">"사용 안함"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"사용 설정됨"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"허용됨"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"허용되지 않음"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"알 수 없는 앱 설치"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"내장 스피커"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV 오디오"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"연결 중에 문제가 발생했습니다. 기기를 껐다가 다시 켜 보세요."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"유선 오디오 기기"</string>
     <string name="help_label" msgid="3528360748637781274">"고객센터"</string>
     <string name="storage_category" msgid="2287342585424631813">"저장용량"</string>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index b048837..5a8a66f 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Чектелген параметр аркылуу көзөмөлдөнөт"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Сүйлөшүп жаткан учурда жеткиликсиз"</string>
     <string name="disabled" msgid="8017887509554714950">"Өчүрүлгөн"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Иштетилди"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Уруксат берилген"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Тыюу салынган"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Белгисиз колдонмолорду орнотуу"</string>
@@ -612,7 +611,7 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Ушул телефон"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
     <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Аналог"</string>
-    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"КШМЧ"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Бул түзмөктө ойнотууга болбойт"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Премиум аккаунтка которулуу керек"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"Жүктөлүп алынгандар ойнотулбайт"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Алдын ала орнотулган динамик"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Сыналгы аудиосу"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Туташууда маселе келип чыкты. Түзмөктү өчүрүп, кайра күйгүзүп көрүңүз"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Зымдуу аудио түзмөк"</string>
     <string name="help_label" msgid="3528360748637781274">"Жардам/Пикир билдирүү"</string>
     <string name="storage_category" msgid="2287342585424631813">"Сактагыч"</string>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index f57ed0c..c60c04d 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ຄວບຄຸມໂດຍການຕັ້ງຄ່າທີ່ຈຳກັດໄວ້"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ບໍ່ສາມາດໃຊ້ໄດ້ລະຫວ່າງການໂທ"</string>
     <string name="disabled" msgid="8017887509554714950">"ປິດການນຳໃຊ້"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ເປີດການນຳໃຊ້ຢູ່"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ອະນຸຍາດແລ້ວ"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ບໍ່ອະນຸຍາດ"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"ຕິດຕັ້ງແອັບທີ່ບໍ່ຮູ້ຈັກ"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ລຳໂພງທີ່ມີໃນຕົວ"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ສຽງນີ້"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ເກີດບັນຫາໃນການເຊື່ອມຕໍ່. ປິດອຸປະກອນແລ້ວເປີດກັບຄືນມາໃໝ່"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ອຸປະກອນສຽງແບບມີສາຍ"</string>
     <string name="help_label" msgid="3528360748637781274">"ຊ່ວຍເຫຼືອ ແລະ ຕິຊົມ"</string>
     <string name="storage_category" msgid="2287342585424631813">"ບ່ອນເກັບຂໍ້ມູນ"</string>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 25b22ca..6467e89 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Valdoma pagal apribotą nustatymą"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nepasiekiama per skambučius"</string>
     <string name="disabled" msgid="8017887509554714950">"Neleidžiama"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Įgalinta"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Leidžiama"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Neleidžiama"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Nežinomų programų diegimas"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Įtaisytas garsiakalbis"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV garso įrašas"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Prisijungiant kilo problema. Išjunkite įrenginį ir vėl jį įjunkite"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Laidinis garso įrenginys"</string>
     <string name="help_label" msgid="3528360748637781274">"Pagalba ir atsiliepimai"</string>
     <string name="storage_category" msgid="2287342585424631813">"Saugykla"</string>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index cdca19b..ab9dfd5 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrolē ierobežots iestatījums"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ierīce nav pieejama zvanu laikā"</string>
     <string name="disabled" msgid="8017887509554714950">"Atspējots"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Iespējots"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Atļauts"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nav atļauts"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Nezināmu lietotņu instalēšana"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Iebūvēts skaļrunis"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Televizora audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Radās problēma ar savienojuma izveidi. Izslēdziet un atkal ieslēdziet ierīci."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Vadu audioierīce"</string>
     <string name="help_label" msgid="3528360748637781274">"Palīdzība un atsauksmes"</string>
     <string name="storage_category" msgid="2287342585424631813">"Krātuve"</string>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index e51ca04..71d9b76 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролирано со ограничени поставки"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недостапно при повици"</string>
     <string name="disabled" msgid="8017887509554714950">"Оневозможено"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Овозможено"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Со дозвола"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Без дозвола"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Инсталирање непознати апликации"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Вграден звучник"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аудио на телевизор"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем со поврзување. Исклучете го уредот и повторно вклучете го"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичен аудиоуред"</string>
     <string name="help_label" msgid="3528360748637781274">"Помош и повратни информации"</string>
     <string name="storage_category" msgid="2287342585424631813">"Простор"</string>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 54b6ff8..d9c9629 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"നിയന്ത്രിത ക്രമീകരണം ഉപയോഗിച്ച് നിയന്ത്രിക്കുന്നത്"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"കോളുകൾ ചെയ്യുമ്പോൾ ലഭ്യമല്ല"</string>
     <string name="disabled" msgid="8017887509554714950">"പ്രവർത്തനരഹിതമാക്കി"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"പ്രവർത്തനക്ഷമമാക്കി"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"അനുവദനീയം"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"അനുവദിച്ചിട്ടില്ല"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"പരിചയമില്ലാത്ത ആപ്പുകൾ ഇൻസ്റ്റാൾ ചെയ്യുക"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ബിൽട്ട്-ഇൻ സ്പീക്കർ"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ടിവി ഓഡിയോ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"കണക്‌റ്റ് ചെയ്യുന്നതിൽ പ്രശ്‌നമുണ്ടായി. ഉപകരണം ഓഫാക്കി വീണ്ടും ഓണാക്കുക"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"വയർ മുഖേന ബന്ധിപ്പിച്ച ഓഡിയോ ഉപകരണം"</string>
     <string name="help_label" msgid="3528360748637781274">"സഹായവും ഫീഡ്‌ബാക്കും"</string>
     <string name="storage_category" msgid="2287342585424631813">"സ്റ്റോറേജ്"</string>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index ed42362..829b1d7 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Хязгаарлагдсан тохиргоогоор хянадаг"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Дуудлагын үер боломжгүй"</string>
     <string name="disabled" msgid="8017887509554714950">"Идэвхгүйжүүлсэн"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Идэвхжүүлсэн"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Зөвшөөрсөн"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Зөвшөөрөөгүй"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Тодорхойгүй апп суулгах"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Бүрэлдэхүүн чанга яригч"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ТВ-ийн аудио"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Холбогдоход асуудал гарлаа. Төхөөрөмжийг унтраагаад дахин асаана уу"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Утастай аудио төхөөрөмж"</string>
     <string name="help_label" msgid="3528360748637781274">"Тусламж, санал хүсэлт"</string>
     <string name="storage_category" msgid="2287342585424631813">"Хадгалах сан"</string>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index 6e7cd02..8207174 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"प्रतिबंधित केलेल्या सेटिंग द्वारे नियंत्रित"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"कॉल दरम्‍यान उपलब्ध नाही"</string>
     <string name="disabled" msgid="8017887509554714950">"अक्षम"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"सुरू केले आहे"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"अनुमती आहे"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"अनुमती नाही"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"अज्ञात अ‍ॅप्स इंस्टॉल करा"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"बिल्ट-इन स्पीकर"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"टीव्ही ऑडिओ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"कनेक्‍ट करण्‍यात समस्‍या आली. डिव्हाइस बंद करा आणि नंतर सुरू करा"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"वायर असलेले ऑडिओ डिव्हाइस"</string>
     <string name="help_label" msgid="3528360748637781274">"मदत आणि फीडबॅक"</string>
     <string name="storage_category" msgid="2287342585424631813">"स्टोरेज"</string>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index 58d8038..ea3d78e 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Dikawal oleh Tetapan Terhad"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Tidak tersedia semasa panggilan berlangsung"</string>
     <string name="disabled" msgid="8017887509554714950">"Dilumpuhkan"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Didayakan"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dibenarkan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Tidak dibenarkan"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Pasang apl yang tidak diketahui"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Pembesar suara terbina dalam"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Masalah penyambungan. Matikan &amp; hidupkan kembali peranti"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Peranti audio berwayar"</string>
     <string name="help_label" msgid="3528360748637781274">"Bantuan &amp; maklum balas"</string>
     <string name="storage_category" msgid="2287342585424631813">"Storan"</string>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index ddd1279..c484a74 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ကန့်သတ်ဆက်တင်ဖြင့် ထိန်းချုပ်ထားသည်"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ဖုန်းခေါ်ဆိုနေချိန်တွင် မရနိုင်ပါ"</string>
     <string name="disabled" msgid="8017887509554714950">"ပိတ်ထားပြီး"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ဖွင့်ထားသည်"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ခွင့်ပြုထားသည်"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ခွင့်မပြုပါ"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"အမည်မသိအက်ပ် ထည့်သွင်းခြင်း"</string>
@@ -625,9 +624,11 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"ARC မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"eARC မှတစ်ဆင့် ချိတ်ဆက်ထားသည်"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"မူလပါရှိသည့် စပီကာ"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"အသင့်ပါ စပီကာ"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV အသံ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ချိတ်ဆက်ရာတွင် ပြဿနာရှိပါသည်။ စက်ကိုပိတ်ပြီး ပြန်ဖွင့်ပါ"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ကြိုးတပ် အသံစက်ပစ္စည်း"</string>
     <string name="help_label" msgid="3528360748637781274">"အကူအညီနှင့် အကြံပြုချက်"</string>
     <string name="storage_category" msgid="2287342585424631813">"သိုလှောင်ခန်း"</string>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index c8fc415..3c06c68 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrollert av en begrenset innstilling"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Utilgjengelig under samtaler"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktivert"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Slått på"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Tillatt"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ikke tillatt"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Installer ukjente apper"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Innebygd høyttaler"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV-lyd"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Tilkoblingsproblemer. Slå enheten av og på igjen"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Lydenhet med kabel"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjelp og tilbakemelding"</string>
     <string name="storage_category" msgid="2287342585424631813">"Lagring"</string>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 5f09635..fe743e8 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"प्रतिबन्धित सेटिङले नियन्त्रण गरेको"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"कल चलिरहेका बेला उपलब्ध छैन"</string>
     <string name="disabled" msgid="8017887509554714950">"असक्षम पारियो"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"अन गरियो"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"अनुमति छ"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"अनुमति छैन"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"अज्ञात एप इन्स्टल गर्ने अनुमति"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"अन्तर्निर्मित स्पिकर"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"टिभीको अडियो"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"जोड्ने क्रममा समस्या भयो। यन्त्रलाई निष्क्रिय पारेर फेरि अन गर्नुहोस्"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"तारयुक्त अडियो यन्त्र"</string>
     <string name="help_label" msgid="3528360748637781274">"मद्दत र प्रतिक्रिया"</string>
     <string name="storage_category" msgid="2287342585424631813">"भण्डारण"</string>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 78dfdce..f49829f 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Beheerd door beperkte instelling"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Niet beschikbaar tijdens gesprekken"</string>
     <string name="disabled" msgid="8017887509554714950">"Uitgezet"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Aangezet"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Toegestaan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Niet toegestaan"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Onbekende apps installeren"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ingebouwde speaker"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Tv-audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Probleem bij verbinding maken. Zet het apparaat uit en weer aan."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Bedraad audioapparaat"</string>
     <string name="help_label" msgid="3528360748637781274">"Hulp en feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Opslag"</string>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index d6e2631..ed202fa 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ପ୍ରତିବନ୍ଧିତ ସେଟିଂ ଦ୍ୱାରା ନିୟନ୍ତ୍ରଣ କରାଯାଇଛି"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"କଲ କରିବାବେଳେ ଉପଲବ୍ଧ ନଥାଏ"</string>
     <string name="disabled" msgid="8017887509554714950">"ଅକ୍ଷମ ହୋଇଛି"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ସକ୍ଷମ କରାଯାଇଛି"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ଅନୁମତି ଦିଆଯାଇଛି"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ଅନୁମତି ନାହିଁ"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"ଅଜଣା ଆପ ଇନଷ୍ଟଲ କରନ୍ତୁ"</string>
@@ -612,7 +611,7 @@
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"ଏହି ଫୋନ୍"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
     <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"ଆନାଲଗ"</string>
-    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"ଅକ୍ସିଲାରି"</string>
+    <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"ଏହି ଡିଭାଇସରେ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"ସ୍ୱିଚ କରିବା ପାଇଁ ଆକାଉଣ୍ଟକୁ ଅପଗ୍ରେଡ କରନ୍ତୁ"</string>
     <string name="media_output_status_not_support_downloads" msgid="4523828729240373315">"ଏଠାରେ ଡାଉନଲୋଡଗୁଡ଼ିକୁ ପ୍ଲେ କରାଯାଇପାରିବ ନାହିଁ"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ବିଲ୍ଟ-ଇନ ସ୍ପିକର"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ଟିଭି ଅଡିଓ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ସଂଯୋଗ କରିବାରେ ସମସ୍ୟା ହେଉଛି। ଡିଭାଇସ୍ ବନ୍ଦ କରି ପୁଣି ଚାଲୁ କରନ୍ତୁ"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ତାରଯୁକ୍ତ ଅଡିଓ ଡିଭାଇସ୍"</string>
     <string name="help_label" msgid="3528360748637781274">"ସାହାଯ୍ୟ ଓ ମତାମତ"</string>
     <string name="storage_category" msgid="2287342585424631813">"ଷ୍ଟୋରେଜ"</string>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index ab5f4af..ee0f761 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ਪ੍ਰਤਿਬੰਧਿਤ ਸੈਟਿੰਗ ਰਾਹੀਂ ਕੰਟਰੋਲ ਕੀਤੀ ਜਾਂਦੀ ਹੈ"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ਕਾਲਾਂ ਦੌਰਾਨ ਉਪਲਬਧ ਨਹੀਂ ਹੈ"</string>
     <string name="disabled" msgid="8017887509554714950">"ਅਯੋਗ ਬਣਾਇਆ"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ਚਾਲੂ ਹੈ"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ਮਨਜ਼ੂਰਸ਼ੁਦਾ"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ਗੈਰ-ਮਨਜ਼ੂਰਸ਼ੁਦਾ"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"ਅਗਿਆਤ ਐਪਾਂ ਦੀ ਸਥਾਪਨਾ"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ਬਿਲਟ-ਇਨ ਸਪੀਕਰ"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"ਟੀਵੀ ਆਡੀਓ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"ਕਨੈਕਟ ਕਰਨ ਵਿੱਚ ਸਮੱਸਿਆ ਆਈ। ਡੀਵਾਈਸ ਨੂੰ ਬੰਦ ਕਰਕੇ ਵਾਪਸ ਚਾਲੂ ਕਰੋ"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"ਤਾਰ ਵਾਲਾ ਆਡੀਓ ਡੀਵਾਈਸ"</string>
     <string name="help_label" msgid="3528360748637781274">"ਮਦਦ ਅਤੇ ਵਿਚਾਰ"</string>
     <string name="storage_category" msgid="2287342585424631813">"ਸਟੋਰੇਜ"</string>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index 4621424..fec5bf1 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Obowiązują ustawienia z ograniczonym dostępem"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Niedostępne w trakcie połączeń"</string>
     <string name="disabled" msgid="8017887509554714950">"Wyłączona"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Włączono"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dozwolone"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Niedozwolone"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalowanie nieznanych aplikacji"</string>
@@ -626,8 +625,10 @@
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Połączono przez ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Połączono przez eARC"</string>
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Wbudowany głośnik"</string>
-    <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Telewizyjne urządzenie audio"</string>
+    <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio z telewizora"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem z połączeniem. Wyłącz i ponownie włącz urządzenie"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Przewodowe urządzenie audio"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoc i opinie"</string>
     <string name="storage_category" msgid="2287342585424631813">"Pamięć wewnętrzna"</string>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 482f479..62d879b 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada pelas configurações restritas"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponível durante ligações"</string>
     <string name="disabled" msgid="8017887509554714950">"Desativado"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Ativado"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Permitido"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Não permitido"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalar apps desconhecidos"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Alto-falante integrado"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Áudio da TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fio"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Armazenamento"</string>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 1a99757..3486037 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlado por uma definição restrita"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponível durante as chamadas"</string>
     <string name="disabled" msgid="8017887509554714950">"Desativada"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Ativado"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Autorizada"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Não autorizada"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalar apps desconhecidas"</string>
@@ -611,7 +610,7 @@
     <string name="media_transfer_default_device_name" msgid="4315604017399871828">"Dispositivo associado"</string>
     <string name="media_transfer_this_phone" msgid="7194341457812151531">"Este telemóvel"</string>
     <string name="media_transfer_digital_line_name" msgid="312091711951124301">"S/PDIF"</string>
-    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógico"</string>
+    <string name="media_transfer_analog_line_name" msgid="1841163866716302104">"Analógica"</string>
     <string name="media_transfer_aux_line_name" msgid="894135835967856689">"AUX"</string>
     <string name="media_output_status_unknown_error" msgid="5098565887497902222">"Não é possível reproduzir neste dispositivo"</string>
     <string name="media_output_status_require_premium" msgid="8411255800047014822">"Atualize a conta para mudar"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altifalante integrado"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Áudio da TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problema ao ligar. Desligue e volte a ligar o dispositivo."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fios"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Armazenamento"</string>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 482f479..62d879b 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlada pelas configurações restritas"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponível durante ligações"</string>
     <string name="disabled" msgid="8017887509554714950">"Desativado"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Ativado"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Permitido"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Não permitido"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalar apps desconhecidos"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Alto-falante integrado"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Áudio da TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ocorreu um problema na conexão. Desligue o dispositivo e ligue-o novamente"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispositivo de áudio com fio"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajuda e feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Armazenamento"</string>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index 757fee9..8965a0c 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Controlată de setarea restricționată"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Indisponibil în timpul apelurilor"</string>
     <string name="disabled" msgid="8017887509554714950">"Dezactivată"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Activată"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Permise"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nepermise"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalarea aplicațiilor necunoscute"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Difuzor încorporat"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problemă la conectare. Oprește și repornește dispozitivul."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Dispozitiv audio cu fir"</string>
     <string name="help_label" msgid="3528360748637781274">"Ajutor și feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Stocare"</string>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 9e922a0..2da6708 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролируется настройками с ограниченным доступом"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недоступно во время вызовов"</string>
     <string name="disabled" msgid="8017887509554714950">"Отключено"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Включено"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Разрешено"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Запрещено"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Установка неизвестных приложений"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Встроенный динамик"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аудиовыход телевизора"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ошибка подключения. Выключите и снова включите устройство."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Проводное аудиоустройство"</string>
     <string name="help_label" msgid="3528360748637781274">"Справка/отзыв"</string>
     <string name="storage_category" msgid="2287342585424631813">"Хранилище"</string>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 517b00c..1c57acd 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"සීමා කළ සැකසීම මගින් පාලනය වේ"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ඇමතුම් අතරතුර නොපවතී"</string>
     <string name="disabled" msgid="8017887509554714950">"අබල කර ඇත"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"සබලයි"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"ඉඩ දුන්"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ඉඩ නොදෙන"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"නොදන්නා යෙදුම් ස්ථාපනය"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"එකට තැනූ ශබ්දවාහිනීය"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"රූපවාහිනී ශ්‍රව්‍ය"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"සම්බන්ධ කිරීමේ ගැටලුවකි උපාංගය ක්‍රියාවිරහිත කර &amp; ආපසු ක්‍රියාත්මක කරන්න"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"රැහැන්ගත කළ ඕඩියෝ උපාංගය"</string>
     <string name="help_label" msgid="3528360748637781274">"උදවු &amp; ප්‍රතිපෝෂණ"</string>
     <string name="storage_category" msgid="2287342585424631813">"ගබඩාව"</string>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index e8fb53f..5534ed0 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Ovládané obmedzeným nastavením"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Počas hovorov nie je k dispozícii"</string>
     <string name="disabled" msgid="8017887509554714950">"Deaktivované"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Zapnuté"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Povolené"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nie je povolené"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Inštalácia neznámych aplikácií"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Vstavaný reproduktor"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvuk televízora"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Pri pripájaní sa vyskytol problém. Zariadenie vypnite a znova zapnite."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Audio zariadenie s káblom"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomocník a spätná väzba"</string>
     <string name="storage_category" msgid="2287342585424631813">"Priestor"</string>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index 7d50886..be7b115 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Pod nadzorom omejene nastavitve"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ni na voljo med klici"</string>
     <string name="disabled" msgid="8017887509554714950">"Onemogočeno"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Omogočeno"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Dovoljene"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ni dovoljeno"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Nameščanje neznanih aplikacij"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Vgrajen zvočnik"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Zvok televizorja"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Težava pri povezovanju. Napravo izklopite in znova vklopite."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Žična zvočna naprava"</string>
     <string name="help_label" msgid="3528360748637781274">"Pomoč in povratne informacije"</string>
     <string name="storage_category" msgid="2287342585424631813">"Shramba"</string>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index 8a711d5e..06da1722 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kontrollohet nga \"Cilësimet e kufizuara\""</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Nuk ofrohet gjatë telefonatave"</string>
     <string name="disabled" msgid="8017887509554714950">"Çaktivizuar"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Aktivizuar"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Lejohet"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Nuk lejohet"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Instalo aplikacione të panjohura"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Altoparlanti i integruar"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audioja e televizorit"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Problem me lidhjen. Fike dhe ndize përsëri pajisjen"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Pajisja audio me tel"</string>
     <string name="help_label" msgid="3528360748637781274">"Ndihma dhe komentet"</string>
     <string name="storage_category" msgid="2287342585424631813">"Hapësira ruajtëse"</string>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index d57eb5c..63d1502 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Контролишу ограничена подешавања"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недоступно током позива"</string>
     <string name="disabled" msgid="8017887509554714950">"Онемогућено"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Омогућено"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Дозвољено"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Није дозвољено"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Инсталирање непознатих апликација"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Уграђени звучник"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Звук ТВ-а"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Проблем при повезивању. Искључите уређај, па га поново укључите"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Жичани аудио уређај"</string>
     <string name="help_label" msgid="3528360748637781274">"Помоћ и повратне информације"</string>
     <string name="storage_category" msgid="2287342585424631813">"Меморијски простор"</string>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 5d27839..131cca7 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Styrs av spärrad inställning"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Ej tillgänglig under samtal"</string>
     <string name="disabled" msgid="8017887509554714950">"Inaktiverad"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Aktiverat"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Tillåts"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Tillåts inte"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Installera okända appar"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Inbyggd högtalare"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Tv-ljud"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Det gick inte att ansluta. Stäng av enheten och slå på den igen"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Ljudenhet med kabelanslutning"</string>
     <string name="help_label" msgid="3528360748637781274">"Hjälp och feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Lagring"</string>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index 9ddb7ff..1cb95a7 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Imedhibitiwa na Mpangilio wenye Mipaka"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Haipatikani wakati unaongea kwa simu"</string>
     <string name="disabled" msgid="8017887509554714950">"Imezimwa"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Imewashwa"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Imeruhusiwa"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Hairuhusiwi"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Kuweka programu zisizojulikana"</string>
@@ -625,9 +624,11 @@
     <string name="tv_media_transfer_earc_fallback_title" msgid="3098685494578519940">"HDMI eARC"</string>
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Imeunganishwa kupitia ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Imeunganishwa kupitia eARC"</string>
-    <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Spika iliyojumuishwa ndani"</string>
+    <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Spika iliyojumuishwa"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Sauti ya Televisheni"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Kuna tatizo la kuunganisha kwenye Intaneti. Zima kisha uwashe kifaa"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kifaa cha sauti kinachotumia waya"</string>
     <string name="help_label" msgid="3528360748637781274">"Usaidizi na maoni"</string>
     <string name="storage_category" msgid="2287342585424631813">"Hifadhi"</string>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index 68a60cf..cc8a36f 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"வரையறுக்கப்பட்ட அமைப்பால் கட்டுப்படுத்தப்படுகிறது"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"அழைப்புகளின்போது பயன்படுத்த முடியாது"</string>
     <string name="disabled" msgid="8017887509554714950">"முடக்கப்பட்டது"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"இயக்கப்பட்டது"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"அனுமதிக்கப்பட்டது"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"அனுமதிக்கப்படவில்லை"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"தெரியாத ஆப்ஸ்களை நிறுவுதல்"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"உள்ளமைந்த ஸ்பீக்கர்"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"டிவி ஆடியோ"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"இணைப்பதில் சிக்கல். சாதனத்தை ஆஃப் செய்து மீண்டும் ஆன் செய்யவும்"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"வயருடன்கூடிய ஆடியோ சாதனம்"</string>
     <string name="help_label" msgid="3528360748637781274">"உதவியும் கருத்தும்"</string>
     <string name="storage_category" msgid="2287342585424631813">"சேமிப்பகம்"</string>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index db4f66b..ccb5aa8 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"పరిమితం చేసిన సెట్టింగ్ ద్వారా నియంత్రించబడుతుంది"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"కాల్స్ సమయంలో అందుబాటులో ఉండదు"</string>
     <string name="disabled" msgid="8017887509554714950">"డిజేబుల్ చేయబడింది"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"ఎనేబుల్ చేయబడింది"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"అనుమతించినవి"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"అనుమతించబడలేదు"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"తెలియని యాప్‌ల ఇన్‌స్టలేషన్"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"బిల్ట్-ఇన్ స్పీకర్"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"టీవీ ఆడియో"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"కనెక్ట్ చేయడంలో సమస్య ఉంది. పరికరాన్ని ఆఫ్ చేసి, ఆపై తిరిగి ఆన్ చేయండి"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"వైర్ గల ఆడియో పరికరం"</string>
     <string name="help_label" msgid="3528360748637781274">"సహాయం &amp; ఫీడ్‌బ్యాక్"</string>
     <string name="storage_category" msgid="2287342585424631813">"స్టోరేజ్"</string>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index 035644f..08d2017 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"ควบคุมโดยการตั้งค่าที่จำกัด"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"ใช้งานไม่ได้ขณะสนทนาโทรศัพท์"</string>
     <string name="disabled" msgid="8017887509554714950">"ปิดอยู่"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"เปิดใช้อยู่"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"อนุญาต"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"ไม่อนุญาต"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"ติดตั้งแอปที่ไม่รู้จัก"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"ลำโพงในตัว"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"เสียงจากทีวี"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"เกิดปัญหาในการเชื่อมต่อ ปิดอุปกรณ์แล้วเปิดใหม่อีกครั้ง"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"อุปกรณ์เสียงแบบมีสาย"</string>
     <string name="help_label" msgid="3528360748637781274">"ความช่วยเหลือและความคิดเห็น"</string>
     <string name="storage_category" msgid="2287342585424631813">"พื้นที่เก็บข้อมูล"</string>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 4ef2f43..14069b9 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kinokontrol ng Pinaghihigpitang Setting"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Hindi available habang may tawag"</string>
     <string name="disabled" msgid="8017887509554714950">"Naka-disable"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Naka-enable"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Pinapayagan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Hindi pinapayagan"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Mag-install ng di-kilalang app"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Built-in na speaker"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Audio ng TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Nagkaproblema sa pagkonekta. I-off at pagkatapos ay i-on ang device"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Wired na audio device"</string>
     <string name="help_label" msgid="3528360748637781274">"Tulong at feedback"</string>
     <string name="storage_category" msgid="2287342585424631813">"Storage"</string>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 19295aa..7021003 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kısıtlanmış ayar tarafından kontrol ediliyor"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Telefon aramaları sırasında kullanılamaz"</string>
     <string name="disabled" msgid="8017887509554714950">"Devre dışı"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Etkin"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"İzin verildi"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"İzin verilmiyor"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Bilinmeyen uygulamaları yükleme"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Dahili hoparlör"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV Sesi"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Bağlanırken sorun oluştu. Cihazı kapatıp tekrar açın"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Kablolu ses cihazı"</string>
     <string name="help_label" msgid="3528360748637781274">"Yardım ve geri bildirim"</string>
     <string name="storage_category" msgid="2287342585424631813">"Depolama"</string>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index e46137f..e8fb02e 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Керується налаштуваннями з обмеженнями"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Недоступно під час викликів"</string>
     <string name="disabled" msgid="8017887509554714950">"Вимкнено"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Увімкнено"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Дозволено"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Заборонено"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Встановлювати невідомі додатки"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Вбудований динамік"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Аудіо з телевізора"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Не вдається підключитися. Перезавантажте пристрій."</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Дротовий аудіопристрій"</string>
     <string name="help_label" msgid="3528360748637781274">"Довідка й відгуки"</string>
     <string name="storage_category" msgid="2287342585424631813">"Сховище"</string>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 72da378..a0ff95a 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"محدود کردہ ترتیب کے زیر انتظام ہے"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"کالز کے دوران غیر دستیاب"</string>
     <string name="disabled" msgid="8017887509554714950">"غیر فعال"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"فعال ہے"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"اجازت ہے"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"اجازت نہیں ہے"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"نامعلوم ایپس انسٹال کریں"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"پہلے سے شامل اسپیکر"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"‏‫TV آڈیو"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"منسلک کرنے میں مسئلہ پیش آ گیا۔ آلہ کو آف اور بیک آن کریں"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"وائرڈ آڈیو آلہ"</string>
     <string name="help_label" msgid="3528360748637781274">"مدد اور تاثرات"</string>
     <string name="storage_category" msgid="2287342585424631813">"اسٹوریج"</string>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 795eae4..0a65885 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Cheklangan sozlama tomonidan boshqariladi"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Chaqiruv vaqtida ishlamaydi"</string>
     <string name="disabled" msgid="8017887509554714950">"Oʻchiq"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Yoniq"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Ruxsat berilgan"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Ruxsat berilmagan"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Notanish ilovalarni o‘rnatish"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Ichki karnay"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"TV Audio"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Ulanishda muammo yuz berdi. Qurilmani oʻchiring va yoqing"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Simli audio qurilma"</string>
     <string name="help_label" msgid="3528360748637781274">"Yordam/fikr-mulohaza"</string>
     <string name="storage_category" msgid="2287342585424631813">"Xotira"</string>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 8f5c0c2..5e1e3da 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Do chế độ Cài đặt hạn chế kiểm soát"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Không dùng được khi có cuộc gọi"</string>
     <string name="disabled" msgid="8017887509554714950">"Đã tắt"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Đã bật"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Được phép"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Không được phép"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Cài ứng dụng không rõ nguồn"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Loa tích hợp"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Âm thanh TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Sự cố kết nối. Hãy tắt thiết bị rồi bật lại"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Thiết bị âm thanh có dây"</string>
     <string name="help_label" msgid="3528360748637781274">"Trợ giúp và phản hồi"</string>
     <string name="storage_category" msgid="2287342585424631813">"Bộ nhớ"</string>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 85d3c17..6bf27b3 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由受限设置控制"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"通话期间无法使用"</string>
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"已启用"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"允许"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"不允许"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"安装未知应用"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"内置扬声器"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"电视音频"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"连接时遇到问题。请关闭并重新开启设备"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有线音频设备"</string>
     <string name="help_label" msgid="3528360748637781274">"帮助和反馈"</string>
     <string name="storage_category" msgid="2287342585424631813">"存储空间"</string>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 3ff5540..9f96b5b 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由「受限設定」控制"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"通話時無法使用"</string>
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"已啟用"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"允許"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"不允許"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"安裝不明的應用程式"</string>
@@ -602,7 +601,7 @@
     <string name="zen_mode_forever" msgid="3339224497605461291">"直至你關閉為止"</string>
     <string name="zen_mode_starred_contacts_empty_name" msgid="933552939706125937">"(沒有名稱)"</string>
     <string name="time_unit_just_now" msgid="3006134267292728099">"剛剛"</string>
-    <string name="media_transfer_this_device_name" msgid="2357329267148436433">"此手機"</string>
+    <string name="media_transfer_this_device_name" msgid="2357329267148436433">"這部手機"</string>
     <string name="media_transfer_this_device_name_tablet" msgid="2975593806278422086">"此平板電腦"</string>
     <string name="media_transfer_this_device_name_desktop" msgid="7912386128141470452">"此電腦 (內置)"</string>
     <string name="media_transfer_this_device_name_tv" msgid="8508713779441163887">"這部電視"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"內置喇叭"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"電視音訊"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連接,請關閉裝置然後重新開機"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線音響裝置"</string>
     <string name="help_label" msgid="3528360748637781274">"說明與意見反映"</string>
     <string name="storage_category" msgid="2287342585424631813">"儲存空間"</string>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 5362d38..e5f29e9 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"由受限制的設定控管"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"通話時無法使用"</string>
     <string name="disabled" msgid="8017887509554714950">"已停用"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"已啟用"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"允許"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"不允許"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"安裝不明應用程式"</string>
@@ -628,6 +627,8 @@
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"內建喇叭"</string>
     <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"電視音訊"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"無法連線,請關閉裝置後再重新開啟"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"有線音訊裝置"</string>
     <string name="help_label" msgid="3528360748637781274">"說明與意見回饋"</string>
     <string name="storage_category" msgid="2287342585424631813">"儲存空間"</string>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 79ce6d7b..c587678 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -539,8 +539,7 @@
     <string name="disabled_by_app_ops_text" msgid="8373595926549098012">"Kulawulwe Isethingi Elikhawulelwe"</string>
     <string name="disabled_in_phone_call_text" msgid="6568931334337318320">"Akutholakali ngesikhathi samakholi"</string>
     <string name="disabled" msgid="8017887509554714950">"Akusebenzi"</string>
-    <!-- no translation found for enabled (3997122818554810678) -->
-    <skip />
+    <string name="enabled" msgid="3997122818554810678">"Ukwenza kusebenze"</string>
     <string name="external_source_trusted" msgid="1146522036773132905">"Kuvumelekile"</string>
     <string name="external_source_untrusted" msgid="5037891688911672227">"Akuvumelekile"</string>
     <string name="install_other_apps" msgid="3232595082023199454">"Faka ama-app angaziwa"</string>
@@ -626,8 +625,10 @@
     <string name="tv_media_transfer_arc_subtitle" msgid="1040017851325069082">"Ixhunywe nge-ARC"</string>
     <string name="tv_media_transfer_earc_subtitle" msgid="645191413103303077">"Ixhunywe nge-eARC"</string>
     <string name="tv_media_transfer_internal_speakers" msgid="4662765121700213785">"Isipikha esakhelwe ngaphakathi"</string>
-    <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Umsondo weTV"</string>
+    <string name="tv_media_transfer_hdmi_title" msgid="6715658310934507444">"Umsindo we-TV"</string>
     <string name="profile_connect_timeout_subtext" msgid="4043408193005851761">"Inkinga yokuxhumeka. Vala idivayisi futhi uphinde uyivule"</string>
+    <!-- no translation found for bluetooth_key_missing_subtext (1003639333895028298) -->
+    <skip />
     <string name="media_transfer_wired_device_name" msgid="4447880899964056007">"Idivayisi yomsindo enentambo"</string>
     <string name="help_label" msgid="3528360748637781274">"Usizo nempendulo"</string>
     <string name="storage_category" msgid="2287342585424631813">"Isitoreji"</string>
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 03cb1ff..1297aa3 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -1510,6 +1510,9 @@
     <!-- Warning message to tell user is have problem during profile connect, it need to turn off device and back on. [CHAR_LIMIT=NONE] -->
     <string name="profile_connect_timeout_subtext">Problem connecting. Turn device off &amp; back on</string>
 
+    <!-- Warning message when the bluetooth key is missing. [CHAR_LIMIT=NONE] -->
+    <string name="bluetooth_key_missing_subtext">Can’t connect</string>
+
     <!-- Name of the 3.5mm audio device. [CHAR LIMIT=40] -->
     <string name="media_transfer_wired_device_name">Wired audio device</string>
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 3625c00..7cdc13c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -36,6 +36,7 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 import androidx.annotation.VisibleForTesting;
+import androidx.collection.ArraySet;
 
 import com.android.settingslib.R;
 import com.android.settingslib.flags.Flags;
@@ -274,29 +275,37 @@
     @VisibleForTesting
     void dispatchActiveDeviceChanged(
             @Nullable CachedBluetoothDevice activeDevice, int bluetoothProfile) {
-        CachedBluetoothDevice targetDevice = activeDevice;
+        CachedBluetoothDevice mainActiveDevice = activeDevice;
         for (CachedBluetoothDevice cachedDevice : mDeviceManager.getCachedDevicesCopy()) {
-            // should report isActive from main device or it will cause trouble to other callers.
             CachedBluetoothDevice subDevice = cachedDevice.getSubDevice();
-            CachedBluetoothDevice finalTargetDevice = targetDevice;
-            if (targetDevice != null
-                    && ((subDevice != null && subDevice.equals(targetDevice))
-                    || cachedDevice.getMemberDevice().stream().anyMatch(
-                            memberDevice -> memberDevice.equals(finalTargetDevice)))) {
-                Log.d(TAG,
-                        "The active device is the sub/member device "
-                                + targetDevice.getDevice().getAnonymizedAddress()
-                                + ". change targetDevice as main device "
-                                + cachedDevice.getDevice().getAnonymizedAddress());
-                targetDevice = cachedDevice;
+            Set<CachedBluetoothDevice> memberDevices = cachedDevice.getMemberDevice();
+            final Set<CachedBluetoothDevice> cachedDevices = new ArraySet<>();
+            cachedDevices.add(cachedDevice);
+            if (!memberDevices.isEmpty()) {
+                cachedDevices.addAll(memberDevices);
+            } else if (subDevice != null) {
+                cachedDevices.add(subDevice);
             }
-            boolean isActiveDevice = cachedDevice.equals(targetDevice);
-            cachedDevice.onActiveDeviceChanged(isActiveDevice, bluetoothProfile);
+
+            // should report isActive from main device or it will cause trouble to other callers.
+            if (activeDevice != null
+                    && (cachedDevices.stream().anyMatch(
+                            device -> device.equals(activeDevice)))) {
+                Log.d(TAG, "The active device is in the set, report main device as active device:"
+                        + cachedDevice.getDevice() + ", active device:" + activeDevice.getDevice());
+                mainActiveDevice = cachedDevice;
+            }
+            boolean isActiveDevice = cachedDevice.equals(mainActiveDevice);
+            cachedDevices.forEach(
+                    device -> device.onActiveDeviceChanged(isActiveDevice, bluetoothProfile));
+            //TODO: b/400440223 - Check if we can call DeviceManager.onActiveDeviceChanged &
+            // Callback.onActiveDeviceChanged for cachedDevices Set also, so we don't need to report
+            // isActive from main device.
             mDeviceManager.onActiveDeviceChanged(cachedDevice);
         }
 
         for (BluetoothCallback callback : mCallbacks) {
-            callback.onActiveDeviceChanged(targetDevice, bluetoothProfile);
+            callback.onActiveDeviceChanged(mainActiveDevice, bluetoothProfile);
         }
     }
 
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 5f88bcd..011b2fc 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -1495,6 +1495,11 @@
         int leftBattery = -1;
         int rightBattery = -1;
 
+        Integer keyMissingCount = BluetoothUtils.getKeyMissingCount(mDevice);
+        if (keyMissingCount != null && keyMissingCount > 0) {
+            return mContext.getString(R.string.bluetooth_key_missing_subtext);
+        }
+
         if (isProfileConnectedFail() && isConnected()) {
             return mContext.getString(R.string.profile_connect_timeout_subtext);
         }
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
index f22bdaf..b0f3796 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcast.java
@@ -19,6 +19,9 @@
 import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN;
 
 import static com.android.settingslib.Utils.isAudioModeOngoingCall;
+import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.DECRYPTION_FAILED;
+import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.PAUSED;
+import static com.android.settingslib.bluetooth.LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState.STREAMING;
 
 import static java.util.stream.Collectors.toList;
 
@@ -70,9 +73,11 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
@@ -138,6 +143,8 @@
             };
     private final Context mContext;
     private final CachedBluetoothDeviceManager mDeviceManager;
+    private final boolean mHysteresisModeFixAvailable;
+    private final boolean mIsWorkProfile;
     private BluetoothLeBroadcast mServiceBroadcast;
     private BluetoothLeBroadcastAssistant mServiceBroadcastAssistant;
     private BluetoothLeAudioContentMetadata mBluetoothLeAudioContentMetadata;
@@ -158,6 +165,7 @@
     // Cached broadcast callbacks being register before service is connected.
     private ConcurrentHashMap<BluetoothLeBroadcast.Callback, Executor>
             mCachedBroadcastCallbackExecutorMap = new ConcurrentHashMap<>();
+    private Set<BluetoothDevice> mLocalSinksPendingSourceRemoval = new HashSet<>();
 
     private final ServiceListener mServiceListener =
             new ServiceListener() {
@@ -376,6 +384,7 @@
                                         + ", sourceId = "
                                         + sourceId);
                     }
+                    mLocalSinksPendingSourceRemoval.remove(sink);
                 }
 
                 @Override
@@ -408,6 +417,35 @@
                                         + ", state = "
                                         + state);
                     }
+                    if (!Flags.audioStreamMediaServiceByReceiveState()) {
+                        Log.d(TAG, "Skip notifyPrivateBroadcastReceived, flag off.");
+                        return;
+                    }
+                    if (mIsWorkProfile) {
+                        Log.d(TAG, "Skip notifyPrivateBroadcastReceived for work profile.");
+                        return;
+                    }
+                    if (state.getBroadcastId() == mBroadcastId
+                            || !mLocalSinksPendingSourceRemoval.isEmpty()) {
+                        Log.d(TAG,
+                                "Skip notifyPrivateBroadcastReceived, onReceiveStateChanged "
+                                        + "triggered by personal audio sharing.");
+                        return;
+                    }
+                    var sourceState = LocalBluetoothLeBroadcastAssistant.getLocalSourceState(state);
+                    if (sourceState == STREAMING || sourceState == DECRYPTION_FAILED
+                            || (mHysteresisModeFixAvailable && sourceState == PAUSED)) {
+                        List<BluetoothLeAudioContentMetadata> subgroupMetadata =
+                                state.getSubgroupMetadata();
+                        String programInfo = subgroupMetadata.isEmpty() ? ""
+                                : subgroupMetadata.getFirst().getProgramInfo();
+                        notifyPrivateBroadcastReceived(
+                                sink,
+                                sourceId,
+                                state.getBroadcastId(),
+                                programInfo == null ? "" : programInfo,
+                                sourceState);
+                    }
                 }
             };
 
@@ -439,6 +477,10 @@
         BluetoothAdapter.getDefaultAdapter()
                 .getProfileProxy(
                         context, mServiceListener, BluetoothProfile.LE_AUDIO_BROADCAST_ASSISTANT);
+
+        mHysteresisModeFixAvailable = BluetoothUtils.isAudioSharingHysteresisModeFixAvailable(
+                context);
+        mIsWorkProfile = isWorkProfile(mContext);
     }
 
     /**
@@ -724,7 +766,10 @@
             Log.d(TAG, "The BluetoothLeBroadcast is null");
             return null;
         }
-        if (mBluetoothLeBroadcastMetadata == null) {
+        if (mBluetoothLeBroadcastMetadata == null
+                // mBroadcastId is updated when onBroadcastStarted, which is always before
+                // onBroadcastMetadataChanged, so mBroadcastId is always the latest broadcast info
+                || mBluetoothLeBroadcastMetadata.getBroadcastId() != mBroadcastId) {
             final List<BluetoothLeBroadcastMetadata> metadataList =
                     mServiceBroadcast.getAllBroadcastMetadata();
             mBluetoothLeBroadcastMetadata =
@@ -732,6 +777,7 @@
                             .filter(i -> i.getBroadcastId() == mBroadcastId)
                             .findFirst()
                             .orElse(null);
+            Log.d(TAG, "getLatestBluetoothLeBroadcastMetadata for broadcast id " + mBroadcastId);
         }
         return mBluetoothLeBroadcastMetadata;
     }
@@ -1134,6 +1180,7 @@
                 int localBroadcastId = getLatestBroadcastId();
                 if (receiveState.getBroadcastId() != localBroadcastId) continue;
 
+                mLocalSinksPendingSourceRemoval.add(device);
                 mServiceBroadcastAssistant.removeSource(device, receiveState.getSourceId());
             }
         }
@@ -1147,7 +1194,7 @@
             Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded, disable flag is on");
             return;
         }
-        if (isWorkProfile(mContext)) {
+        if (mIsWorkProfile) {
             Log.d(TAG, "Skip updateFallbackActiveDeviceIfNeeded for work profile.");
             return;
         }
@@ -1275,7 +1322,7 @@
             Log.d(TAG, "Skip notifyBroadcastStateChange, not triggered by Settings or SystemUI.");
             return;
         }
-        if (isWorkProfile(mContext)) {
+        if (mIsWorkProfile) {
             Log.d(TAG, "Skip notifyBroadcastStateChange, not triggered for work profile.");
             return;
         }
@@ -1286,6 +1333,26 @@
         mContext.sendBroadcast(intent);
     }
 
+    private void notifyPrivateBroadcastReceived(BluetoothDevice sink, int sourceId, int broadcastId,
+            String programInfo,
+            LocalBluetoothLeBroadcastAssistant.LocalBluetoothLeBroadcastSourceState state) {
+        String packageName = mContext.getPackageName();
+        if (!packageName.equals(SYSUI_PKG)) {
+            Log.d(TAG, "Skip notifyPrivateBroadcastReceived, not triggered by SystemUI.");
+            return;
+        }
+        var data = new PrivateBroadcastReceiveData(sink, sourceId, broadcastId, programInfo, state);
+        Intent intent = new Intent(ACTION_LE_AUDIO_PRIVATE_BROADCAST_RECEIVED);
+        intent.putExtra(EXTRA_PRIVATE_BROADCAST_RECEIVE_DATA, data);
+        intent.setPackage(SETTINGS_PKG);
+        Log.d(TAG,
+                "notifyPrivateBroadcastReceived for sink = " + sink + " with sourceId = " + sourceId
+                        + " state = " + state
+                        + " programInfo =" + programInfo
+                        + " broadcastId = " + broadcastId);
+        mContext.sendBroadcast(intent);
+    }
+
     private boolean isWorkProfile(Context context) {
         UserManager userManager = context.getSystemService(UserManager.class);
         return userManager != null && userManager.isManagedProfile();
diff --git a/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt
index 58c7907..086516b 100644
--- a/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt
+++ b/packages/SettingsLib/src/com/android/settingslib/notification/data/repository/FakeZenModeRepository.kt
@@ -114,14 +114,19 @@
         activeModesDurations.remove(id)
     }
 
-    // Update the active state while maintaining the mode's position in the list
+    /** Updates a [ZenMode]'s active state, preserving its position in the list. */
     private fun updateModeActiveState(id: String, isActive: Boolean) {
+        updateMode(id) { TestModeBuilder(it).setActive(isActive).build() }
+    }
+
+    /** Updates a [ZenMode], preserving its position in the list. */
+    fun updateMode(id: String, update: (original: ZenMode) -> ZenMode) {
         val modes = mutableModesFlow.value.toMutableList()
         val index = modes.indexOfFirst { it.id == id }
         if (index < 0) {
             throw IllegalArgumentException("mode $id not found")
         }
-        modes[index] = TestModeBuilder(modes[index]).setActive(isActive).build()
+        modes[index] = update(modes[index])
         mutableModesFlow.value = modes
     }
 }
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerImplTest.kt b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerImplTest.kt
new file mode 100644
index 0000000..78dba57
--- /dev/null
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateAutoRotateSettingManagerImplTest.kt
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.devicestate
+
+import android.content.ContentResolver
+import android.content.Context
+import android.content.res.Resources
+import android.hardware.devicestate.DeviceStateManager
+import android.os.Handler
+import android.os.UserHandle
+import android.provider.Settings
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNFOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_LOCKED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_LOCK_UNLOCKED
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager.DeviceStateAutoRotateSettingListener
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.any
+import org.mockito.Mock
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import java.util.concurrent.Executor
+import org.mockito.Mockito.`when` as whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class DeviceStateAutoRotateSettingManagerImplTest {
+    @get:Rule
+    val rule = MockitoJUnit.rule()
+
+    private val fakeSecureSettings = FakeSecureSettings()
+    private val executor: Executor = Executor { it.run() }
+    private val configPerDeviceStateRotationLockDefaults = arrayOf(
+        "$DEVICE_STATE_ROTATION_KEY_HALF_FOLDED:" +
+                "$DEVICE_STATE_ROTATION_LOCK_IGNORED:" +
+                "$DEVICE_STATE_ROTATION_KEY_UNFOLDED",
+        "$DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY:" +
+                "$DEVICE_STATE_ROTATION_LOCK_IGNORED:" +
+                "$DEVICE_STATE_ROTATION_KEY_UNFOLDED",
+        "$DEVICE_STATE_ROTATION_KEY_UNFOLDED:$DEVICE_STATE_ROTATION_LOCK_LOCKED",
+        "$DEVICE_STATE_ROTATION_KEY_FOLDED:$DEVICE_STATE_ROTATION_LOCK_LOCKED",
+    )
+
+    @Mock
+    private lateinit var mockContext: Context
+
+    @Mock
+    private lateinit var mockContentResolver: ContentResolver
+
+    @Mock
+    private lateinit var mockPosturesHelper: PosturesHelper
+
+    @Mock
+    private lateinit var mockHandler: Handler
+
+    @Mock
+    private lateinit var mockDeviceStateManager: DeviceStateManager
+
+    @Mock
+    private lateinit var mockResources: Resources
+    private lateinit var settingManager: DeviceStateAutoRotateSettingManagerImpl
+
+    @Before
+    fun setUp() {
+        whenever(mockContext.contentResolver).thenReturn(mockContentResolver)
+        whenever(mockContext.resources).thenReturn(mockResources)
+        whenever(mockResources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults))
+            .thenReturn(configPerDeviceStateRotationLockDefaults)
+        whenever(mockHandler.post(any(Runnable::class.java))).thenAnswer { invocation ->
+            val runnable = invocation.arguments[0] as Runnable
+            runnable.run()
+            null
+        }
+        whenever(mockContext.getSystemService(DeviceStateManager::class.java))
+            .thenReturn(mockDeviceStateManager)
+        whenever(mockPosturesHelper.deviceStateToPosture(DEVICE_STATE_UNFOLDED))
+            .thenReturn(DEVICE_STATE_ROTATION_KEY_UNFOLDED)
+        whenever(mockPosturesHelper.deviceStateToPosture(DEVICE_STATE_FOLDED))
+            .thenReturn(DEVICE_STATE_ROTATION_KEY_FOLDED)
+        whenever(mockPosturesHelper.deviceStateToPosture(DEVICE_STATE_HALF_FOLDED))
+            .thenReturn(DEVICE_STATE_ROTATION_KEY_HALF_FOLDED)
+        whenever(mockPosturesHelper.deviceStateToPosture(DEVICE_STATE_INVALID))
+            .thenReturn(DEVICE_STATE_ROTATION_LOCK_IGNORED)
+        whenever(mockPosturesHelper.deviceStateToPosture(DEVICE_STATE_REAR_DISPLAY))
+            .thenReturn(DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY)
+
+        settingManager =
+            DeviceStateAutoRotateSettingManagerImpl(
+                mockContext,
+                executor,
+                fakeSecureSettings,
+                mockHandler,
+                mockPosturesHelper,
+            )
+    }
+
+    @Test
+    fun registerListener_onSettingsChanged_listenerNotified() {
+        val listener = mock(DeviceStateAutoRotateSettingListener::class.java)
+        settingManager.registerListener(listener)
+
+        persistSettings(DEVICE_STATE_ROTATION_KEY_UNFOLDED, DEVICE_STATE_ROTATION_LOCK_LOCKED)
+
+        verify(listener).onSettingsChanged()
+    }
+
+    @Test
+    fun registerMultipleListeners_onSettingsChanged_allListenersNotified() {
+        val listener1 = mock(DeviceStateAutoRotateSettingListener::class.java)
+        val listener2 = mock(DeviceStateAutoRotateSettingListener::class.java)
+        settingManager.registerListener(listener1)
+        settingManager.registerListener(listener2)
+
+        persistSettings(DEVICE_STATE_ROTATION_KEY_UNFOLDED, DEVICE_STATE_ROTATION_LOCK_LOCKED)
+
+        verify(listener1).onSettingsChanged()
+        verify(listener2).onSettingsChanged()
+    }
+
+    @Test
+    fun unregisterListener_onSettingsChanged_listenerNotNotified() {
+        val listener = mock(DeviceStateAutoRotateSettingListener::class.java)
+        settingManager.registerListener(listener)
+        settingManager.unregisterListener(listener)
+
+        persistSettings(DEVICE_STATE_ROTATION_KEY_UNFOLDED, DEVICE_STATE_ROTATION_LOCK_LOCKED)
+
+        verify(listener, never()).onSettingsChanged()
+    }
+
+    @Test
+    fun getAutoRotateSetting_offForUnfolded_returnsOff() {
+        persistSettings(DEVICE_STATE_ROTATION_KEY_UNFOLDED, DEVICE_STATE_ROTATION_LOCK_LOCKED)
+
+        val autoRotateSetting = settingManager.getRotationLockSetting(DEVICE_STATE_UNFOLDED)
+
+        assertThat(autoRotateSetting).isEqualTo(DEVICE_STATE_ROTATION_LOCK_LOCKED)
+    }
+
+    @Test
+    fun getAutoRotateSetting_onForFolded_returnsOn() {
+        persistSettings(DEVICE_STATE_ROTATION_KEY_FOLDED, DEVICE_STATE_ROTATION_LOCK_UNLOCKED)
+
+        val autoRotateSetting = settingManager.getRotationLockSetting(DEVICE_STATE_FOLDED)
+
+        assertThat(autoRotateSetting).isEqualTo(DEVICE_STATE_ROTATION_LOCK_UNLOCKED)
+    }
+
+    @Test
+    fun getAutoRotateSetting_forInvalidPostureWithNoFallback_returnsIgnored() {
+        val autoRotateSetting = settingManager.getRotationLockSetting(DEVICE_STATE_INVALID)
+
+        assertThat(autoRotateSetting).isEqualTo(DEVICE_STATE_ROTATION_LOCK_IGNORED)
+    }
+
+    @Test
+    fun getAutoRotateSetting_forInvalidPosture_returnsSettingForFallbackPosture() {
+        persistSettings(DEVICE_STATE_ROTATION_KEY_UNFOLDED, DEVICE_STATE_ROTATION_LOCK_UNLOCKED)
+        persistSettings(DEVICE_STATE_ROTATION_KEY_FOLDED, DEVICE_STATE_ROTATION_LOCK_LOCKED)
+
+        val autoRotateSetting = settingManager.getRotationLockSetting(DEVICE_STATE_HALF_FOLDED)
+
+        assertThat(autoRotateSetting).isEqualTo(DEVICE_STATE_ROTATION_LOCK_UNLOCKED)
+    }
+
+    @Test
+    fun getAutoRotateSetting_invalidFormat_returnsIgnored() {
+        persistSettings("invalid_format")
+
+        val autoRotateSetting = settingManager.getRotationLockSetting(DEVICE_STATE_FOLDED)
+
+        assertThat(autoRotateSetting).isEqualTo(DEVICE_STATE_ROTATION_LOCK_IGNORED)
+    }
+
+    @Test
+    fun getAutoRotateSetting_invalidNumberFormat_returnsIgnored() {
+        persistSettings("$DEVICE_STATE_ROTATION_KEY_FOLDED:4")
+
+        val autoRotateSetting = settingManager.getRotationLockSetting(DEVICE_STATE_FOLDED)
+
+        assertThat(autoRotateSetting).isEqualTo(DEVICE_STATE_ROTATION_LOCK_IGNORED)
+    }
+
+    @Test
+    fun getAutoRotateSetting_multipleSettings_returnsCorrectSetting() {
+        persistSettings(
+            "$DEVICE_STATE_ROTATION_KEY_FOLDED:$DEVICE_STATE_ROTATION_LOCK_LOCKED:" +
+                    "$DEVICE_STATE_ROTATION_KEY_UNFOLDED:$DEVICE_STATE_ROTATION_LOCK_UNLOCKED"
+        )
+
+        val foldedSetting = settingManager.getRotationLockSetting(DEVICE_STATE_FOLDED)
+        val unfoldedSetting = settingManager.getRotationLockSetting(DEVICE_STATE_UNFOLDED)
+
+        assertThat(foldedSetting).isEqualTo(DEVICE_STATE_ROTATION_LOCK_LOCKED)
+        assertThat(unfoldedSetting).isEqualTo(DEVICE_STATE_ROTATION_LOCK_UNLOCKED)
+    }
+
+    @Test
+    fun isAutoRotateOff_offForUnfolded_returnsTrue() {
+        persistSettings(DEVICE_STATE_ROTATION_KEY_UNFOLDED, DEVICE_STATE_ROTATION_LOCK_LOCKED)
+
+        val isAutoRotateOff = settingManager.isRotationLocked(DEVICE_STATE_UNFOLDED)
+
+        assertThat(isAutoRotateOff).isTrue()
+    }
+
+    @Test
+    fun isRotationLockedForAllStates_allStatesLocked_returnsTrue() {
+        persistSettings(
+            "$DEVICE_STATE_ROTATION_KEY_FOLDED:$DEVICE_STATE_ROTATION_LOCK_LOCKED:" +
+                    "$DEVICE_STATE_ROTATION_KEY_UNFOLDED:$DEVICE_STATE_ROTATION_LOCK_LOCKED"
+        )
+
+        val isRotationLockedForAllStates = settingManager.isRotationLockedForAllStates()
+
+        assertThat(isRotationLockedForAllStates).isTrue()
+    }
+
+    @Test
+    fun isRotationLockedForAllStates_someStatesLocked_returnsFalse() {
+        persistSettings(
+            "$DEVICE_STATE_ROTATION_KEY_FOLDED:$DEVICE_STATE_ROTATION_LOCK_UNLOCKED:" +
+                    "$DEVICE_STATE_ROTATION_KEY_UNFOLDED:$DEVICE_STATE_ROTATION_LOCK_LOCKED"
+        )
+
+        val isRotationLockedForAllStates = settingManager.isRotationLockedForAllStates()
+
+        assertThat(isRotationLockedForAllStates).isFalse()
+    }
+
+    @Test
+    fun isRotationLockedForAllStates_noStatesLocked_returnsFalse() {
+        persistSettings(
+            "$DEVICE_STATE_ROTATION_KEY_FOLDED:$DEVICE_STATE_ROTATION_LOCK_UNLOCKED:" +
+                    "$DEVICE_STATE_ROTATION_KEY_UNFOLDED:$DEVICE_STATE_ROTATION_LOCK_UNLOCKED"
+        )
+
+        val isRotationLockedForAllStates = settingManager.isRotationLockedForAllStates()
+
+        assertThat(isRotationLockedForAllStates).isFalse()
+    }
+
+    @Test
+    fun getSettableDeviceStates_returnsExpectedValuesInOriginalOrder() {
+        val settableDeviceStates = settingManager.getSettableDeviceStates()
+
+        assertThat(settableDeviceStates)
+            .containsExactly(
+                SettableDeviceState(DEVICE_STATE_ROTATION_KEY_UNFOLDED, isSettable = true),
+                SettableDeviceState(DEVICE_STATE_ROTATION_KEY_FOLDED, isSettable = true),
+                SettableDeviceState(DEVICE_STATE_ROTATION_KEY_HALF_FOLDED, isSettable = false),
+                SettableDeviceState(DEVICE_STATE_ROTATION_KEY_REAR_DISPLAY, isSettable = false),
+                SettableDeviceState(DEVICE_STATE_ROTATION_LOCK_IGNORED, isSettable = false),
+            )
+    }
+
+    private fun persistSettings(devicePosture: Int, autoRotateSetting: Int) {
+        persistSettings("$devicePosture:$autoRotateSetting")
+    }
+
+    private fun persistSettings(value: String) {
+        fakeSecureSettings.putStringForUser(
+            Settings.Secure.DEVICE_STATE_ROTATION_LOCK, value, UserHandle.USER_CURRENT
+        )
+    }
+
+    private companion object {
+        const val DEVICE_STATE_FOLDED = 0
+        const val DEVICE_STATE_HALF_FOLDED = 1
+        const val DEVICE_STATE_UNFOLDED = 2
+        const val DEVICE_STATE_REAR_DISPLAY = 3
+        const val DEVICE_STATE_INVALID = 4
+    }
+}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
index 9f9aaf5..baebaf7 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
@@ -40,7 +40,6 @@
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.R;
-import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager.SettableDeviceState;
 
 import com.google.common.truth.Expect;
 
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
index eac69234..2620174 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java
@@ -70,6 +70,9 @@
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     private static final String DEVICE_NAME = "test_device_name";
+    private static final String DEVICE_ADDRESS_1 = "AA:BB:CC:DD:EE:11";
+    private static final String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22";
+    private static final String DEVICE_ADDRESS_3 = "AA:BB:CC:DD:EE:33";
 
     @Mock
     private LocalBluetoothAdapter mLocalAdapter;
@@ -132,6 +135,9 @@
         when(mA2dpProfile.isProfileReady()).thenReturn(true);
         when(mHearingAidProfile.isProfileReady()).thenReturn(true);
         when(mLeAudioProfile.isProfileReady()).thenReturn(true);
+        when(mDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1);
+        when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2);
+        when(mDevice3.getAddress()).thenReturn(DEVICE_ADDRESS_3);
         mCachedDevice1 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice1);
         mCachedDevice2 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice2);
         mCachedDevice3 = new CachedBluetoothDevice(mContext, mLocalProfileManager, mDevice3);
@@ -515,7 +521,6 @@
         cachedDevices.add(mCachedDevice2);
 
         int group1 = 1;
-        when(mDevice3.getAddress()).thenReturn("testAddress3");
         mCachedDevice1.setGroupId(group1);
         mCachedDevice3.setGroupId(group1);
         mCachedDevice1.addMemberDevice(mCachedDevice3);
@@ -620,18 +625,32 @@
     }
 
     @Test
-    public void dispatchActiveDeviceChanged_activeFromSubDevice_mainCachedDeviceActive() {
+    public void dispatchActiveDeviceChanged_activeFromSubDevice_bothCachedDevicesActive() {
         CachedBluetoothDevice subDevice = new CachedBluetoothDevice(mContext, mLocalProfileManager,
                 mDevice3);
         mCachedDevice1.setSubDevice(subDevice);
         when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
                 Collections.singletonList(mCachedDevice1));
-        mCachedDevice1.onProfileStateChanged(mHearingAidProfile,
-                BluetoothProfile.STATE_CONNECTED);
+        mCachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
 
-        assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
         mBluetoothEventManager.dispatchActiveDeviceChanged(subDevice, BluetoothProfile.HEARING_AID);
+
         assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isTrue();
+        assertThat(subDevice.isActiveDevice(BluetoothProfile.HEARING_AID)).isTrue();
+    }
+
+    @Test
+    public void dispatchActiveDeviceChanged_activeFromMemberDevice_allCachedDevicesActive() {
+        mCachedDevice1.addMemberDevice(mCachedDevice2);
+        when(mCachedDeviceManager.getCachedDevicesCopy()).thenReturn(
+                Collections.singletonList(mCachedDevice1));
+        mCachedDevice1.onProfileStateChanged(mLeAudioProfile, BluetoothProfile.STATE_CONNECTED);
+
+        mBluetoothEventManager.dispatchActiveDeviceChanged(mCachedDevice2,
+                BluetoothProfile.LE_AUDIO);
+
+        assertThat(mCachedDevice1.isActiveDevice(BluetoothProfile.LE_AUDIO)).isTrue();
+        assertThat(mCachedDevice2.isActiveDevice(BluetoothProfile.LE_AUDIO)).isTrue();
     }
 
     @Test
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index d929b0d..94aa955 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -341,4 +341,7 @@
 
     <!-- The default ringer mode. See `AudioManager` for list of valid values. -->
     <integer name="def_ringer_mode">2</integer>
+
+    <!-- Caps minsum contrast from -1.0 (Material API) to 0.0 (Android Support)-->
+    <bool name="config_increaseMinContrast">true</bool>
 </resources>
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
index fc61b1e..d3291b4 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/GlobalSettings.java
@@ -118,6 +118,8 @@
         Settings.Global.Wearable.CHARGING_SOUNDS_ENABLED,
         Settings.Global.Wearable.WRIST_DETECTION_AUTO_LOCKING_ENABLED,
         Settings.Global.Wearable.AUTO_BEDTIME_MODE,
+        Settings.Global.Wearable.GESTURE_PRIMARY_ACTION_USER_PREFERENCE,
+        Settings.Global.Wearable.GESTURE_DISMISS_ACTION_USER_PREFERENCE,
         Settings.Global.FORCE_ENABLE_PSS_PROFILING,
         Settings.Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_ENABLED,
         Settings.Global.Wearable.ACCESSIBILITY_VIBRATION_WATCH_TYPE,
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 0121d31..829d4cb 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -300,5 +300,9 @@
         Settings.Secure.DUAL_SHADE,
         Settings.Secure.BROWSER_CONTENT_FILTERS_ENABLED,
         Settings.Secure.SEARCH_CONTENT_FILTERS_ENABLED,
+        Settings.Secure.SPELL_CHECKER_ENABLED,
+        Settings.Secure.SELECTED_SPELL_CHECKER,
+        // SELECTED_SPELL_CHECKER_SUBTYPE needs to be restored after SELECTED_SPELL_CHECKER
+        Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE,
     };
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index cf0447f..98f5fac 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -124,7 +124,8 @@
                 Settings.System.NOTIFICATION_COOLDOWN_ENABLED,
                 Settings.System.NOTIFICATION_COOLDOWN_ALL,
                 Settings.System.NOTIFICATION_COOLDOWN_VIBRATE_UNLOCKED,
-                Settings.System.PREFERRED_REGION
+                Settings.System.PREFERRED_REGION,
+                Settings.System.CV_ENABLED
         ));
         if (Flags.backUpSmoothDisplayAndForcePeakRefreshRate()) {
             settings.add(Settings.System.PEAK_REFRESH_RATE);
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index 4c6a1ba..cd6521f 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -474,5 +474,7 @@
                                 String.valueOf(
                                         Global.Wearable.STATUS_TRAY_CONFIGURATION_SYSTEM_HIDDEN)
                         }));
+        VALIDATORS.put(Global.Wearable.GESTURE_PRIMARY_ACTION_USER_PREFERENCE, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Global.Wearable.GESTURE_DISMISS_ACTION_USER_PREFERENCE, BOOLEAN_VALIDATOR);
     }
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index 5eb6af6..d0f8462 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -472,5 +472,8 @@
         VALIDATORS.put(Secure.DUAL_SHADE, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.BROWSER_CONTENT_FILTERS_ENABLED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(Secure.SEARCH_CONTENT_FILTERS_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.SPELL_CHECKER_ENABLED, BOOLEAN_VALIDATOR);
+        VALIDATORS.put(Secure.SELECTED_SPELL_CHECKER, NULLABLE_COMPONENT_NAME_VALIDATOR);
+        VALIDATORS.put(Secure.SELECTED_SPELL_CHECKER_SUBTYPE, ANY_INTEGER_VALIDATOR);
     }
 }
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index 4f649ed..3a58440 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -271,5 +271,7 @@
         VALIDATORS.put(System.NOTIFICATION_COOLDOWN_ALL, BOOLEAN_VALIDATOR);
         VALIDATORS.put(System.NOTIFICATION_COOLDOWN_VIBRATE_UNLOCKED, BOOLEAN_VALIDATOR);
         VALIDATORS.put(System.PREFERRED_REGION, ANY_STRING_VALIDATOR);
+        VALIDATORS.put(System.CV_ENABLED,
+                new InclusiveIntegerRangeValidator(0, 1));
     }
 }
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index fc402d4..37ada93 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -37,10 +37,12 @@
 import android.app.backup.BackupDataOutput;
 import android.app.backup.BackupRestoreEventLogger;
 import android.app.backup.FullBackupDataOutput;
+import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.pm.PackageManager;
+import android.content.pm.ServiceInfo;
 import android.database.Cursor;
 import android.net.NetworkPolicy;
 import android.net.NetworkPolicyManager;
@@ -941,6 +943,7 @@
         Set<String> blockedSettings = getBlockedSettings(blockedSettingsArrayId);
 
         int restoredSettingsCount = 0;
+        boolean selectedSpellCheckerRestored = false;
         for (String key : allowlist.mSettingsAllowlist) {
             boolean isBlockedBySystem = blockedSettings != null && blockedSettings.contains(key);
             if (isBlockedBySystem || isBlockedByDynamicList(dynamicBlockList, contentUri,  key)) {
@@ -1068,6 +1071,25 @@
                     }
                     continue;
                 }
+            } else if (Settings.Secure.SELECTED_SPELL_CHECKER.equals(key)) {
+                ServiceInfo si = getServiceInfoOrNull(value);
+                if (si == null || si.applicationInfo == null) {
+                    Log.i(TAG, "Skipping restore for setting selected_spell_checker "
+                            + "as it is not installed");
+                    continue;
+                } else if (!si.applicationInfo.isSystemApp()
+                        && !si.applicationInfo.isUpdatedSystemApp()) {
+                    Log.i(TAG, "Skipping restore for setting selected_spell_checker "
+                            + "as it is not a system app");
+                    continue;
+                }
+                selectedSpellCheckerRestored = true;
+            } else if (Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE.equals(key)) {
+                if (!selectedSpellCheckerRestored) {
+                    Log.i(TAG, "Skipping restore for setting selected_spell_checker_subtype "
+                            + "as selected_spell_checker was not restored");
+                    continue;
+                }
             }
 
             if (Settings.System.FONT_SCALE.equals(key)) {
@@ -1085,6 +1107,21 @@
                 Log.d(TAG, "Restored font scale from: " + toRestore + " to " + value);
             }
 
+            if (Settings.Secure.CONTRAST_LEVEL.equals(key)) {
+                boolean increaseMinContrast = getBaseContext().getResources()
+                        .getBoolean(R.bool.config_increaseMinContrast);
+
+                float valueFloat;
+                try {
+                    valueFloat = Float.parseFloat(value);
+                } catch (NumberFormatException e) {
+                    valueFloat = 0.0f;
+                }
+
+                float newValue = Math.max(valueFloat, increaseMinContrast ? 0.0f : -1.0f);
+                value = String.valueOf(newValue);
+            }
+
             settingsHelper.restoreValue(this, cr, contentValues, destination, key, value,
                     mRestoredFromSdkInt);
 
@@ -1868,6 +1905,18 @@
         return result;
     }
 
+    @Nullable
+    private ServiceInfo getServiceInfoOrNull(@Nullable String flattenedServiceName) {
+        if (flattenedServiceName == null) return null;
+        ComponentName componentName = ComponentName.unflattenFromString(flattenedServiceName);
+        if (componentName == null) return null;
+        try {
+            return getBaseContext().getPackageManager().getServiceInfo(componentName, 0);
+        } catch (PackageManager.NameNotFoundException e) {
+            return null;
+        }
+    }
+
     /**
      * Store the allowlist of settings to be backed up and validators for them.
      */
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index e7527dc..584b21a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -3157,6 +3157,12 @@
                 SystemSettingsProto.Volume.MASTER_BALANCE);
         p.end(volumeToken);
 
+        final long systemDisplayToken = p.start(SystemSettingsProto.DISPLAY);
+        dumpSetting(s, p,
+                Settings.System.CV_ENABLED,
+                SystemSettingsProto.Display.CV_ENABLED);
+        p.end(systemDisplayToken);
+
         dumpSetting(s, p,
                 Settings.System.WHEN_TO_MAKE_WIFI_CALLS,
                 SystemSettingsProto.WHEN_TO_MAKE_WIFI_CALLS);
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 70c042c..7179cbd 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -567,6 +567,7 @@
                     Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
                     Settings.Global.HEARING_DEVICE_LOCAL_AMBIENT_VOLUME, // cache per hearing device
                     Settings.Global.HEARING_DEVICE_LOCAL_NOTIFICATION, // cache per hearing device
+                    Settings.Global.REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS,
                     Settings.Global.Wearable.COMBINED_LOCATION_ENABLE,
                     Settings.Global.Wearable.HAS_PAY_TOKENS,
                     Settings.Global.Wearable.GMS_CHECKIN_TIMEOUT_MIN,
@@ -749,15 +750,12 @@
                  Settings.Secure.SECURE_FRP_MODE,
                  Settings.Secure.SEARCH_WEB_RESULTS_OVERRIDE_LIMIT,
                  Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
-                 Settings.Secure.SELECTED_SPELL_CHECKER,  // Intentionally removed in Q
-                 Settings.Secure.SELECTED_SPELL_CHECKER_SUBTYPE,  // Intentionally removed in Q
                  Settings.Secure.SETTINGS_CLASSNAME,
                  Settings.Secure.SHOW_NOTE_ABOUT_NOTIFICATION_HIDING, // candidate?
                  Settings.Secure.SHOW_ROTATION_SUGGESTIONS,
                  Settings.Secure.SKIP_FIRST_USE_HINTS, // candidate?
                  Settings.Secure.SLEEP_TIMEOUT,
                  Settings.Secure.SMS_DEFAULT_APPLICATION,
-                 Settings.Secure.SPELL_CHECKER_ENABLED,  // Intentionally removed in Q
                  Settings.Secure.TRUST_AGENTS_INITIALIZED,
                  Settings.Secure.KNOWN_TRUST_AGENTS_INITIALIZED,
                  Settings.Secure.TV_APP_USES_NON_SYSTEM_INPUTS,
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
index 48c360b..bc727d3 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsBackupAgentTest.java
@@ -16,15 +16,15 @@
 
 package com.android.providers.settings;
 
-import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_NEW_CONFIG;
-import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SOFTAP_CONFIG;
 import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SIM_SPECIFIC_SETTINGS_2;
+import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_SOFTAP_CONFIG;
+import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_NEW_CONFIG;
 import static com.android.providers.settings.SettingsBackupRestoreKeys.KEY_WIFI_SETTINGS_BACKUP_DATA;
 
 import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
 import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertTrue;
 
 import static org.junit.Assert.assertArrayEquals;
@@ -35,12 +35,10 @@
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.when;
 
-import android.annotation.Nullable;
 import android.app.backup.BackupAnnotations.BackupDestination;
 import android.app.backup.BackupAnnotations.OperationType;
 import android.app.backup.BackupDataInput;
 import android.app.backup.BackupDataOutput;
-import android.app.backup.BackupRestoreEventLogger;
 import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
 import android.content.ContentResolver;
 import android.content.ContentValues;
@@ -69,13 +67,11 @@
 
 import com.android.window.flags.Flags;
 
-import java.util.List;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.Mockito;
 import org.mockito.junit.MockitoJUnit;
 import org.mockito.junit.MockitoRule;
 
@@ -331,6 +327,47 @@
     }
 
     @Test
+    public void testOnRestore_minContrastLevelIsRestoredToZero() {
+        mAgentUnderTest = new TestFriendlySettingsBackupAgent() {
+            @Override
+            protected Set<String> getBlockedSettings(int blockedSettingsArrayId) {
+                return new HashSet<>();
+            }
+        };
+        mAgentUnderTest.attach(mContext);
+
+        TestSettingsHelper settingsHelper = new TestSettingsHelper(mContext);
+        mAgentUnderTest.mSettingsHelper = settingsHelper;
+
+        String contrastLevelValue = "-1.0";
+        Map<String, String> settingsToRestore = Map.of(Settings.Secure.CONTRAST_LEVEL,
+                contrastLevelValue);
+
+        byte[] backupData = generateBackupData(settingsToRestore);
+        mAgentUnderTest.restoreSettings(
+                backupData,
+                /* pos */ 0,
+                backupData.length,
+                Settings.Secure.CONTENT_URI,
+                null,
+                null,
+                null,
+                /* blockedSettingsArrayId */ 0,
+                Collections.emptySet(),
+                Collections.emptySet(),
+                KEY_SECURE);
+
+        // Check that the contrast level has been restored.
+        assertTrue(settingsHelper.mWrittenValues.containsKey(Settings.Secure.CONTRAST_LEVEL));
+
+        String restoredContrastLevel = settingsHelper.mWrittenValues.get(
+                Settings.Secure.CONTRAST_LEVEL);
+
+        float restoredFloat = Float.parseFloat(restoredContrastLevel);
+        assertEquals(0.0f, restoredFloat, 0.001f);
+    }
+
+    @Test
     @DisableFlags(com.android.server.backup.Flags.FLAG_ENABLE_METRICS_SETTINGS_BACKUP_AGENTS)
     public void onCreate_metricsFlagIsDisabled_areAgentMetricsEnabledIsFalse() {
         mAgentUnderTest.onCreate();
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 55f7317..758ad79 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -1015,6 +1015,10 @@
     <uses-permission android:name="android.permission.MANAGE_GLOBAL_SOUND_QUALITY_SERVICE" />
     <uses-permission android:name="android.permission.READ_COLOR_ZONES" />
 
+    <!-- Permissions required for CTS test - CtsModernMediaProviderTests -->
+    <uses-permission android:name="com.android.providers.media.permission.ACCESS_OEM_METADATA" />
+    <uses-permission android:name="com.android.providers.media.permission.UPDATE_OEM_METADATA" />
+
     <!-- Permission required for trade-in mode testing -->
     <uses-permission android:name="android.permission.ENTER_TRADE_IN_MODE" />
 
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index fb0678f..5bba99f 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -255,11 +255,11 @@
     /** Always keep remote bugreport files created in the last day. */
     private static final long REMOTE_MIN_KEEP_AGE = DateUtils.DAY_IN_MILLIS;
 
-    /** Minimum delay for sending last update notification */
-    private static final int DELAY_NOTIFICATION_MS = 250;
-
     private final Object mLock = new Object();
 
+/** Minimum delay between percentage points before sending an update notification */
+    private static final int MIN_NOTIFICATION_GAP = 10;
+
     /** Managed bugreport info (keyed by id) */
     @GuardedBy("mLock")
     private final SparseArray<BugreportInfo> mBugreportInfos = new SparseArray<>();
@@ -1460,17 +1460,6 @@
      * Sends a notification indicating the bugreport has finished so use can share it.
      */
     private void sendBugreportNotification(BugreportInfo info, boolean takingScreenshot) {
-
-        final long lastUpdate = System.currentTimeMillis() - info.lastUpdate.longValue();
-        if (lastUpdate < DELAY_NOTIFICATION_MS) {
-            Log.d(TAG, "Delaying final notification for "
-                    + (DELAY_NOTIFICATION_MS - lastUpdate) + " ms ");
-            mMainThreadHandler.postDelayed(() -> {
-                sendBugreportNotification(info, takingScreenshot);
-            }, DELAY_NOTIFICATION_MS - lastUpdate);
-            return;
-        }
-
         // Since adding the details can take a while, do it before notifying user.
         addDetailsToZipFile(info);
 
@@ -1523,7 +1512,7 @@
             builder.setSubText(info.getName());
         }
 
-        Log.v(TAG, "Sending 'Share' notification for ID " + info.id + ": " + title);
+        Log.d(TAG, "Sending 'Share' notification for ID " + info.id + ": " + title);
         NotificationManager.from(mContext).notify(info.id, builder.build());
     }
 
@@ -2753,6 +2742,11 @@
         if (progress > CAPPED_PROGRESS) {
             progress = CAPPED_PROGRESS;
         }
+
+        if ((progress - info.lastProgress.intValue()) < MIN_NOTIFICATION_GAP) {
+            return;
+        }
+
         if (DEBUG) {
             if (progress != info.progress.intValue()) {
                 Log.v(TAG, "Updating progress for name " + info.getName() + "(id: " + info.id
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 129949f..7f45443 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -429,6 +429,7 @@
     manifest: "AndroidManifest-res.xml",
     flags_packages: [
         "android.app.flags-aconfig",
+        "com_android_systemui_flags",
     ],
 }
 
diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING
index 1362ffe..86559fd 100644
--- a/packages/SystemUI/TEST_MAPPING
+++ b/packages/SystemUI/TEST_MAPPING
@@ -1,22 +1,6 @@
 {
-  // Curious where your @Scenario tests are running?
-  //
-  // @Ignore: Will not run in any configuration
-  //
-  // @FlakyTest: Tests that don't block pre/postsubmit but are staged to run known failures.
-  //             Tests will run in postsubmit on sysui-e2e-staged suite.
-  //
-  //
-  // @PlatinumTest: Marking your test with this annotation will put your tests in presubmit.
-  //                Please DO NOT annotate new or old tests with @PlatinumTest annotation
-  //                without discussing with mdb:android-platinum
-  //
-  // @Postsubmit: Do not use this annotation for e2e tests. This won't have any affect.
-
-  // For all other e2e tests which are not platinum, they run in sysui-silver suite,that
-  // primarily runs in postsubmit with an exception to e2e test related changes.
-  // If you want to see one shot place to monitor all e2e tests, look for
-  // sysui-e2e-staged suite.
+  // Test mappings for SystemUI unit tests.
+  // For e2e mappings, see go/sysui-e2e-test-mapping
 
   // v2/android-virtual-infra/test_mapping/presubmit-avd
   "presubmit": [
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml
index db733fc..afb337d 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values-iw/strings.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <resources xmlns:android="http://schemas.android.com/apk/res/android"
     xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
-    <string name="accessibility_menu_service_name" msgid="730136711554740131">"תפריט נגישות"</string>
+    <string name="accessibility_menu_service_name" msgid="730136711554740131">"תפריט הנגישות"</string>
     <string name="accessibility_menu_intro" msgid="3164193281544042394">"תפריט הנגישות הוא תפריט גדול שמופיע במסך ומאפשר לשלוט במכשיר. אפשר לנעול את המכשיר, לשלוט בעוצמת הקול ובבהירות, לצלם צילומי מסך ועוד."</string>
     <string name="assistant_label" msgid="6796392082252272356">"Assistant"</string>
     <string name="assistant_utterance" msgid="65509599221141377">"Assistant"</string>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
index 7172619..1543dbe 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
@@ -46,7 +46,7 @@
 import android.media.AudioManager;
 import android.os.PowerManager;
 import android.os.UserManager;
-import android.platform.uiautomator_helpers.WaitUtils;
+import android.platform.uiautomatorhelpers.WaitUtils;
 import android.provider.Settings;
 import android.util.Log;
 import android.view.Display;
diff --git a/packages/SystemUI/aconfig/accessibility.aconfig b/packages/SystemUI/aconfig/accessibility.aconfig
index 3cb3025..c6bc1c7 100644
--- a/packages/SystemUI/aconfig/accessibility.aconfig
+++ b/packages/SystemUI/aconfig/accessibility.aconfig
@@ -155,3 +155,13 @@
       purpose: PURPOSE_BUGFIX
     }
 }
+
+flag {
+    name: "hearing_devices_input_routing_ui_improvement"
+    namespace: "accessibility"
+    description: "UI improvement for hearing device input routing feature"
+    bug: "397314200"
+    metadata {
+        purpose: PURPOSE_BUGFIX
+    }
+}
diff --git a/packages/SystemUI/aconfig/systemui.aconfig b/packages/SystemUI/aconfig/systemui.aconfig
index ab18612..1c37687 100644
--- a/packages/SystemUI/aconfig/systemui.aconfig
+++ b/packages/SystemUI/aconfig/systemui.aconfig
@@ -213,18 +213,6 @@
 }
 
 flag {
-    name: "notification_undo_guts_on_config_changed"
-    namespace: "systemui"
-    description: "Fixes a bug where a theme or font change while notification guts were open"
-        " (e.g. the snooze options or notification info) would show an empty notification by"
-        " closing the guts and undoing changes."
-    bug: "379267630"
-    metadata {
-        purpose: PURPOSE_BUGFIX
-    }
-}
-
-flag {
    name: "pss_app_selector_recents_split_screen"
    namespace: "systemui"
    description: "Allows recent apps selected for partial screenshare to be launched in split screen mode"
@@ -410,13 +398,6 @@
 }
 
 flag {
-    name: "light_reveal_migration"
-    namespace: "systemui"
-    description: "Move LightRevealScrim to recommended architecture"
-    bug: "281655028"
-}
-
-flag {
    name: "theme_overlay_controller_wakefulness_deprecation"
    namespace: "systemui"
    description: "Replacing WakefulnessLifecycle by KeyguardTransitionInteractor in "
@@ -544,6 +525,14 @@
 }
 
 flag {
+  name: "status_bar_font_updates"
+  namespace: "systemui"
+  description: "Read only flag for using a new font in the status bar"
+  bug: "393609116"
+  is_fixed_read_only: true
+}
+
+flag {
     name: "promote_notifications_automatically"
     namespace: "systemui"
     description: "Flag to automatically turn certain notifications into promoted notifications so "
@@ -1455,16 +1444,6 @@
 }
 
 flag {
-  name: "dozeui_scheduling_alarms_background_execution"
-  namespace: "systemui"
-  description: "Decide whether to execute binder calls to schedule alarms in background thread"
-  bug: "330492575"
-  metadata {
-    purpose: PURPOSE_BUGFIX
-  }
-}
-
-flag {
     name: "media_lockscreen_launch_animation"
     namespace : "systemui"
     description : "Enable the origin launch animation for UMO when opening on top of lockscreen."
@@ -2148,3 +2127,14 @@
     description: "Enables return animations for status bar chips"
     bug: "202516970"
 }
+
+flag {
+    name: "media_projection_grey_error_text"
+    namespace: "systemui"
+    description: "Set the error text color to grey when app sharing is hidden by the requesting app"
+    bug: "400877402"
+    metadata {
+       purpose: PURPOSE_BUGFIX
+    }
+}
+
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
index 7ee6a6e..5599db7 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/ActivityTransitionAnimator.kt
@@ -1216,6 +1216,13 @@
         private var animation: TransitionAnimator.Animation? = null
 
         /**
+         * Whether the opening/closing window needs to reparented to the view's window at the
+         * beginning of the animation. Since we don't always do this, we need to keep track of it in
+         * order to have the rest of the animation behave correctly.
+         */
+        var reparent = false
+
+        /**
          * A timeout to cancel the transition animation if the remote animation is not started or
          * cancelled within [TRANSITION_TIMEOUT] milliseconds after the intent was started.
          *
@@ -1469,6 +1476,17 @@
                 transitionAnimator.isExpandingFullyAbove(controller.transitionContainer, endState)
             val windowState = startingWindowState ?: controller.windowAnimatorState
 
+            // We only reparent launch animations. In current integrations, returns are
+            // not affected by the issue solved by reparenting, and they present
+            // additional problems when the view lives in the Status Bar.
+            // TODO(b/397646693): remove this exception.
+            val isEligibleForReparenting = controller.isLaunching
+            val viewRoot = controller.transitionContainer.viewRootImpl
+            val skipReparenting = skipReparentTransaction || viewRoot == null
+            if (moveTransitionAnimationLayer() && isEligibleForReparenting && !skipReparenting) {
+                reparent = true
+            }
+
             // We animate the opening window and delegate the view expansion to [this.controller].
             val delegate = this.controller
             val controller =
@@ -1536,16 +1554,13 @@
                             )
                         }
 
-                        if (moveTransitionAnimationLayer() && !skipReparentTransaction) {
+                        if (reparent) {
                             // Ensure that the launching window is rendered above the view's window,
                             // so it is not obstructed.
                             // TODO(b/397180418): re-use the start transaction once the
                             //  RemoteAnimation wrapper is cleaned up.
                             SurfaceControl.Transaction().use {
-                                it.reparent(
-                                    window.leash,
-                                    controller.transitionContainer.viewRootImpl.surfaceControl,
-                                )
+                                it.reparent(window.leash, viewRoot.surfaceControl)
                                 it.apply()
                             }
                         }
@@ -1603,7 +1618,7 @@
                     null
                 }
             val fadeWindowBackgroundLayer =
-                if (moveTransitionAnimationLayer()) {
+                if (reparent) {
                     false
                 } else {
                     !controller.isBelowAnimatingWindow
@@ -1727,7 +1742,7 @@
             // fade in progressively. Otherwise, it should be fully opaque and will be progressively
             // revealed as the window background color layer above the window fades out.
             val alpha =
-                if (moveTransitionAnimationLayer() || controller.isBelowAnimatingWindow) {
+                if (reparent || controller.isBelowAnimatingWindow) {
                     if (controller.isLaunching) {
                         interpolators.contentAfterFadeInInterpolator.getInterpolation(
                             windowProgress
diff --git a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
index 694fc8e..060f0c9 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
+++ b/packages/SystemUI/animation/src/com/android/systemui/animation/RemoteAnimationRunnerCompat.java
@@ -22,6 +22,7 @@
 import static android.view.WindowManager.TRANSIT_OPEN;
 import static android.view.WindowManager.TRANSIT_TO_BACK;
 import static android.view.WindowManager.TRANSIT_TO_FRONT;
+import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_EXIT_BY_MINIMIZE_TRANSITION_BUGFIX;
 import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_EXIT_TRANSITIONS_BUGFIX;
 import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
 
@@ -196,6 +197,10 @@
                     // Release surface references now. This is apparently to free GPU memory
                     // before GC would.
                     info.releaseAllSurfaces();
+                    // Make sure that the transition leashes created are not leaked.
+                    for (SurfaceControl leash : leashMap.values()) {
+                        finishTransaction.reparent(leash, null);
+                    }
                     // Don't release here since launcher might still be using them. Instead
                     // let launcher release them (eg. via RemoteAnimationTargets)
                     leashMap.clear();
@@ -244,6 +249,17 @@
                 runner.onAnimationCancelled();
                 finishRunnable.run();
             }
+
+            @Override
+            public void onTransitionConsumed(IBinder transition, boolean aborted)
+                    throws RemoteException {
+                // Notify the remote runner that the transition has been canceled if the transition
+                // was merged into another transition or aborted
+                synchronized (mFinishRunnables) {
+                    mFinishRunnables.remove(transition);
+                }
+                runner.onAnimationCancelled();
+            }
         };
     }
 
@@ -261,7 +277,8 @@
             SurfaceControl.Transaction startTransaction
     ) {
         checkArgument(isOpeningMode(launcherChange.getMode()));
-        if (!isClosingType(info.getType())) {
+        if (!isClosingType(info.getType())
+                && !ENABLE_DESKTOP_WINDOWING_EXIT_BY_MINIMIZE_TRANSITION_BUGFIX.isTrue()) {
             return;
         }
         for (int i = info.getChanges().size() - 1; i >= 0; --i) {
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt b/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
index df50eb8..da07fbd 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/PlatformButtons.kt
@@ -101,10 +101,17 @@
     modifier: Modifier = Modifier,
     enabled: Boolean = true,
     colors: IconButtonColors = iconButtonColors(),
+    shape: Shape = IconButtonDefaults.standardShape,
     @DrawableRes iconResource: Int,
     contentDescription: String?,
 ) {
-    IconButton(modifier = modifier, onClick = onClick, enabled = enabled, colors = colors) {
+    IconButton(
+        modifier = modifier,
+        onClick = onClick,
+        enabled = enabled,
+        colors = colors,
+        shape = shape,
+    ) {
         Icon(
             painter = painterResource(id = iconResource),
             contentDescription = contentDescription,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
index a352b1e..cd9fcef 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/Expandable.kt
@@ -21,7 +21,6 @@
 import android.view.ViewGroup
 import android.view.ViewGroupOverlay
 import androidx.compose.foundation.BorderStroke
-import androidx.compose.foundation.background
 import androidx.compose.foundation.border
 import androidx.compose.foundation.clickable
 import androidx.compose.foundation.interaction.MutableInteractionSource
@@ -62,6 +61,7 @@
 import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.graphics.drawscope.scale
 import androidx.compose.ui.graphics.drawscope.translate
+import androidx.compose.ui.graphics.isSpecified
 import androidx.compose.ui.graphics.layer.GraphicsLayer
 import androidx.compose.ui.graphics.layer.drawLayer
 import androidx.compose.ui.graphics.rememberGraphicsLayer
@@ -82,6 +82,7 @@
 import androidx.lifecycle.setViewTreeViewModelStoreOwner
 import androidx.savedstate.findViewTreeSavedStateRegistryOwner
 import androidx.savedstate.setViewTreeSavedStateRegistryOwner
+import com.android.compose.modifiers.animatedBackground
 import com.android.compose.modifiers.thenIf
 import com.android.compose.ui.graphics.FullScreenComposeViewInOverlay
 import com.android.systemui.animation.ComposableControllerFactory
@@ -126,6 +127,8 @@
  *
  * @sample com.android.systemui.compose.gallery.ActivityLaunchScreen
  * @sample com.android.systemui.compose.gallery.DialogLaunchScreen
+ * @param defaultMinSize true if a default minimum size should be enforced even if this Expandable
+ *   isn't currently clickable and false otherwise.
  */
 @Composable
 fun Expandable(
@@ -139,6 +142,7 @@
     // TODO(b/285250939): Default this to true then remove once the Compose QS expandables have
     // proven that the new implementation is robust.
     useModifierBasedImplementation: Boolean = false,
+    defaultMinSize: Boolean = true,
     transitionControllerFactory: ComposableControllerFactory? = null,
     content: @Composable (Expandable) -> Unit,
 ) {
@@ -154,6 +158,7 @@
         onClick,
         interactionSource,
         useModifierBasedImplementation,
+        defaultMinSize,
         content,
     )
 }
@@ -181,6 +186,8 @@
  *
  * @sample com.android.systemui.compose.gallery.ActivityLaunchScreen
  * @sample com.android.systemui.compose.gallery.DialogLaunchScreen
+ * @param defaultMinSize true if a default minimum size should be enforced even if this Expandable
+ *   isn't currently clickable and false otherwise.
  */
 @Composable
 fun Expandable(
@@ -191,6 +198,7 @@
     // TODO(b/285250939): Default this to true then remove once the Compose QS expandables have
     // proven that the new implementation is robust.
     useModifierBasedImplementation: Boolean = false,
+    defaultMinSize: Boolean = true,
     content: @Composable (Expandable) -> Unit,
 ) {
     val controller = controller as ExpandableControllerImpl
@@ -208,7 +216,12 @@
 
     if (useModifierBasedImplementation) {
         Box(modifier.expandable(controller, onClick, interactionSource)) {
-            WrappedContent(controller.expandable, controller.contentColor, content)
+            WrappedContent(
+                controller.expandable,
+                controller.contentColor,
+                defaultMinSize = defaultMinSize,
+                content,
+            )
         }
         return
     }
@@ -220,7 +233,7 @@
     val wrappedContent =
         remember(content) {
             movableContentOf { expandable: Expandable ->
-                WrappedContent(expandable, contentColor, content)
+                WrappedContent(expandable, contentColor, defaultMinSize = defaultMinSize, content)
             }
         }
 
@@ -291,7 +304,7 @@
                     .updateExpandableSize()
                     .then(minInteractiveSizeModifier)
                     .then(clickModifier(controller, onClick, interactionSource))
-                    .background(color, shape)
+                    .animatedBackground(color, shape = shape)
                     .border(controller)
                     .onGloballyPositioned { controller.boundsInComposeViewRoot = it.boundsInRoot() }
             ) {
@@ -305,21 +318,32 @@
 private fun WrappedContent(
     expandable: Expandable,
     contentColor: Color,
+    defaultMinSize: Boolean,
     content: @Composable (Expandable) -> Unit,
 ) {
-    CompositionLocalProvider(LocalContentColor provides contentColor) {
-        // We make sure that the content itself (wrapped by the background) is at least 40.dp, which
-        // is the same as the M3 buttons. This applies even if onClick is null, to make it easier to
-        // write expandables that are sometimes clickable and sometimes not. There shouldn't be any
-        // Expandable smaller than 40dp because if the expandable is not clickable directly, then
-        // something in its content should be (and with a size >= 40dp).
-        val minSize = 40.dp
-        Box(
-            Modifier.defaultMinSize(minWidth = minSize, minHeight = minSize),
-            contentAlignment = Alignment.Center,
-        ) {
-            content(expandable)
+    val minSizeContent =
+        @Composable {
+            if (defaultMinSize) {
+                // We make sure that the content itself (wrapped by the background) is at
+                // least 40.dp, which is the same as the M3 buttons. This applies even if
+                // onClick is null, to make it easier to write expandables that are
+                // sometimes clickable and sometimes not.
+                val minSize = 40.dp
+                Box(
+                    modifier = Modifier.defaultMinSize(minWidth = minSize, minHeight = minSize),
+                    contentAlignment = Alignment.Center,
+                ) {
+                    content(expandable)
+                }
+            } else {
+                content(expandable)
+            }
         }
+
+    if (contentColor.isSpecified) {
+        CompositionLocalProvider(LocalContentColor provides contentColor, content = minSizeContent)
+    } else {
+        minSizeContent()
     }
 }
 
@@ -345,7 +369,7 @@
         .thenIf(drawContent) {
             Modifier.border(controller)
                 .then(clickModifier(controller, onClick, interactionSource))
-                .background(controller.color, controller.shape)
+                .animatedBackground(controller.color, shape = controller.shape)
         }
         .onPlaced { controller.boundsInComposeViewRoot = it.boundsInRoot() }
         .drawWithContent {
@@ -422,7 +446,7 @@
             // Background.
             this@draw.drawBackground(
                 state,
-                controller.color,
+                controller.color(),
                 controller.borderStroke,
                 size = Size(state.width.toFloat(), state.height.toFloat()),
             )
@@ -469,7 +493,7 @@
 /** Draw [content] in [overlay] while respecting its screen position given by [animatorState]. */
 @Composable
 private fun AnimatedContentInOverlay(
-    color: Color,
+    color: () -> Color,
     sizeInOriginalLayout: Size,
     overlay: ViewGroupOverlay,
     controller: ExpandableControllerImpl,
@@ -523,7 +547,7 @@
                                     return@drawWithContent
                                 }
 
-                                drawBackground(animatorState, color, controller.borderStroke)
+                                drawBackground(animatorState, color(), controller.borderStroke)
                                 drawContent()
                             },
                             // We center the content in the expanding container.
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
index 72da175e..d7d5a48 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/animation/ExpandableController.kt
@@ -26,7 +26,6 @@
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.Stable
-import androidx.compose.runtime.State
 import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
@@ -80,6 +79,24 @@
     borderStroke: BorderStroke? = null,
     transitionControllerFactory: ComposableControllerFactory? = null,
 ): ExpandableController {
+    return rememberExpandableController(
+        color = { color },
+        shape = shape,
+        contentColor = contentColor,
+        borderStroke = borderStroke,
+        transitionControllerFactory = transitionControllerFactory,
+    )
+}
+
+/** Create an [ExpandableController] to control an [Expandable]. */
+@Composable
+fun rememberExpandableController(
+    color: () -> Color,
+    shape: Shape,
+    contentColor: Color = Color.Unspecified,
+    borderStroke: BorderStroke? = null,
+    transitionControllerFactory: ComposableControllerFactory? = null,
+): ExpandableController {
     val composeViewRoot = LocalView.current
     val density = LocalDensity.current
     val layoutDirection = LocalLayoutDirection.current
@@ -125,7 +142,7 @@
 }
 
 internal class ExpandableControllerImpl(
-    internal val color: Color,
+    internal val color: () -> Color,
     internal val contentColor: Color,
     internal val shape: Shape,
     internal val borderStroke: BorderStroke?,
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
index 959f28f..362748e 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedDraggable.kt
@@ -95,13 +95,41 @@
      * nested scrollable.
      *
      * This is called whenever a nested scrollable does not consume some scroll amount. If this
-     * returns `true`, then [onDragStarted] will be called and this draggable will have priority and
+     * returns `true`, then [onDragStarted] will be called, this draggable will have priority and
      * consume all future events during preScroll until the nested scroll is finished.
      */
-    fun shouldConsumeNestedScroll(sign: Float): Boolean
+    fun shouldConsumeNestedPostScroll(sign: Float): Boolean = true
+
+    /**
+     * Whether this draggable should consume any scroll amount with the given [sign] *before* it can
+     * be consumed by a nested scrollable.
+     *
+     * This is called before a nested scrollable is able to consume that scroll amount. If this
+     * returns `true`, then [onDragStarted] will be called, this draggable will have priority and
+     * consume all future scroll events during preScroll until the nested scroll is finished.
+     */
+    fun shouldConsumeNestedPreScroll(sign: Float): Boolean = false
 
     interface Controller {
         /**
+         * Whether this controller is ready to drag. [onDrag] will be called only if this returns
+         * `true`, and any drag event will be ignored until then.
+         *
+         * This can for instance be used to wait for the content we are dragging to to be composed
+         * before actually dragging, reducing perceivable jank at the beginning of a drag.
+         */
+        val isReadyToDrag: Boolean
+            get() = true
+
+        /**
+         * Whether drags that were started from nested scrolls should be automatically
+         * [stopped][onDragStopped] as soon as they don't consume the entire `delta` passed to
+         * [onDrag].
+         */
+        val autoStopNestedDrags: Boolean
+            get() = false
+
+        /**
          * Drag by [delta] pixels.
          *
          * @return the consumed [delta]. Any non-consumed delta will be dispatched to the next
@@ -256,6 +284,9 @@
     /** The pointers currently down, in order of which they were done and mapping to their type. */
     private val pointersDown = linkedMapOf<PointerId, PointerType>()
 
+    /** Whether the next drag event should be ignored. */
+    private var ignoreNextDrag = false
+
     init {
         delegate(nestedScrollModifierNode(this, nestedScrollDispatcher))
     }
@@ -408,6 +439,7 @@
         velocityTracker: VelocityTracker,
     ) {
         velocityTracker.addPointerInputChange(change)
+        if (shouldIgnoreDrag(controller)) return
 
         scrollWithOverscroll(delta.toOffset()) { deltaFromOverscroll ->
             scrollWithNestedScroll(deltaFromOverscroll) { deltaFromNestedScroll ->
@@ -416,6 +448,23 @@
         }
     }
 
+    private fun shouldIgnoreDrag(controller: NestedDraggable.Controller): Boolean {
+        return when {
+            !controller.isReadyToDrag -> {
+                // The controller is not ready yet, so we are waiting for an expensive frame to be
+                // composed. We should ignore this drag and the next one, given that the first delta
+                // after an expensive frame will be large.
+                ignoreNextDrag = true
+                true
+            }
+            ignoreNextDrag -> {
+                ignoreNextDrag = false
+                true
+            }
+            else -> false
+        }
+    }
+
     private fun onDragStopped(controller: NestedDraggable.Controller, velocity: Velocity) {
         // We launch in the scope of the dispatcher so that the fling is not cancelled if this node
         // is removed right after onDragStopped() is called.
@@ -540,6 +589,14 @@
     }
 
     override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+        val sign = available.toFloat().sign
+        maybeCreateNewController(
+            sign = sign,
+            condition = {
+                source == NestedScrollSource.UserInput &&
+                    draggable.shouldConsumeNestedPreScroll(sign)
+            },
+        )
         val controller = nestedScrollController ?: return Offset.Zero
         return scrollWithOverscroll(controller, available)
     }
@@ -560,33 +617,48 @@
         }
 
         val sign = offset.sign
-        if (
-            nestedDragsEnabled &&
-                nestedScrollController == null &&
-                // TODO(b/388231324): Remove this.
-                !lastEventWasScrollWheel &&
-                draggable.shouldConsumeNestedScroll(sign) &&
-                lastFirstDown != null
-        ) {
-            val startedPosition = checkNotNull(lastFirstDown)
-
-            // TODO(b/382665591): Ensure that there is at least one pointer down.
-            val pointersDownCount = pointersDown.size.coerceAtLeast(1)
-            val pointerType = pointersDown.entries.firstOrNull()?.value
-            nestedScrollController =
-                NestedScrollController(
-                    overscrollEffect,
-                    draggable.onDragStarted(startedPosition, sign, pointersDownCount, pointerType),
-                )
-        }
-
+        maybeCreateNewController(
+            sign,
+            condition = { draggable.shouldConsumeNestedPostScroll(sign) },
+        )
         val controller = nestedScrollController ?: return Offset.Zero
         return scrollWithOverscroll(controller, available)
     }
 
+    private fun maybeCreateNewController(sign: Float, condition: () -> Boolean) {
+        if (
+            !nestedDragsEnabled ||
+                nestedScrollController != null ||
+                lastEventWasScrollWheel ||
+                lastFirstDown == null ||
+                !condition()
+        ) {
+            return
+        }
+
+        // TODO(b/382665591): Ensure that there is at least one pointer down.
+        val pointersDownCount = pointersDown.size.coerceAtLeast(1)
+        val pointerType = pointersDown.entries.firstOrNull()?.value
+        val startedPosition = checkNotNull(lastFirstDown)
+        nestedScrollController =
+            NestedScrollController(
+                overscrollEffect,
+                draggable.onDragStarted(startedPosition, sign, pointersDownCount, pointerType),
+            )
+    }
+
     private fun scrollWithOverscroll(controller: NestedScrollController, offset: Offset): Offset {
-        return scrollWithOverscroll(offset) {
-            controller.controller.onDrag(it.toFloat()).toOffset()
+        if (shouldIgnoreDrag(controller.controller)) return offset
+
+        return scrollWithOverscroll(offset) { delta ->
+            val available = delta.toFloat()
+            val consumed = controller.controller.onDrag(available)
+            if (controller.controller.autoStopNestedDrags && consumed != available) {
+                controller.ensureOnDragStoppedIsCalled()
+                this.nestedScrollController = null
+            }
+
+            consumed.toOffset()
         }
     }
 
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt
index 2530a4f..54232e7 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/gesture/NestedScrollController.kt
@@ -134,6 +134,7 @@
     private var bounds: NestedScrollableBound,
 ) : DelegatingNode(), NestedScrollConnection {
     private var childrenConsumedAnyScroll = false
+    private var availableOnPreScroll = Offset.Zero
 
     init {
         delegate(nestedScrollModifierNode(this, dispatcher = null))
@@ -153,12 +154,21 @@
         this.bounds = bounds
     }
 
+    override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
+        availableOnPreScroll = available
+        return Offset.Zero
+    }
+
     override fun onPostScroll(
         consumed: Offset,
         available: Offset,
         source: NestedScrollSource,
     ): Offset {
-        if (hasConsumedScrollInBounds(consumed.x) || hasConsumedScrollInBounds(consumed.y)) {
+        val consumedIncludingPreScroll = availableOnPreScroll - available
+        if (
+            hasConsumedScrollInBounds(consumedIncludingPreScroll.x) ||
+                hasConsumedScrollInBounds(consumedIncludingPreScroll.y)
+        ) {
             childrenConsumedAnyScroll = true
         }
 
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/modifiers/AnimatedBackground.kt b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/AnimatedBackground.kt
new file mode 100644
index 0000000..5b1f0a7
--- /dev/null
+++ b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/AnimatedBackground.kt
@@ -0,0 +1,159 @@
+/*
+ * 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.compose.modifiers
+
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Size
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Outline
+import androidx.compose.ui.graphics.RectangleShape
+import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.drawOutline
+import androidx.compose.ui.graphics.drawscope.ContentDrawScope
+import androidx.compose.ui.node.DrawModifierNode
+import androidx.compose.ui.node.ModifierNodeElement
+import androidx.compose.ui.node.ObserverModifierNode
+import androidx.compose.ui.node.invalidateDraw
+import androidx.compose.ui.node.observeReads
+import androidx.compose.ui.platform.InspectorInfo
+import androidx.compose.ui.platform.debugInspectorInfo
+import androidx.compose.ui.unit.LayoutDirection
+
+/**
+ * Draws a background in a given [shape] and with a [color] or [alpha] that can be animated.
+ *
+ * @param color color to paint background with
+ * @param alpha alpha of the background
+ * @param shape desired shape of the background
+ */
+fun Modifier.animatedBackground(
+    color: () -> Color,
+    alpha: () -> Float = DefaultAlpha,
+    shape: Shape = RectangleShape,
+) =
+    this.then(
+        BackgroundElement(
+            color = color,
+            alpha = alpha,
+            shape = shape,
+            inspectorInfo =
+                debugInspectorInfo {
+                    name = "background"
+                    value = color
+                    properties["color"] = color
+                    properties["alpha"] = alpha
+                    properties["shape"] = shape
+                },
+        )
+    )
+
+private val DefaultAlpha = { 1f }
+
+private class BackgroundElement(
+    private val color: () -> Color,
+    private val alpha: () -> Float,
+    private val shape: Shape,
+    private val inspectorInfo: InspectorInfo.() -> Unit,
+) : ModifierNodeElement<BackgroundNode>() {
+    override fun create(): BackgroundNode {
+        return BackgroundNode(color, alpha, shape)
+    }
+
+    override fun update(node: BackgroundNode) {
+        node.color = color
+        node.alpha = alpha
+        node.shape = shape
+    }
+
+    override fun InspectorInfo.inspectableProperties() {
+        inspectorInfo()
+    }
+
+    override fun hashCode(): Int {
+        var result = color.hashCode()
+        result = 31 * result + alpha.hashCode()
+        result = 31 * result + shape.hashCode()
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        val otherModifier = other as? BackgroundElement ?: return false
+        return color == otherModifier.color &&
+            alpha == otherModifier.alpha &&
+            shape == otherModifier.shape
+    }
+}
+
+private class BackgroundNode(var color: () -> Color, var alpha: () -> Float, var shape: Shape) :
+    DrawModifierNode, Modifier.Node(), ObserverModifierNode {
+
+    // Naively cache outline calculation if input parameters are the same, we manually observe
+    // reads inside shape#createOutline separately
+    private var lastSize: Size = Size.Unspecified
+    private var lastLayoutDirection: LayoutDirection? = null
+    private var lastOutline: Outline? = null
+    private var lastShape: Shape? = null
+    private var tmpOutline: Outline? = null
+
+    override fun ContentDrawScope.draw() {
+        if (shape === RectangleShape) {
+            // shortcut to avoid Outline calculation and allocation
+            drawRect()
+        } else {
+            drawOutline()
+        }
+        drawContent()
+    }
+
+    override fun onObservedReadsChanged() {
+        // Reset cached properties
+        lastSize = Size.Unspecified
+        lastLayoutDirection = null
+        lastOutline = null
+        lastShape = null
+        // Invalidate draw so we build the cache again - this is needed because observeReads within
+        // the draw scope obscures the state reads from the draw scope's observer
+        invalidateDraw()
+    }
+
+    private fun ContentDrawScope.drawRect() {
+        drawRect(color = color(), alpha = alpha())
+    }
+
+    private fun ContentDrawScope.drawOutline() {
+        val outline = getOutline()
+        drawOutline(outline, color = color(), alpha = alpha())
+    }
+
+    private fun ContentDrawScope.getOutline(): Outline {
+        val outline: Outline?
+        if (size == lastSize && layoutDirection == lastLayoutDirection && lastShape == shape) {
+            outline = lastOutline!!
+        } else {
+            // Manually observe reads so we can directly invalidate the outline when it changes
+            // Use tmpOutline to avoid creating an object reference to local var outline
+            observeReads { tmpOutline = shape.createOutline(size, layoutDirection, this) }
+            outline = tmpOutline
+            tmpOutline = null
+        }
+        lastOutline = outline
+        lastSize = size
+        lastLayoutDirection = layoutDirection
+        lastShape = shape
+        return outline!!
+    }
+}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/modifiers/FadingBackground.kt b/packages/SystemUI/compose/core/src/com/android/compose/modifiers/FadingBackground.kt
deleted file mode 100644
index 794b7a4..0000000
--- a/packages/SystemUI/compose/core/src/com/android/compose/modifiers/FadingBackground.kt
+++ /dev/null
@@ -1,113 +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.compose.modifiers
-
-import androidx.compose.ui.Modifier
-import androidx.compose.ui.draw.DrawModifier
-import androidx.compose.ui.geometry.Size
-import androidx.compose.ui.graphics.Brush
-import androidx.compose.ui.graphics.Color
-import androidx.compose.ui.graphics.Outline
-import androidx.compose.ui.graphics.RectangleShape
-import androidx.compose.ui.graphics.Shape
-import androidx.compose.ui.graphics.SolidColor
-import androidx.compose.ui.graphics.drawOutline
-import androidx.compose.ui.graphics.drawscope.ContentDrawScope
-import androidx.compose.ui.platform.InspectorInfo
-import androidx.compose.ui.platform.InspectorValueInfo
-import androidx.compose.ui.platform.debugInspectorInfo
-import androidx.compose.ui.unit.LayoutDirection
-
-/**
- * Draws a fading [shape] with a solid [color] and [alpha] behind the content.
- *
- * @param color color to paint background with
- * @param alpha alpha of the background
- * @param shape desired shape of the background
- */
-fun Modifier.fadingBackground(color: Color, alpha: () -> Float, shape: Shape = RectangleShape) =
-    this.then(
-        FadingBackground(
-            brush = SolidColor(color),
-            alpha = alpha,
-            shape = shape,
-            inspectorInfo =
-                debugInspectorInfo {
-                    name = "background"
-                    value = color
-                    properties["color"] = color
-                    properties["alpha"] = alpha
-                    properties["shape"] = shape
-                },
-        )
-    )
-
-private class FadingBackground
-constructor(
-    private val brush: Brush,
-    private val shape: Shape,
-    private val alpha: () -> Float,
-    inspectorInfo: InspectorInfo.() -> Unit,
-) : DrawModifier, InspectorValueInfo(inspectorInfo) {
-    // naive cache outline calculation if size is the same
-    private var lastSize: Size? = null
-    private var lastLayoutDirection: LayoutDirection? = null
-    private var lastOutline: Outline? = null
-
-    override fun ContentDrawScope.draw() {
-        if (shape === RectangleShape) {
-            // shortcut to avoid Outline calculation and allocation
-            drawRect()
-        } else {
-            drawOutline()
-        }
-        drawContent()
-    }
-
-    private fun ContentDrawScope.drawRect() {
-        drawRect(brush, alpha = alpha())
-    }
-
-    private fun ContentDrawScope.drawOutline() {
-        val outline =
-            if (size == lastSize && layoutDirection == lastLayoutDirection) {
-                lastOutline!!
-            } else {
-                shape.createOutline(size, layoutDirection, this)
-            }
-        drawOutline(outline, brush = brush, alpha = alpha())
-        lastOutline = outline
-        lastSize = size
-        lastLayoutDirection = layoutDirection
-    }
-
-    override fun hashCode(): Int {
-        var result = brush.hashCode()
-        result = 31 * result + alpha.hashCode()
-        result = 31 * result + shape.hashCode()
-        return result
-    }
-
-    override fun equals(other: Any?): Boolean {
-        val otherModifier = other as? FadingBackground ?: return false
-        return brush == otherModifier.brush &&
-            alpha == otherModifier.alpha &&
-            shape == otherModifier.shape
-    }
-
-    override fun toString(): String = "FadingBackground(brush=$brush, alpha = $alpha, shape=$shape)"
-}
diff --git a/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt b/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
index 84370ed..6fb3679 100644
--- a/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
+++ b/packages/SystemUI/compose/core/src/com/android/compose/theme/PlatformTheme.kt
@@ -43,7 +43,7 @@
     val context = LocalContext.current
 
     val colorScheme = remember(context, isDarkTheme) { platformColorScheme(isDarkTheme, context) }
-    val androidColorScheme = remember(context) { AndroidColorScheme(context) }
+    val androidColorScheme = remember(context, isDarkTheme) { AndroidColorScheme(context) }
     val typefaceNames = remember(context) { TypefaceNames.get(context) }
     val typefaceTokens = remember(typefaceNames) { TypefaceTokens(typefaceNames) }
     val typography =
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
index d8e46ad..b316173 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedDraggableTest.kt
@@ -971,6 +971,98 @@
         assertThat(availableToEffectPostFling).isWithin(1f).of(100f)
     }
 
+    @Test
+    fun isReadyToDrag() {
+        var isReadyToDrag by mutableStateOf(false)
+        val draggable = TestDraggable(isReadyToDrag = { isReadyToDrag })
+        val touchSlop =
+            rule.setContentWithTouchSlop {
+                Box(Modifier.fillMaxSize().nestedDraggable(draggable, orientation))
+            }
+
+        rule.onRoot().performTouchInput {
+            down(center)
+            moveBy((touchSlop + 10f).toOffset())
+        }
+
+        assertThat(draggable.onDragStartedCalled).isTrue()
+        assertThat(draggable.onDragDelta).isEqualTo(0f)
+
+        rule.onRoot().performTouchInput { moveBy(20f.toOffset()) }
+        assertThat(draggable.onDragDelta).isEqualTo(0f)
+
+        // Flag as ready to drag. We still ignore the next drag after that.
+        isReadyToDrag = true
+        rule.onRoot().performTouchInput { moveBy(30f.toOffset()) }
+        assertThat(draggable.onDragDelta).isEqualTo(0f)
+
+        // Now we drag.
+        rule.onRoot().performTouchInput { moveBy(40f.toOffset()) }
+        assertThat(draggable.onDragDelta).isEqualTo(40f)
+    }
+
+    @Test
+    fun consumeNestedPreScroll() {
+        var consumeNestedPreScroll by mutableStateOf(false)
+        val draggable = TestDraggable(shouldConsumeNestedPreScroll = { consumeNestedPreScroll })
+
+        val touchSlop =
+            rule.setContentWithTouchSlop {
+                Box(
+                    Modifier.fillMaxSize()
+                        .nestedDraggable(draggable, orientation)
+                        // Always consume everything so that the only way to start the drag is to
+                        // intercept preScroll events.
+                        .scrollable(rememberScrollableState { it }, orientation)
+                )
+            }
+
+        rule.onRoot().performTouchInput {
+            down(center)
+            moveBy((touchSlop + 1f).toOffset())
+        }
+
+        assertThat(draggable.onDragStartedCalled).isFalse()
+
+        consumeNestedPreScroll = true
+        rule.onRoot().performTouchInput { moveBy(1f.toOffset()) }
+
+        assertThat(draggable.onDragStartedCalled).isTrue()
+    }
+
+    @Test
+    fun autoStopNestedDrags() {
+        var consumeScrolls by mutableStateOf(true)
+        val draggable =
+            TestDraggable(autoStopNestedDrags = true, onDrag = { if (consumeScrolls) it else 0f })
+
+        val touchSlop =
+            rule.setContentWithTouchSlop {
+                Box(
+                    Modifier.fillMaxSize()
+                        .nestedDraggable(draggable, orientation)
+                        .scrollable(rememberScrollableState { 0f }, orientation)
+                )
+            }
+
+        rule.onRoot().performTouchInput {
+            down(center)
+            moveBy((touchSlop + 1f).toOffset())
+        }
+
+        assertThat(draggable.onDragStartedCalled).isTrue()
+        assertThat(draggable.onDragStoppedCalled).isFalse()
+
+        rule.onRoot().performTouchInput { moveBy(50f.toOffset()) }
+
+        assertThat(draggable.onDragStoppedCalled).isFalse()
+
+        consumeScrolls = false
+        rule.onRoot().performTouchInput { moveBy(1f.toOffset()) }
+
+        assertThat(draggable.onDragStoppedCalled).isTrue()
+    }
+
     private fun ComposeContentTestRule.setContentWithTouchSlop(
         content: @Composable () -> Unit
     ): Float {
@@ -996,7 +1088,10 @@
             { velocity, _ ->
                 velocity
             },
-        private val shouldConsumeNestedScroll: (Float) -> Boolean = { true },
+        private val shouldConsumeNestedPostScroll: (Float) -> Boolean = { true },
+        private val shouldConsumeNestedPreScroll: (Float) -> Boolean = { false },
+        private val isReadyToDrag: () -> Boolean = { true },
+        private val autoStopNestedDrags: Boolean = false,
     ) : NestedDraggable {
         var shouldStartDrag = true
         var onDragStartedCalled = false
@@ -1026,6 +1121,11 @@
 
             onDragStarted.invoke(position, sign)
             return object : NestedDraggable.Controller {
+                override val autoStopNestedDrags: Boolean = this@TestDraggable.autoStopNestedDrags
+
+                override val isReadyToDrag: Boolean
+                    get() = isReadyToDrag()
+
                 override fun onDrag(delta: Float): Float {
                     onDragCalled = true
                     onDragDelta += delta
@@ -1042,8 +1142,12 @@
             }
         }
 
-        override fun shouldConsumeNestedScroll(sign: Float): Boolean {
-            return shouldConsumeNestedScroll.invoke(sign)
+        override fun shouldConsumeNestedPostScroll(sign: Float): Boolean {
+            return shouldConsumeNestedPostScroll.invoke(sign)
+        }
+
+        override fun shouldConsumeNestedPreScroll(sign: Float): Boolean {
+            return shouldConsumeNestedPreScroll.invoke(sign)
         }
     }
 }
diff --git a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt
index 424af33..377cbe2 100644
--- a/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt
+++ b/packages/SystemUI/compose/core/tests/src/com/android/compose/gesture/NestedScrollControllerTest.kt
@@ -23,9 +23,13 @@
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
+import androidx.compose.ui.input.nestedscroll.NestedScrollSource
+import androidx.compose.ui.input.nestedscroll.nestedScroll
 import androidx.compose.ui.test.junit4.createComposeRule
 import androidx.compose.ui.test.onRoot
 import androidx.compose.ui.test.performTouchInput
@@ -103,4 +107,35 @@
         rule.waitForIdle()
         assertThat(state.isOuterScrollAllowed).isTrue()
     }
+
+    @Test
+    fun supportsPreScrolls() {
+        val state = NestedScrollControlState()
+        rule.setContent {
+            Box(
+                Modifier.fillMaxSize()
+                    .nestedScrollController(state)
+                    .nestedScroll(
+                        remember {
+                            object : NestedScrollConnection {
+                                override fun onPreScroll(
+                                    available: Offset,
+                                    source: NestedScrollSource,
+                                ): Offset = available
+                            }
+                        }
+                    )
+                    .scrollable(rememberScrollableState { 0f }, Orientation.Vertical)
+            )
+        }
+
+        rule.onRoot().performTouchInput {
+            down(topLeft)
+            moveBy(Offset(0f, bottom))
+        }
+        assertThat(state.isOuterScrollAllowed).isFalse()
+
+        rule.onRoot().performTouchInput { up() }
+        assertThat(state.isOuterScrollAllowed).isTrue()
+    }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
index 3150e94..2b8fe39 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContainer.kt
@@ -47,6 +47,7 @@
 import com.android.compose.animation.scene.rememberMutableSceneTransitionLayoutState
 import com.android.compose.animation.scene.transitions
 import com.android.compose.modifiers.thenIf
+import com.android.systemui.Flags
 import com.android.systemui.communal.shared.model.CommunalBackgroundType
 import com.android.systemui.communal.shared.model.CommunalScenes
 import com.android.systemui.communal.shared.model.CommunalTransitionKeys
@@ -104,7 +105,9 @@
             fade(Communal.Elements.Grid)
             fade(Communal.Elements.IndicationArea)
             fade(Communal.Elements.LockIcon)
-            fade(Communal.Elements.StatusBar)
+            if (!Flags.glanceableHubV2()) {
+                fade(Communal.Elements.StatusBar)
+            }
         }
         timestampRange(startMillis = 167, endMillis = 334) { fade(Communal.Elements.Scrim) }
     }
@@ -131,7 +134,9 @@
             fade(Communal.Elements.Grid)
             fade(Communal.Elements.IndicationArea)
             fade(Communal.Elements.LockIcon)
-            fade(Communal.Elements.StatusBar)
+            if (!Flags.glanceableHubV2()) {
+                fade(Communal.Elements.StatusBar)
+            }
         }
         timestampRange(startMillis = 167, endMillis = 334) { fade(Communal.Elements.Scrim) }
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
index 2d03e2b..0181928 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalContent.kt
@@ -29,6 +29,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.zIndex
 import com.android.compose.animation.scene.ContentScope
+import com.android.systemui.Flags
 import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
 import com.android.systemui.communal.smartspace.SmartspaceInteractionHandler
 import com.android.systemui.communal.ui.compose.section.AmbientStatusBarSection
@@ -70,8 +71,10 @@
                 content = {
                     Box(modifier = Modifier.fillMaxSize()) {
                         with(communalPopupSection) { Popup() }
-                        with(ambientStatusBarSection) {
-                            AmbientStatusBar(modifier = Modifier.fillMaxWidth().zIndex(1f))
+                        if (!Flags.glanceableHubV2()) {
+                            with(ambientStatusBarSection) {
+                                AmbientStatusBar(modifier = Modifier.fillMaxWidth().zIndex(1f))
+                            }
                         }
                         CommunalHub(
                             viewModel = viewModel,
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
index 216f0a7..336f9e1 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/qs/footer/ui/compose/FooterActions.kt
@@ -38,6 +38,7 @@
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.foundation.shape.CornerSize
 import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
 import androidx.compose.material3.Icon
 import androidx.compose.material3.LocalContentColor
 import androidx.compose.material3.MaterialTheme
@@ -73,7 +74,7 @@
 import androidx.lifecycle.repeatOnLifecycle
 import com.android.compose.animation.Expandable
 import com.android.compose.animation.scene.ContentScope
-import com.android.compose.modifiers.fadingBackground
+import com.android.compose.modifiers.animatedBackground
 import com.android.compose.theme.colorAttr
 import com.android.systemui.Flags.notificationShadeBlur
 import com.android.systemui.animation.Expandable
@@ -81,6 +82,7 @@
 import com.android.systemui.common.ui.compose.Icon
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.qs.flags.QSComposeFragment
+import com.android.systemui.qs.flags.QsInCompose
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsButtonViewModel
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsForegroundServicesButtonViewModel
 import com.android.systemui.qs.footer.ui.viewmodel.FooterActionsSecurityButtonViewModel
@@ -172,8 +174,8 @@
     val backgroundTopRadius = dimensionResource(R.dimen.qs_corner_radius)
     val backgroundModifier =
         remember(backgroundColor, backgroundAlphaValue, backgroundTopRadius) {
-            Modifier.fadingBackground(
-                backgroundColor,
+            Modifier.animatedBackground(
+                { backgroundColor },
                 backgroundAlphaValue,
                 RoundedCornerShape(topStart = backgroundTopRadius, topEnd = backgroundTopRadius),
             )
@@ -388,6 +390,7 @@
 }
 
 /** A larger button with an icon, some text and an optional dot (to indicate new changes). */
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 private fun TextButton(
     icon: Icon,
@@ -422,10 +425,13 @@
             Text(
                 text,
                 Modifier.weight(1f),
-                style = MaterialTheme.typography.bodyMedium,
-                // TODO(b/242040009): Remove this letter spacing. We should only use the M3 text
-                // styles without modifying them.
-                letterSpacing = 0.01.em,
+                style =
+                    if (QsInCompose.isEnabled) {
+                        MaterialTheme.typography.labelLarge
+                    } else {
+                        MaterialTheme.typography.bodyMedium
+                    },
+                letterSpacing = if (QsInCompose.isEnabled) 0.em else 0.01.em,
                 color = colorAttr(R.attr.onShadeInactiveVariant),
                 maxLines = 1,
                 overflow = TextOverflow.Ellipsis,
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 7015f79..0daef46 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
@@ -101,7 +101,7 @@
         rememberActivated(traceName = "sceneJankMonitor") { sceneJankMonitorFactory.create() }
 
     val hapticFeedback = LocalHapticFeedback.current
-    val shadeExpansionMotion = OverlayShade.rememberShadeExpansionMotion()
+    val shadeExpansionMotion = OverlayShade.rememberShadeExpansionMotion(isFullWidthShade())
     val sceneTransitions =
         remember(hapticFeedback, shadeExpansionMotion) {
             transitionsBuilder.build(
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
index 9b45ef6..2f5a030 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitions.kt
@@ -6,7 +6,7 @@
 import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
 import com.android.compose.animation.scene.transitions
 import com.android.internal.jank.Cuj
-import com.android.mechanics.behavior.EdgeContainerExpansionSpec
+import com.android.mechanics.behavior.VerticalExpandContainerSpec
 import com.android.systemui.notifications.ui.composable.Notifications
 import com.android.systemui.scene.shared.model.Overlays
 import com.android.systemui.scene.shared.model.Scenes
@@ -50,7 +50,7 @@
  */
 class SceneContainerTransitions : SceneContainerTransitionsBuilder {
     override fun build(
-        shadeExpansionMotion: EdgeContainerExpansionSpec,
+        shadeExpansionMotion: VerticalExpandContainerSpec,
         revealHaptics: ContainerRevealHaptics,
     ): SceneTransitions {
         return transitions {
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt
index eb5548d..4c9c23a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/SceneContainerTransitionsBuilder.kt
@@ -19,7 +19,7 @@
 import com.android.compose.animation.scene.SceneTransitions
 import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
 import com.android.compose.animation.scene.transitions
-import com.android.mechanics.behavior.EdgeContainerExpansionSpec
+import com.android.mechanics.behavior.VerticalExpandContainerSpec
 
 /**
  * Builder of the comprehensive definition of all transitions between scenes and overlays in the
@@ -29,7 +29,7 @@
 
     /** Build the [SceneContainer] transitions spec. */
     fun build(
-        shadeExpansionMotion: EdgeContainerExpansionSpec,
+        shadeExpansionMotion: VerticalExpandContainerSpec,
         revealHaptics: ContainerRevealHaptics,
     ): SceneTransitions
 }
@@ -42,7 +42,7 @@
     private val transitions: SceneTransitions = transitions { /* No transitions */ }
 ) : SceneContainerTransitionsBuilder {
     override fun build(
-        shadeExpansionMotion: EdgeContainerExpansionSpec,
+        shadeExpansionMotion: VerticalExpandContainerSpec,
         revealHaptics: ContainerRevealHaptics,
     ): SceneTransitions = transitions
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
index 9b4b91e..85aad9b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToNotificationsShadeTransition.kt
@@ -20,7 +20,7 @@
 import com.android.compose.animation.scene.TransitionBuilder
 import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
 import com.android.compose.animation.scene.reveal.verticalContainerReveal
-import com.android.mechanics.behavior.EdgeContainerExpansionSpec
+import com.android.mechanics.behavior.VerticalExpandContainerSpec
 import com.android.systemui.keyguard.ui.composable.blueprint.ClockElementKeys
 import com.android.systemui.notifications.ui.composable.NotificationsShade
 import com.android.systemui.scene.shared.model.Overlays
@@ -29,7 +29,7 @@
 
 fun TransitionBuilder.toNotificationsShadeTransition(
     durationScale: Double = 1.0,
-    shadeExpansionMotion: EdgeContainerExpansionSpec,
+    shadeExpansionMotion: VerticalExpandContainerSpec,
     revealHaptics: ContainerRevealHaptics,
 ) {
     spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
index 47dd85f..8f0447d 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/scene/ui/composable/transitions/ToQuickSettingsShadeTransition.kt
@@ -20,14 +20,14 @@
 import com.android.compose.animation.scene.TransitionBuilder
 import com.android.compose.animation.scene.reveal.ContainerRevealHaptics
 import com.android.compose.animation.scene.reveal.verticalContainerReveal
-import com.android.mechanics.behavior.EdgeContainerExpansionSpec
+import com.android.mechanics.behavior.VerticalExpandContainerSpec
 import com.android.systemui.qs.ui.composable.QuickSettingsShade
 import com.android.systemui.shade.ui.composable.OverlayShade
 import kotlin.time.Duration.Companion.milliseconds
 
 fun TransitionBuilder.toQuickSettingsShadeTransition(
     durationScale: Double = 1.0,
-    shadeExpansionMotion: EdgeContainerExpansionSpec,
+    shadeExpansionMotion: VerticalExpandContainerSpec,
     revealHaptics: ContainerRevealHaptics,
 ) {
     spec = tween(durationMillis = (DefaultDuration * durationScale).inWholeMilliseconds.toInt())
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
index 3446081..068218a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/shade/ui/composable/OverlayShade.kt
@@ -53,8 +53,8 @@
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.LowestZIndexContentPicker
 import com.android.compose.windowsizeclass.LocalWindowSizeClass
-import com.android.mechanics.behavior.EdgeContainerExpansionSpec
-import com.android.mechanics.behavior.edgeContainerExpansionBackground
+import com.android.mechanics.behavior.VerticalExpandContainerSpec
+import com.android.mechanics.behavior.verticalExpandContainerBackground
 import com.android.systemui.res.R
 import com.android.systemui.shade.ui.composable.OverlayShade.rememberShadeExpansionMotion
 
@@ -114,9 +114,9 @@
         modifier =
             modifier
                 .disableSwipesWhenScrolling()
-                .edgeContainerExpansionBackground(
-                    OverlayShade.Colors.PanelBackground,
-                    rememberShadeExpansionMotion(),
+                .verticalExpandContainerBackground(
+                    backgroundColor = OverlayShade.Colors.PanelBackground,
+                    spec = rememberShadeExpansionMotion(isFullWidthShade()),
                 )
     ) {
         Column {
@@ -202,8 +202,10 @@
     }
 
     @Composable
-    fun rememberShadeExpansionMotion(): EdgeContainerExpansionSpec {
+    fun rememberShadeExpansionMotion(isFullWidth: Boolean): VerticalExpandContainerSpec {
         val radius = Dimensions.PanelCornerRadius
-        return remember(radius) { EdgeContainerExpansionSpec(radius = radius) }
+        return remember(radius, isFullWidth) {
+            VerticalExpandContainerSpec(isFloating = !isFullWidth, radius = radius)
+        }
     }
 }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
index d9e8f02..52b1e3a 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/ColumnVolumeSliders.kt
@@ -30,9 +30,11 @@
 import androidx.compose.animation.shrinkVertically
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.RowScope
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.IconButtonDefaults
@@ -42,7 +44,6 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.res.painterResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.semantics.Role
@@ -154,9 +155,7 @@
                                                 totalCount = viewModels.size,
                                             ),
                                     )
-                                    .thenIf(!Flags.volumeRedesign()) {
-                                        Modifier.padding(top = 16.dp)
-                                    },
+                                    .padding(top = if (Flags.volumeRedesign()) 4.dp else 16.dp),
                             state = sliderState,
                             onValueChange = { newValue: Float ->
                                 sliderViewModel.onValueChanged(sliderState, newValue)
@@ -223,7 +222,7 @@
 }
 
 @Composable
-private fun ExpandButton(
+private fun RowScope.ExpandButton(
     isExpanded: Boolean,
     isExpandable: Boolean,
     onExpandedChanged: (Boolean) -> Unit,
@@ -243,16 +242,17 @@
     ) {
         PlatformIconButton(
             modifier =
-                Modifier.size(width = 48.dp, height = 40.dp).semantics {
+                Modifier.size(40.dp).semantics {
                     role = Role.Switch
                     stateDescription = expandButtonStateDescription
                 },
             onClick = { onExpandedChanged(!isExpanded) },
             colors =
                 IconButtonDefaults.iconButtonColors(
-                    containerColor = Color.Transparent,
-                    contentColor = MaterialTheme.colorScheme.onSurfaceVariant,
+                    containerColor = MaterialTheme.colorScheme.surfaceContainerHighest,
+                    contentColor = MaterialTheme.colorScheme.onSurface,
                 ),
+            shape = RoundedCornerShape(12.dp),
             iconResource =
                 if (isExpanded) {
                     R.drawable.ic_arrow_down_24dp
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
index 4b3ebc2..f9492da 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/volume/ui/composable/VolumeSlider.kt
@@ -30,14 +30,16 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.RowScope
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.foundation.layout.fillMaxWidth
-import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
 import androidx.compose.material3.Icon as MaterialIcon
 import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.SliderDefaults
 import androidx.compose.material3.Text
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
@@ -60,28 +62,31 @@
 import androidx.compose.ui.semantics.progressBarRangeInfo
 import androidx.compose.ui.semantics.setProgress
 import androidx.compose.ui.semantics.stateDescription
+import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import com.android.compose.PlatformSlider
 import com.android.compose.PlatformSliderColors
 import com.android.systemui.Flags
-import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.common.shared.model.Icon as IconModel
 import com.android.systemui.common.ui.compose.Icon
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter
 import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
 import com.android.systemui.lifecycle.rememberViewModel
 import com.android.systemui.res.R
+import com.android.systemui.volume.dialog.sliders.ui.compose.SliderTrack
 import com.android.systemui.volume.haptics.ui.VolumeHapticsConfigsProvider
 import com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel.SliderState
-import com.android.systemui.volume.ui.slider.AccessibilityParams
-import com.android.systemui.volume.ui.slider.Haptics
-import com.android.systemui.volume.ui.slider.Slider
+import com.android.systemui.volume.ui.compose.slider.AccessibilityParams
+import com.android.systemui.volume.ui.compose.slider.Haptics
+import com.android.systemui.volume.ui.compose.slider.Slider
+import com.android.systemui.volume.ui.compose.slider.SliderIcon
 import kotlin.math.round
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.map
 
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 fun VolumeSlider(
     state: SliderState,
@@ -91,7 +96,7 @@
     modifier: Modifier = Modifier,
     hapticsViewModelFactory: SliderHapticsViewModel.Factory?,
     onValueChangeFinished: (() -> Unit)? = null,
-    button: (@Composable () -> Unit)? = null,
+    button: (@Composable RowScope.() -> Unit)? = null,
 ) {
     if (!Flags.volumeRedesign()) {
         LegacyVolumeSlider(
@@ -106,52 +111,86 @@
         return
     }
 
-    Column(modifier = modifier.animateContentSize(), verticalArrangement = Arrangement.Top) {
+    Column(modifier = modifier.animateContentSize()) {
+        Text(
+            text = state.label,
+            style = MaterialTheme.typography.titleMedium,
+            color = MaterialTheme.colorScheme.onSurface,
+            modifier = Modifier.fillMaxWidth().clearAndSetSemantics {},
+        )
         Row(
-            horizontalArrangement = Arrangement.spacedBy(12.dp),
-            modifier = Modifier.fillMaxWidth().height(40.dp),
+            horizontalArrangement = Arrangement.spacedBy(8.dp),
+            modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp),
             verticalAlignment = Alignment.CenterVertically,
         ) {
-            state.icon?.let {
-                Icon(
-                    icon = it,
-                    tint = MaterialTheme.colorScheme.onSurface,
-                    modifier = Modifier.size(24.dp),
+            val materialSliderColors =
+                SliderDefaults.colors(
+                    activeTickColor = MaterialTheme.colorScheme.surfaceContainerHigh,
+                    inactiveTrackColor = MaterialTheme.colorScheme.surfaceContainerHigh,
                 )
-            }
-            Text(
-                text = state.label,
-                style = MaterialTheme.typography.titleMedium,
-                color = MaterialTheme.colorScheme.onSurface,
-                modifier = Modifier.weight(1f),
-            )
-            button?.invoke()
-        }
-
-        Slider(
-            value = state.value,
-            valueRange = state.valueRange,
-            onValueChanged = onValueChange,
-            onValueChangeFinished = { onValueChangeFinished?.invoke() },
-            isEnabled = state.isEnabled,
-            stepDistance = state.a11yStep,
-            accessibilityParams =
-                AccessibilityParams(
-                    label = state.label,
-                    disabledMessage = state.disabledMessage,
-                    currentStateDescription = state.a11yStateDescription,
-                ),
-            haptics =
-                hapticsViewModelFactory?.let {
-                    Haptics.Enabled(
-                        hapticsViewModelFactory = it,
-                        hapticFilter = state.hapticFilter,
-                        orientation = Orientation.Horizontal,
+            Slider(
+                value = state.value,
+                valueRange = state.valueRange,
+                onValueChanged = onValueChange,
+                onValueChangeFinished = { onValueChangeFinished?.invoke() },
+                colors = materialSliderColors,
+                isEnabled = state.isEnabled,
+                stepDistance = state.step,
+                accessibilityParams =
+                    AccessibilityParams(
+                        contentDescription = state.a11yContentDescription,
+                        stateDescription = state.a11yStateDescription,
+                    ),
+                track = { sliderState ->
+                    SliderTrack(
+                        sliderState = sliderState,
+                        colors = materialSliderColors,
+                        isEnabled = state.isEnabled,
+                        activeTrackStartIcon =
+                            state.icon?.let { icon ->
+                                { iconsState ->
+                                    SliderIcon(
+                                        icon = {
+                                            Icon(icon = icon, modifier = Modifier.size(24.dp))
+                                        },
+                                        isVisible = iconsState.isActiveTrackStartIconVisible,
+                                    )
+                                }
+                            },
+                        inactiveTrackStartIcon =
+                            state.icon?.let { icon ->
+                                { iconsState ->
+                                    SliderIcon(
+                                        icon = {
+                                            Icon(icon = icon, modifier = Modifier.size(24.dp))
+                                        },
+                                        isVisible = !iconsState.isActiveTrackStartIconVisible,
+                                    )
+                                }
+                            },
                     )
-                } ?: Haptics.Disabled,
-            modifier =
-                Modifier.height(40.dp).padding(top = 4.dp, bottom = 12.dp).sysuiResTag(state.label),
-        )
+                },
+                thumb = { sliderState, interactionSource ->
+                    SliderDefaults.Thumb(
+                        sliderState = sliderState,
+                        interactionSource = interactionSource,
+                        enabled = state.isEnabled,
+                        colors = materialSliderColors,
+                        thumbSize = DpSize(4.dp, 52.dp),
+                    )
+                },
+                haptics =
+                    hapticsViewModelFactory?.let {
+                        Haptics.Enabled(
+                            hapticsViewModelFactory = it,
+                            hapticFilter = state.hapticFilter,
+                            orientation = Orientation.Horizontal,
+                        )
+                    } ?: Haptics.Disabled,
+                modifier = Modifier.weight(1f).sysuiResTag(state.label),
+            )
+            button?.invoke(this)
+        }
         state.disabledMessage?.let { disabledMessage ->
             AnimatedVisibility(visible = !state.isEnabled) {
                 Row(
@@ -169,7 +208,7 @@
                         text = disabledMessage,
                         color = MaterialTheme.colorScheme.onSurfaceVariant,
                         style = MaterialTheme.typography.labelSmall,
-                        modifier = Modifier.basicMarquee(),
+                        modifier = Modifier.basicMarquee().clearAndSetSemantics {},
                     )
                 }
             }
@@ -229,7 +268,7 @@
                         }
 
                     val newValue =
-                        (value + targetDirection * state.a11yStep).coerceIn(
+                        (value + targetDirection * state.step).coerceIn(
                             state.valueRange.start,
                             state.valueRange.endInclusive,
                         )
@@ -250,7 +289,11 @@
         enabled = state.isEnabled,
         icon = {
             state.icon?.let {
-                SliderIcon(icon = it, onIconTapped = onIconTapped, isTappable = state.isMutable)
+                LegacySliderIcon(
+                    icon = it,
+                    onIconTapped = onIconTapped,
+                    isTappable = state.isMutable,
+                )
             }
         },
         colors = sliderColors,
@@ -286,8 +329,8 @@
 }
 
 @Composable
-private fun SliderIcon(
-    icon: Icon,
+private fun LegacySliderIcon(
+    icon: IconModel,
     onIconTapped: () -> Unit,
     isTappable: Boolean,
     modifier: Modifier = Modifier,
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt
index b04d89d..0b0df06c 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/AnimateContent.kt
@@ -20,6 +20,7 @@
 import androidx.compose.animation.core.AnimationVector1D
 import androidx.compose.animation.core.SpringSpec
 import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
+import androidx.compose.runtime.withFrameNanos
 import com.android.compose.animation.scene.content.state.TransitionState
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
@@ -47,6 +48,11 @@
                 oneOffAnimation.animatable = it
             }
 
+        if (layoutState.deferTransitionProgress) {
+            // Defer the animation by one frame so that the transition progress is changed only when
+            // the expensive first composition frame is done.
+            withFrameNanos {}
+        }
         animatable.animateTo(targetProgress, animationSpec, initialVelocity)
     }
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
index 1360611..36eafa4 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/DraggableHandler.kt
@@ -68,7 +68,7 @@
         return layoutImpl.swipeDetector.detectSwipe(change)
     }
 
-    override fun shouldConsumeNestedScroll(sign: Float): Boolean {
+    override fun shouldConsumeNestedPostScroll(sign: Float): Boolean {
         return this.enabled()
     }
 
@@ -290,6 +290,15 @@
     val isDrivingTransition: Boolean
         get() = layoutState.transitionState == swipeAnimation.contentTransition
 
+    override val isReadyToDrag: Boolean
+        get() {
+            return !layoutState.deferTransitionProgress ||
+                with(draggableHandler.layoutImpl.elementStateScope) {
+                    swipeAnimation.fromContent.targetSize() != null &&
+                        swipeAnimation.toContent.targetSize() != null
+                }
+        }
+
     init {
         check(!isDrivingTransition) { "Multiple controllers with the same SwipeTransition" }
     }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
index 4da83c3..a8b676d 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutImpl.kt
@@ -462,7 +462,9 @@
                 // swipes.
                 .swipeToScene(horizontalDraggableHandler)
                 .swipeToScene(verticalDraggableHandler)
-                .then(LayoutElement(layoutImpl = this))
+                .then(
+                    LayoutElement(layoutImpl = this, transitionState = this.state.transitionState)
+                )
         ) {
             LookaheadScope {
                 if (_lookaheadScope == null) {
@@ -623,23 +625,28 @@
     @VisibleForTesting internal fun overlaysOrNullForTest(): Map<OverlayKey, Overlay>? = _overlays
 }
 
-private data class LayoutElement(private val layoutImpl: SceneTransitionLayoutImpl) :
-    ModifierNodeElement<LayoutNode>() {
-    override fun create(): LayoutNode = LayoutNode(layoutImpl)
+private data class LayoutElement(
+    private val layoutImpl: SceneTransitionLayoutImpl,
+    private val transitionState: TransitionState,
+) : ModifierNodeElement<LayoutNode>() {
+    override fun create(): LayoutNode = LayoutNode(layoutImpl, transitionState)
 
     override fun update(node: LayoutNode) {
         node.layoutImpl = layoutImpl
+        node.transitionState = transitionState
     }
 }
 
-private class LayoutNode(var layoutImpl: SceneTransitionLayoutImpl) :
-    Modifier.Node(), ApproachLayoutModifierNode, LayoutAwareModifierNode {
+private class LayoutNode(
+    var layoutImpl: SceneTransitionLayoutImpl,
+    var transitionState: TransitionState,
+) : Modifier.Node(), ApproachLayoutModifierNode, LayoutAwareModifierNode {
     override fun onRemeasured(size: IntSize) {
         layoutImpl.lastSize = size
     }
 
     override fun isMeasurementApproachInProgress(lookaheadSize: IntSize): Boolean {
-        return layoutImpl.state.isTransitioning()
+        return transitionState is TransitionState.Transition.ChangeScene
     }
 
     @ExperimentalComposeUiApi
@@ -652,8 +659,7 @@
 
         val width: Int
         val height: Int
-        val transition =
-            layoutImpl.state.currentTransition as? TransitionState.Transition.ChangeScene
+        val transition = transitionState as? TransitionState.Transition.ChangeScene
         if (transition == null) {
             width = placeable.width
             height = placeable.height
@@ -662,6 +668,9 @@
             val fromSize = layoutImpl.scene(transition.fromScene).targetSize
             val toSize = layoutImpl.scene(transition.toScene).targetSize
 
+            check(fromSize != Element.SizeUnspecified) { "fromSize is unspecified " }
+            check(toSize != Element.SizeUnspecified) { "toSize is unspecified" }
+
             // Optimization: make sure we don't read state.progress if fromSize ==
             // toSize to avoid running this code every frame when the layout size does
             // not change.
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
index 56e8c45..4e28dd5 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/SceneTransitionLayoutState.kt
@@ -234,6 +234,10 @@
  *   `from` overlay by `to` overlay.
  * @param stateLinks the [StateLink] connecting this [SceneTransitionLayoutState] to other
  *   [SceneTransitionLayoutState]s.
+ * @param deferTransitionProgress whether we should wait for the first composition to be done before
+ *   changing the progress of a transition. This can help reduce perceivable jank at the start of a
+ *   transition in case the first composition of a content takes a lot of time and we are going to
+ *   miss that first frame.
  */
 fun MutableSceneTransitionLayoutState(
     initialScene: SceneKey,
@@ -246,6 +250,9 @@
     canReplaceOverlay: (from: OverlayKey, to: OverlayKey) -> Boolean = { _, _ -> true },
     onTransitionStart: (TransitionState.Transition) -> Unit = {},
     onTransitionEnd: (TransitionState.Transition) -> Unit = {},
+
+    // TODO(b/400688335): Turn on by default and remove this flag before flexiglass is released.
+    deferTransitionProgress: Boolean = false,
 ): MutableSceneTransitionLayoutState {
     return MutableSceneTransitionLayoutStateImpl(
         initialScene,
@@ -258,6 +265,7 @@
         canReplaceOverlay,
         onTransitionStart,
         onTransitionEnd,
+        deferTransitionProgress,
     )
 }
 
@@ -272,6 +280,9 @@
     canReplaceOverlay: (from: OverlayKey, to: OverlayKey) -> Boolean = { _, _ -> true },
     onTransitionStart: (TransitionState.Transition) -> Unit = {},
     onTransitionEnd: (TransitionState.Transition) -> Unit = {},
+
+    // TODO(b/400688335): Turn on by default and remove this flag before flexiglass is released.
+    deferTransitionProgress: Boolean = false,
 ): MutableSceneTransitionLayoutState {
     val motionScheme = MaterialTheme.motionScheme
     val layoutState = remember {
@@ -286,6 +297,7 @@
             canReplaceOverlay = canReplaceOverlay,
             onTransitionStart = onTransitionStart,
             onTransitionEnd = onTransitionEnd,
+            deferTransitionProgress = deferTransitionProgress,
         )
     }
 
@@ -298,6 +310,7 @@
         layoutState.canReplaceOverlay = canReplaceOverlay
         layoutState.onTransitionStart = onTransitionStart
         layoutState.onTransitionEnd = onTransitionEnd
+        layoutState.deferTransitionProgress = deferTransitionProgress
     }
     return layoutState
 }
@@ -317,6 +330,8 @@
     },
     internal var onTransitionStart: (TransitionState.Transition) -> Unit = {},
     internal var onTransitionEnd: (TransitionState.Transition) -> Unit = {},
+    // TODO(b/400688335): Turn on by default and remove this flag before flexiglass is released.
+    internal var deferTransitionProgress: Boolean = false,
 ) : MutableSceneTransitionLayoutState {
     private val creationThread: Thread = Thread.currentThread()
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
index 2d2a8154..5d4232d8 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/UserActionDistanceScopeImpl.kt
@@ -38,7 +38,7 @@
     }
 
     override fun ContentKey.targetSize(): IntSize? {
-        return layoutImpl.content(this).targetSize.takeIf { it != IntSize.Zero }
+        return layoutImpl.content(this).targetSize.takeIf { it != Element.SizeUnspecified }
     }
 }
 
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
index 90bf92a..7492f37 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/content/Content.kt
@@ -93,9 +93,10 @@
     val containerState = ContainerState()
 
     // Important: All fields in this class should be backed by State given that contents are updated
-    // directly during composition, outside of a SideEffect.
+    // directly during composition, outside of a SideEffect, or are observed during composition,
+    // layout or drawing.
     var content by mutableStateOf(content)
-    var targetSize by mutableStateOf(IntSize.Zero)
+    var targetSize by mutableStateOf(Element.SizeUnspecified)
     var userActions by mutableStateOf(actions)
     var zIndex by mutableFloatStateOf(zIndex)
 
@@ -212,9 +213,17 @@
         return if (isElevationPossible) delegate(ContainerNode(content.containerState)) else null
     }
 
+    override fun onDetach() {
+        this.content.targetSize = Element.SizeUnspecified
+    }
+
     fun update(content: Content, isElevationPossible: Boolean, isInvisible: Boolean) {
-        if (content != this.content || isElevationPossible != this.isElevationPossible) {
+        if (content != this.content) {
+            this.content.targetSize = Element.SizeUnspecified
             this.content = content
+        }
+
+        if (content != this.content || isElevationPossible != this.isElevationPossible) {
             this.isElevationPossible = isElevationPossible
 
             containerDelegate?.let { undelegate(it) }
diff --git a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
index 72f9bd5..734de34 100644
--- a/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
+++ b/packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/reveal/ContainerReveal.kt
@@ -29,7 +29,7 @@
 import com.android.compose.animation.scene.transformation.PropertyTransformation
 import com.android.compose.animation.scene.transformation.PropertyTransformationScope
 import com.android.mechanics.MotionValue
-import com.android.mechanics.behavior.EdgeContainerExpansionSpec
+import com.android.mechanics.behavior.VerticalExpandContainerSpec
 import kotlinx.coroutines.CoroutineScope
 
 interface ContainerRevealHaptics {
@@ -53,7 +53,7 @@
 @OptIn(ExperimentalMaterial3ExpressiveApi::class)
 fun TransitionBuilder.verticalContainerReveal(
     container: ElementKey,
-    motionSpec: EdgeContainerExpansionSpec,
+    motionSpec: VerticalExpandContainerSpec,
     haptics: ContainerRevealHaptics,
 ) {
     // Make the swipe distance be exactly the target height of the container.
diff --git a/packages/SystemUI/compose/scene/tests/Android.bp b/packages/SystemUI/compose/scene/tests/Android.bp
index 2ab27af..d63450b 100644
--- a/packages/SystemUI/compose/scene/tests/Android.bp
+++ b/packages/SystemUI/compose/scene/tests/Android.bp
@@ -42,6 +42,7 @@
         "PlatformMotionTestingCompose",
         "androidx.test.runner",
         "androidx.test.ext.junit",
+        "platform-parametric-runner-lib",
 
         "androidx.compose.runtime_runtime",
         "androidx.compose.ui_ui-test-junit4",
diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragFullyClose.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragFullyClose.json
new file mode 100644
index 0000000..770f859
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragFullyClose.json
@@ -0,0 +1,624 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816,
+    832,
+    848,
+    864,
+    880,
+    896,
+    912,
+    928,
+    944
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 8.4,
+          "y": 5.2
+        },
+        {
+          "x": 11.2,
+          "y": 5.2
+        },
+        {
+          "x": 13.6,
+          "y": 5.2
+        },
+        {
+          "x": 15.6,
+          "y": 5.2
+        },
+        {
+          "x": 16.8,
+          "y": 5.2
+        },
+        {
+          "x": 17.6,
+          "y": 5.2
+        },
+        {
+          "x": 18.4,
+          "y": 5.2
+        },
+        {
+          "x": 18.8,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 292.8
+        },
+        {
+          "width": 150,
+          "height": 292.8
+        },
+        {
+          "width": 150,
+          "height": 286
+        },
+        {
+          "width": 150,
+          "height": 279.6
+        },
+        {
+          "width": 150,
+          "height": 273.2
+        },
+        {
+          "width": 150,
+          "height": 266.8
+        },
+        {
+          "width": 150,
+          "height": 260.4
+        },
+        {
+          "width": 150,
+          "height": 254
+        },
+        {
+          "width": 150,
+          "height": 247.6
+        },
+        {
+          "width": 150,
+          "height": 241.2
+        },
+        {
+          "width": 150,
+          "height": 241.2
+        },
+        {
+          "width": 150,
+          "height": 234.4
+        },
+        {
+          "width": 150,
+          "height": 228
+        },
+        {
+          "width": 150,
+          "height": 221.6
+        },
+        {
+          "width": 150,
+          "height": 215.2
+        },
+        {
+          "width": 150,
+          "height": 208.8
+        },
+        {
+          "width": 150,
+          "height": 202
+        },
+        {
+          "width": 150,
+          "height": 195.6
+        },
+        {
+          "width": 150,
+          "height": 189.2
+        },
+        {
+          "width": 150,
+          "height": 189.2
+        },
+        {
+          "width": 150,
+          "height": 182.8
+        },
+        {
+          "width": 150,
+          "height": 176.4
+        },
+        {
+          "width": 150,
+          "height": 170
+        },
+        {
+          "width": 150,
+          "height": 163.6
+        },
+        {
+          "width": 150,
+          "height": 157.2
+        },
+        {
+          "width": 150,
+          "height": 150.8
+        },
+        {
+          "width": 150,
+          "height": 144.4
+        },
+        {
+          "width": 150,
+          "height": 137.6
+        },
+        {
+          "width": 150,
+          "height": 137.6
+        },
+        {
+          "width": 150,
+          "height": 131.2
+        },
+        {
+          "width": 150,
+          "height": 124.8
+        },
+        {
+          "width": 150,
+          "height": 118.4
+        },
+        {
+          "width": 150,
+          "height": 112
+        },
+        {
+          "width": 150,
+          "height": 112
+        },
+        {
+          "width": 150,
+          "height": 99.2
+        },
+        {
+          "width": 150,
+          "height": 81.2
+        },
+        {
+          "width": 144,
+          "height": 62.8
+        },
+        {
+          "width": 138,
+          "height": 46.4
+        },
+        {
+          "width": 133.2,
+          "height": 32
+        },
+        {
+          "width": 129.6,
+          "height": 20.4
+        },
+        {
+          "width": 127.2,
+          "height": 12
+        },
+        {
+          "width": 125.2,
+          "height": 6.4
+        },
+        {
+          "width": 124,
+          "height": 2.8
+        },
+        {
+          "width": 123.2,
+          "height": 0.4
+        },
+        {
+          "width": 122.4,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.99781144,
+        0.87040234,
+        0.6695792,
+        0.48078007,
+        0.33033127,
+        0.22004372,
+        0.1432175,
+        0.09153092,
+        0.057634592,
+        0.035840213,
+        0.022048414,
+        0.013435662,
+        0.008117795,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragHalfClose.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragHalfClose.json
new file mode 100644
index 0000000..6b7de56
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragHalfClose.json
@@ -0,0 +1,644 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816,
+    832,
+    848,
+    864,
+    880,
+    896,
+    912,
+    928,
+    944,
+    960,
+    976
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 6.8,
+          "y": 5.2
+        },
+        {
+          "x": 10.4,
+          "y": 5.2
+        },
+        {
+          "x": 13.2,
+          "y": 5.2
+        },
+        {
+          "x": 15.2,
+          "y": 5.2
+        },
+        {
+          "x": 16.8,
+          "y": 5.2
+        },
+        {
+          "x": 17.6,
+          "y": 5.2
+        },
+        {
+          "x": 18.4,
+          "y": 5.2
+        },
+        {
+          "x": 18.8,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 297.6
+        },
+        {
+          "width": 150,
+          "height": 292.4
+        },
+        {
+          "width": 150,
+          "height": 287.6
+        },
+        {
+          "width": 150,
+          "height": 282.8
+        },
+        {
+          "width": 150,
+          "height": 278
+        },
+        {
+          "width": 150,
+          "height": 273.2
+        },
+        {
+          "width": 150,
+          "height": 268.4
+        },
+        {
+          "width": 150,
+          "height": 263.6
+        },
+        {
+          "width": 150,
+          "height": 258.8
+        },
+        {
+          "width": 150,
+          "height": 258.8
+        },
+        {
+          "width": 150,
+          "height": 253.6
+        },
+        {
+          "width": 150,
+          "height": 248.8
+        },
+        {
+          "width": 150,
+          "height": 244
+        },
+        {
+          "width": 150,
+          "height": 239.2
+        },
+        {
+          "width": 150,
+          "height": 234.4
+        },
+        {
+          "width": 150,
+          "height": 229.6
+        },
+        {
+          "width": 150,
+          "height": 224.8
+        },
+        {
+          "width": 150,
+          "height": 220
+        },
+        {
+          "width": 150,
+          "height": 220
+        },
+        {
+          "width": 150,
+          "height": 214.8
+        },
+        {
+          "width": 150,
+          "height": 210
+        },
+        {
+          "width": 150,
+          "height": 205.2
+        },
+        {
+          "width": 150,
+          "height": 200.4
+        },
+        {
+          "width": 150,
+          "height": 195.6
+        },
+        {
+          "width": 150,
+          "height": 190.8
+        },
+        {
+          "width": 150,
+          "height": 186
+        },
+        {
+          "width": 150,
+          "height": 181.2
+        },
+        {
+          "width": 150,
+          "height": 181.2
+        },
+        {
+          "width": 150,
+          "height": 176.4
+        },
+        {
+          "width": 150,
+          "height": 171.6
+        },
+        {
+          "width": 150,
+          "height": 166.8
+        },
+        {
+          "width": 150,
+          "height": 161.6
+        },
+        {
+          "width": 150,
+          "height": 161.6
+        },
+        {
+          "width": 150,
+          "height": 147.2
+        },
+        {
+          "width": 150,
+          "height": 122
+        },
+        {
+          "width": 150,
+          "height": 95.2
+        },
+        {
+          "width": 146.8,
+          "height": 70.8
+        },
+        {
+          "width": 139.6,
+          "height": 50.8
+        },
+        {
+          "width": 134,
+          "height": 34
+        },
+        {
+          "width": 130,
+          "height": 19.2
+        },
+        {
+          "width": 127.2,
+          "height": 9.2
+        },
+        {
+          "width": 125.2,
+          "height": 2.8
+        },
+        {
+          "width": 123.6,
+          "height": 0
+        },
+        {
+          "width": 122.8,
+          "height": 0
+        },
+        {
+          "width": 122.4,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.99979615,
+        0.8860379,
+        0.6869267,
+        0.4955439,
+        0.34154767,
+        0.22803628,
+        0.14868057,
+        0.09515619,
+        0.059987247,
+        0.037340224,
+        0.02299112,
+        0.01402092,
+        0.008477271,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragOpen.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragOpen.json
new file mode 100644
index 0000000..13f75d2
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_dragOpen.json
@@ -0,0 +1,544 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "x": 18,
+          "y": 5.2
+        },
+        {
+          "x": 18,
+          "y": 5.2
+        },
+        {
+          "x": 16.8,
+          "y": 5.2
+        },
+        {
+          "x": 16,
+          "y": 5.2
+        },
+        {
+          "x": 14.8,
+          "y": 5.2
+        },
+        {
+          "x": 13.6,
+          "y": 5.2
+        },
+        {
+          "x": 12.4,
+          "y": 5.2
+        },
+        {
+          "x": 11.2,
+          "y": 5.2
+        },
+        {
+          "x": 10.4,
+          "y": 5.2
+        },
+        {
+          "x": 9.2,
+          "y": 5.2
+        },
+        {
+          "x": 9.2,
+          "y": 5.2
+        },
+        {
+          "x": 8,
+          "y": 5.2
+        },
+        {
+          "x": 6.8,
+          "y": 5.2
+        },
+        {
+          "x": 5.6,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "width": 124.4,
+          "height": 1.6
+        },
+        {
+          "width": 124.4,
+          "height": 1.6
+        },
+        {
+          "width": 126.8,
+          "height": 3.2
+        },
+        {
+          "width": 128.8,
+          "height": 4.8
+        },
+        {
+          "width": 131.2,
+          "height": 6.4
+        },
+        {
+          "width": 133.6,
+          "height": 8
+        },
+        {
+          "width": 135.6,
+          "height": 9.6
+        },
+        {
+          "width": 138,
+          "height": 11.2
+        },
+        {
+          "width": 140,
+          "height": 12.8
+        },
+        {
+          "width": 142.4,
+          "height": 14.4
+        },
+        {
+          "width": 142.4,
+          "height": 14.4
+        },
+        {
+          "width": 144.8,
+          "height": 16.4
+        },
+        {
+          "width": 147.2,
+          "height": 18
+        },
+        {
+          "width": 149.2,
+          "height": 19.6
+        },
+        {
+          "width": 150,
+          "height": 25.6
+        },
+        {
+          "width": 150,
+          "height": 36.4
+        },
+        {
+          "width": 150,
+          "height": 45.6
+        },
+        {
+          "width": 150,
+          "height": 59.2
+        },
+        {
+          "width": 150,
+          "height": 72.8
+        },
+        {
+          "width": 150,
+          "height": 79.6
+        },
+        {
+          "width": 150,
+          "height": 92.8
+        },
+        {
+          "width": 150,
+          "height": 104.4
+        },
+        {
+          "width": 150,
+          "height": 115.2
+        },
+        {
+          "width": 150,
+          "height": 125.2
+        },
+        {
+          "width": 150,
+          "height": 134.8
+        },
+        {
+          "width": 150,
+          "height": 143.2
+        },
+        {
+          "width": 150,
+          "height": 151.2
+        },
+        {
+          "width": 150,
+          "height": 158.8
+        },
+        {
+          "width": 150,
+          "height": 160
+        },
+        {
+          "width": 150,
+          "height": 167.2
+        },
+        {
+          "width": 150,
+          "height": 174.4
+        },
+        {
+          "width": 150,
+          "height": 180.8
+        },
+        {
+          "width": 150,
+          "height": 187.6
+        },
+        {
+          "width": 150,
+          "height": 188
+        },
+        {
+          "width": 150,
+          "height": 200.4
+        },
+        {
+          "width": 150,
+          "height": 218.4
+        },
+        {
+          "width": 150,
+          "height": 236.8
+        },
+        {
+          "width": 150,
+          "height": 253.2
+        },
+        {
+          "width": 150,
+          "height": 266.8
+        },
+        {
+          "width": 150,
+          "height": 277.2
+        },
+        {
+          "width": 150,
+          "height": 284.8
+        },
+        {
+          "width": 150,
+          "height": 290
+        },
+        {
+          "width": 150,
+          "height": 294
+        },
+        {
+          "width": 150,
+          "height": 296.4
+        },
+        {
+          "width": 150,
+          "height": 298
+        },
+        {
+          "width": 150,
+          "height": 298.8
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        },
+        {
+          "width": 150,
+          "height": 300
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        0,
+        0,
+        0,
+        0,
+        0.0067873597,
+        0.06125766,
+        0.19080031,
+        0.39327443,
+        0.5711931,
+        0.7085583,
+        0.8074065,
+        0.8754226,
+        0.9207788,
+        0.95032376,
+        0.9692185,
+        0.98112255,
+        0.9885286,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingClose.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingClose.json
new file mode 100644
index 0000000..015df8f
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingClose.json
@@ -0,0 +1,434 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 6.4,
+          "y": 5.2
+        },
+        {
+          "x": 10.4,
+          "y": 5.2
+        },
+        {
+          "x": 13.6,
+          "y": 5.2
+        },
+        {
+          "x": 15.6,
+          "y": 5.2
+        },
+        {
+          "x": 17.2,
+          "y": 5.2
+        },
+        {
+          "x": 18,
+          "y": 5.2
+        },
+        {
+          "x": 18.8,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 288.8
+        },
+        {
+          "width": 150,
+          "height": 278.8
+        },
+        {
+          "width": 150,
+          "height": 266
+        },
+        {
+          "width": 150,
+          "height": 252
+        },
+        {
+          "width": 150,
+          "height": 252
+        },
+        {
+          "width": 150,
+          "height": 224
+        },
+        {
+          "width": 150,
+          "height": 183.2
+        },
+        {
+          "width": 150,
+          "height": 141.6
+        },
+        {
+          "width": 150,
+          "height": 104.4
+        },
+        {
+          "width": 148,
+          "height": 74.4
+        },
+        {
+          "width": 139.6,
+          "height": 51.2
+        },
+        {
+          "width": 133.6,
+          "height": 32.4
+        },
+        {
+          "width": 129.6,
+          "height": 15.6
+        },
+        {
+          "width": 126.4,
+          "height": 5.2
+        },
+        {
+          "width": 124.4,
+          "height": 0
+        },
+        {
+          "width": 123.2,
+          "height": 0
+        },
+        {
+          "width": 122.4,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.99532944,
+        0.8594856,
+        0.65783304,
+        0.47089338,
+        0.32286334,
+        0.21474117,
+        0.139602,
+        0.089136004,
+        0.056082606,
+        0.03485179,
+        0.02142787,
+        0.013050735,
+        0.007881463,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingOpen.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingOpen.json
similarity index 63%
rename from packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingOpen.json
rename to packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingOpen.json
index 6dc5a0e..f202fcd 100644
--- a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingOpen.json
+++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_flingOpen.json
@@ -64,104 +64,104 @@
           "type": "not_found"
         },
         {
-          "x": 62.4,
-          "y": 50
+          "x": 17.6,
+          "y": 5.2
         },
         {
-          "x": 61.2,
-          "y": 50
+          "x": 16.4,
+          "y": 5.2
         },
         {
-          "x": 59.2,
-          "y": 50
+          "x": 14.4,
+          "y": 5.2
         },
         {
-          "x": 57.2,
-          "y": 50
+          "x": 12.4,
+          "y": 5.2
         },
         {
-          "x": 54.8,
-          "y": 50
+          "x": 10,
+          "y": 5.2
         },
         {
-          "x": 52.4,
-          "y": 50
+          "x": 7.6,
+          "y": 5.2
         },
         {
-          "x": 52.4,
-          "y": 50
+          "x": 7.6,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         },
         {
-          "x": 50,
-          "y": 50
+          "x": 5.2,
+          "y": 5.2
         }
       ]
     },
@@ -194,104 +194,104 @@
           "type": "not_found"
         },
         {
-          "width": 163.2,
+          "width": 125.2,
           "height": 2
         },
         {
-          "width": 166,
+          "width": 128,
           "height": 4.4
         },
         {
-          "width": 170,
+          "width": 132,
           "height": 6.8
         },
         {
-          "width": 174,
+          "width": 136,
           "height": 10
         },
         {
-          "width": 178.4,
+          "width": 140.4,
           "height": 13.2
         },
         {
-          "width": 183.6,
+          "width": 145.6,
           "height": 16.8
         },
         {
-          "width": 183.6,
+          "width": 145.6,
           "height": 16.8
         },
         {
-          "width": 188,
-          "height": 44.4
+          "width": 150,
+          "height": 36.8
         },
         {
-          "width": 188,
-          "height": 103.6
+          "width": 150,
+          "height": 81.2
         },
         {
-          "width": 188,
-          "height": 166
+          "width": 150,
+          "height": 126.8
         },
         {
-          "width": 188,
-          "height": 222.4
+          "width": 150,
+          "height": 168
         },
         {
-          "width": 188,
-          "height": 270
+          "width": 150,
+          "height": 202.8
         },
         {
-          "width": 188,
-          "height": 307.2
+          "width": 150,
+          "height": 230
         },
         {
-          "width": 188,
-          "height": 335.6
+          "width": 150,
+          "height": 250.8
         },
         {
-          "width": 188,
-          "height": 356.4
+          "width": 150,
+          "height": 266.4
         },
         {
-          "width": 188,
-          "height": 371.2
+          "width": 150,
+          "height": 277.6
         },
         {
-          "width": 188,
-          "height": 381.6
+          "width": 150,
+          "height": 285.2
         },
         {
-          "width": 188,
-          "height": 388.8
+          "width": 150,
+          "height": 290.4
         },
         {
-          "width": 188,
-          "height": 393.2
+          "width": 150,
+          "height": 294
         },
         {
-          "width": 188,
-          "height": 396
+          "width": 150,
+          "height": 296.4
         },
         {
-          "width": 188,
-          "height": 398
+          "width": 150,
+          "height": 298
         },
         {
-          "width": 188,
-          "height": 398.8
+          "width": 150,
+          "height": 298.8
         },
         {
-          "width": 188,
-          "height": 399.2
+          "width": 150,
+          "height": 299.2
         },
         {
-          "width": 188,
-          "height": 399.6
+          "width": 150,
+          "height": 299.6
         },
         {
-          "width": 188,
-          "height": 399.6
+          "width": 150,
+          "height": 299.6
         }
       ]
     },
diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_magneticDetachAndReattach.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_magneticDetachAndReattach.json
new file mode 100644
index 0000000..4c57bda
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_gesture_magneticDetachAndReattach.json
@@ -0,0 +1,724 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816,
+    832,
+    848,
+    864,
+    880,
+    896,
+    912,
+    928,
+    944,
+    960,
+    976,
+    992,
+    1008,
+    1024,
+    1040,
+    1056,
+    1072,
+    1088,
+    1104
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "x": 18,
+          "y": 5.2
+        },
+        {
+          "x": 17.2,
+          "y": 5.2
+        },
+        {
+          "x": 16.4,
+          "y": 5.2
+        },
+        {
+          "x": 15.6,
+          "y": 5.2
+        },
+        {
+          "x": 14.8,
+          "y": 5.2
+        },
+        {
+          "x": 14,
+          "y": 5.2
+        },
+        {
+          "x": 13.2,
+          "y": 5.2
+        },
+        {
+          "x": 12.4,
+          "y": 5.2
+        },
+        {
+          "x": 11.6,
+          "y": 5.2
+        },
+        {
+          "x": 10.8,
+          "y": 5.2
+        },
+        {
+          "x": 10.4,
+          "y": 5.2
+        },
+        {
+          "x": 9.6,
+          "y": 5.2
+        },
+        {
+          "x": 8.8,
+          "y": 5.2
+        },
+        {
+          "x": 8.4,
+          "y": 5.2
+        },
+        {
+          "x": 8,
+          "y": 5.2
+        },
+        {
+          "x": 7.2,
+          "y": 5.2
+        },
+        {
+          "x": 6.8,
+          "y": 5.2
+        },
+        {
+          "x": 6.4,
+          "y": 5.2
+        },
+        {
+          "x": 6,
+          "y": 5.2
+        },
+        {
+          "x": 5.6,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.6,
+          "y": 5.2
+        },
+        {
+          "x": 6,
+          "y": 5.2
+        },
+        {
+          "x": 6.4,
+          "y": 5.2
+        },
+        {
+          "x": 6.8,
+          "y": 5.2
+        },
+        {
+          "x": 7.2,
+          "y": 5.2
+        },
+        {
+          "x": 8,
+          "y": 5.2
+        },
+        {
+          "x": 8.4,
+          "y": 5.2
+        },
+        {
+          "x": 8.8,
+          "y": 5.2
+        },
+        {
+          "x": 9.6,
+          "y": 5.2
+        },
+        {
+          "x": 10.4,
+          "y": 5.2
+        },
+        {
+          "x": 10.8,
+          "y": 5.2
+        },
+        {
+          "x": 11.6,
+          "y": 5.2
+        },
+        {
+          "x": 12.4,
+          "y": 5.2
+        },
+        {
+          "x": 13.2,
+          "y": 5.2
+        },
+        {
+          "x": 14,
+          "y": 5.2
+        },
+        {
+          "x": 14.8,
+          "y": 5.2
+        },
+        {
+          "x": 15.6,
+          "y": 5.2
+        },
+        {
+          "x": 16.4,
+          "y": 5.2
+        },
+        {
+          "x": 17.2,
+          "y": 5.2
+        },
+        {
+          "x": 18,
+          "y": 5.2
+        },
+        {
+          "x": 18.8,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "width": 124.4,
+          "height": 1.6
+        },
+        {
+          "width": 126,
+          "height": 2.8
+        },
+        {
+          "width": 128,
+          "height": 4
+        },
+        {
+          "width": 129.6,
+          "height": 5.2
+        },
+        {
+          "width": 131.2,
+          "height": 6.4
+        },
+        {
+          "width": 132.8,
+          "height": 7.6
+        },
+        {
+          "width": 134.4,
+          "height": 8.8
+        },
+        {
+          "width": 136,
+          "height": 10
+        },
+        {
+          "width": 137.2,
+          "height": 10.8
+        },
+        {
+          "width": 138.8,
+          "height": 12
+        },
+        {
+          "width": 140,
+          "height": 12.8
+        },
+        {
+          "width": 141.2,
+          "height": 13.6
+        },
+        {
+          "width": 142.8,
+          "height": 14.8
+        },
+        {
+          "width": 144,
+          "height": 15.6
+        },
+        {
+          "width": 144.8,
+          "height": 16.4
+        },
+        {
+          "width": 146,
+          "height": 17.2
+        },
+        {
+          "width": 146.8,
+          "height": 17.6
+        },
+        {
+          "width": 148,
+          "height": 18.4
+        },
+        {
+          "width": 148.8,
+          "height": 19.2
+        },
+        {
+          "width": 149.6,
+          "height": 19.6
+        },
+        {
+          "width": 150,
+          "height": 21.2
+        },
+        {
+          "width": 150,
+          "height": 24.8
+        },
+        {
+          "width": 150,
+          "height": 30
+        },
+        {
+          "width": 150,
+          "height": 38
+        },
+        {
+          "width": 150,
+          "height": 46
+        },
+        {
+          "width": 150,
+          "height": 54
+        },
+        {
+          "width": 150,
+          "height": 61.2
+        },
+        {
+          "width": 150,
+          "height": 66.8
+        },
+        {
+          "width": 150,
+          "height": 71.6
+        },
+        {
+          "width": 150,
+          "height": 75.6
+        },
+        {
+          "width": 150,
+          "height": 78
+        },
+        {
+          "width": 150,
+          "height": 79.6
+        },
+        {
+          "width": 150,
+          "height": 80.8
+        },
+        {
+          "width": 150,
+          "height": 80.8
+        },
+        {
+          "width": 150,
+          "height": 80.4
+        },
+        {
+          "width": 150,
+          "height": 79.6
+        },
+        {
+          "width": 149.6,
+          "height": 78
+        },
+        {
+          "width": 148.8,
+          "height": 76.4
+        },
+        {
+          "width": 148,
+          "height": 74
+        },
+        {
+          "width": 146.8,
+          "height": 71.6
+        },
+        {
+          "width": 146,
+          "height": 69.2
+        },
+        {
+          "width": 144.8,
+          "height": 66
+        },
+        {
+          "width": 144,
+          "height": 62.8
+        },
+        {
+          "width": 142.8,
+          "height": 59.2
+        },
+        {
+          "width": 141.2,
+          "height": 55.6
+        },
+        {
+          "width": 140,
+          "height": 52
+        },
+        {
+          "width": 138.8,
+          "height": 48
+        },
+        {
+          "width": 137.2,
+          "height": 44
+        },
+        {
+          "width": 136,
+          "height": 40
+        },
+        {
+          "width": 134.4,
+          "height": 37.6
+        },
+        {
+          "width": 132.8,
+          "height": 38
+        },
+        {
+          "width": 131.2,
+          "height": 30.4
+        },
+        {
+          "width": 129.6,
+          "height": 25.2
+        },
+        {
+          "width": 128,
+          "height": 20.4
+        },
+        {
+          "width": 126,
+          "height": 16
+        },
+        {
+          "width": 124.4,
+          "height": 12.4
+        },
+        {
+          "width": 122.8,
+          "height": 9.2
+        },
+        {
+          "width": 122,
+          "height": 6.8
+        },
+        {
+          "width": 122,
+          "height": 5.2
+        },
+        {
+          "width": 122,
+          "height": 3.6
+        },
+        {
+          "width": 122,
+          "height": 2.4
+        },
+        {
+          "width": 122,
+          "height": 1.6
+        },
+        {
+          "width": 122,
+          "height": 0.8
+        },
+        {
+          "width": 122,
+          "height": 0.4
+        },
+        {
+          "width": 122,
+          "height": 0.4
+        },
+        {
+          "width": 122,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        0,
+        0,
+        0,
+        0,
+        0.012518823,
+        0.0741024,
+        0.22542936,
+        0.42628878,
+        0.5976642,
+        0.7280313,
+        0.82100236,
+        0.8845844,
+        0.9267946,
+        0.95419544,
+        0.9716705,
+        0.98265487,
+        0.98947525,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.9944124,
+        0.9417388,
+        0.81841844,
+        0.61578125,
+        0.43616113,
+        0.29689062,
+        0.19641556,
+        0.12716138,
+        0.080922,
+        0.050773032,
+        0.031477194,
+        0.019312754,
+        0.011740657,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealCloseTransition.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealCloseTransition.json
new file mode 100644
index 0000000..26c80e3
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealCloseTransition.json
@@ -0,0 +1,314 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 7.2,
+          "y": 5.2
+        },
+        {
+          "x": 11.2,
+          "y": 5.2
+        },
+        {
+          "x": 14,
+          "y": 5.2
+        },
+        {
+          "x": 16,
+          "y": 5.2
+        },
+        {
+          "x": 17.6,
+          "y": 5.2
+        },
+        {
+          "x": 18.4,
+          "y": 5.2
+        },
+        {
+          "x": 18.8,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 278.8
+        },
+        {
+          "width": 150,
+          "height": 234.8
+        },
+        {
+          "width": 150,
+          "height": 185.2
+        },
+        {
+          "width": 150,
+          "height": 138.8
+        },
+        {
+          "width": 150,
+          "height": 100.4
+        },
+        {
+          "width": 146.4,
+          "height": 69.6
+        },
+        {
+          "width": 138.4,
+          "height": 46.8
+        },
+        {
+          "width": 132.4,
+          "height": 28
+        },
+        {
+          "width": 128.4,
+          "height": 13.2
+        },
+        {
+          "width": 125.6,
+          "height": 4
+        },
+        {
+          "width": 124,
+          "height": 0
+        },
+        {
+          "width": 122.8,
+          "height": 0
+        },
+        {
+          "width": 122.4,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 122,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.9762947,
+        0.8118515,
+        0.60931784,
+        0.43090785,
+        0.29299664,
+        0.19368339,
+        0.12531388,
+        0.079705715,
+        0.049988627,
+        0.030979574,
+        0.019001365,
+        0.011548042,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealOpenTransition.json b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealOpenTransition.json
new file mode 100644
index 0000000..7a02d36
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/edge_verticalReveal_triggeredRevealOpenTransition.json
@@ -0,0 +1,224 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "x": 19.2,
+          "y": 5.2
+        },
+        {
+          "x": 15.6,
+          "y": 5.2
+        },
+        {
+          "x": 8,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "width": 122,
+          "height": 0
+        },
+        {
+          "width": 129.2,
+          "height": 5.2
+        },
+        {
+          "width": 144.4,
+          "height": 16
+        },
+        {
+          "width": 150,
+          "height": 62
+        },
+        {
+          "width": 150,
+          "height": 118.4
+        },
+        {
+          "width": 150,
+          "height": 166
+        },
+        {
+          "width": 150,
+          "height": 204
+        },
+        {
+          "width": 150,
+          "height": 233.2
+        },
+        {
+          "width": 150,
+          "height": 254.4
+        },
+        {
+          "width": 150,
+          "height": 270
+        },
+        {
+          "width": 150,
+          "height": 280.8
+        },
+        {
+          "width": 150,
+          "height": 288
+        },
+        {
+          "width": 150,
+          "height": 292.8
+        },
+        {
+          "width": 150,
+          "height": 296
+        },
+        {
+          "width": 150,
+          "height": 298
+        },
+        {
+          "width": 150,
+          "height": 298.8
+        },
+        {
+          "width": 150,
+          "height": 299.2
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        0,
+        0,
+        0.0951103,
+        0.2911651,
+        0.48551244,
+        0.6439433,
+        0.76157355,
+        0.8441935,
+        0.9001033,
+        0.9369305,
+        0.96069145,
+        0.97577035,
+        0.98520935,
+        0.9910494,
+        1,
+        1,
+        1,
+        1,
+        1
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragFullyClose.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragFullyClose.json
new file mode 100644
index 0000000..5ac0621
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragFullyClose.json
@@ -0,0 +1,584 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816,
+    832,
+    848,
+    864,
+    880
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 292.8
+        },
+        {
+          "width": 150,
+          "height": 292.8
+        },
+        {
+          "width": 150,
+          "height": 286
+        },
+        {
+          "width": 150,
+          "height": 279.6
+        },
+        {
+          "width": 150,
+          "height": 273.2
+        },
+        {
+          "width": 150,
+          "height": 266.8
+        },
+        {
+          "width": 150,
+          "height": 260.4
+        },
+        {
+          "width": 150,
+          "height": 254
+        },
+        {
+          "width": 150,
+          "height": 247.6
+        },
+        {
+          "width": 150,
+          "height": 241.2
+        },
+        {
+          "width": 150,
+          "height": 241.2
+        },
+        {
+          "width": 150,
+          "height": 234.4
+        },
+        {
+          "width": 150,
+          "height": 228
+        },
+        {
+          "width": 150,
+          "height": 221.6
+        },
+        {
+          "width": 150,
+          "height": 215.2
+        },
+        {
+          "width": 150,
+          "height": 208.8
+        },
+        {
+          "width": 150,
+          "height": 202
+        },
+        {
+          "width": 150,
+          "height": 195.6
+        },
+        {
+          "width": 150,
+          "height": 189.2
+        },
+        {
+          "width": 150,
+          "height": 189.2
+        },
+        {
+          "width": 150,
+          "height": 182.8
+        },
+        {
+          "width": 150,
+          "height": 176.4
+        },
+        {
+          "width": 150,
+          "height": 170
+        },
+        {
+          "width": 150,
+          "height": 163.6
+        },
+        {
+          "width": 150,
+          "height": 157.2
+        },
+        {
+          "width": 150,
+          "height": 150.8
+        },
+        {
+          "width": 150,
+          "height": 144.4
+        },
+        {
+          "width": 150,
+          "height": 137.6
+        },
+        {
+          "width": 150,
+          "height": 137.6
+        },
+        {
+          "width": 150,
+          "height": 131.2
+        },
+        {
+          "width": 150,
+          "height": 124.8
+        },
+        {
+          "width": 150,
+          "height": 118.4
+        },
+        {
+          "width": 150,
+          "height": 112
+        },
+        {
+          "width": 150,
+          "height": 112
+        },
+        {
+          "width": 150,
+          "height": 99.2
+        },
+        {
+          "width": 150,
+          "height": 84.4
+        },
+        {
+          "width": 150,
+          "height": 70.8
+        },
+        {
+          "width": 150,
+          "height": 58
+        },
+        {
+          "width": 150,
+          "height": 46.4
+        },
+        {
+          "width": 150,
+          "height": 36.4
+        },
+        {
+          "width": 150,
+          "height": 28
+        },
+        {
+          "width": 150,
+          "height": 20.8
+        },
+        {
+          "width": 150,
+          "height": 15.6
+        },
+        {
+          "width": 150,
+          "height": 11.2
+        },
+        {
+          "width": 150,
+          "height": 8
+        },
+        {
+          "width": 150,
+          "height": 5.6
+        },
+        {
+          "width": 150,
+          "height": 3.6
+        },
+        {
+          "width": 150,
+          "height": 2.4
+        },
+        {
+          "width": 150,
+          "height": 1.2
+        },
+        {
+          "width": 150,
+          "height": 0.8
+        },
+        {
+          "width": 150,
+          "height": 0.4
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.99781144,
+        0.87040234,
+        0.6695792,
+        0.48078007,
+        0.33033127,
+        0.22004372,
+        0.1432175,
+        0.09153092,
+        0.057634592,
+        0.035840213,
+        0.022048414,
+        0.013435662,
+        0.008117795,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragHalfClose.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragHalfClose.json
new file mode 100644
index 0000000..1cae67b
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragHalfClose.json
@@ -0,0 +1,624 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816,
+    832,
+    848,
+    864,
+    880,
+    896,
+    912,
+    928,
+    944
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 297.6
+        },
+        {
+          "width": 150,
+          "height": 292.4
+        },
+        {
+          "width": 150,
+          "height": 287.6
+        },
+        {
+          "width": 150,
+          "height": 282.8
+        },
+        {
+          "width": 150,
+          "height": 278
+        },
+        {
+          "width": 150,
+          "height": 273.2
+        },
+        {
+          "width": 150,
+          "height": 268.4
+        },
+        {
+          "width": 150,
+          "height": 263.6
+        },
+        {
+          "width": 150,
+          "height": 258.8
+        },
+        {
+          "width": 150,
+          "height": 258.8
+        },
+        {
+          "width": 150,
+          "height": 253.6
+        },
+        {
+          "width": 150,
+          "height": 248.8
+        },
+        {
+          "width": 150,
+          "height": 244
+        },
+        {
+          "width": 150,
+          "height": 239.2
+        },
+        {
+          "width": 150,
+          "height": 234.4
+        },
+        {
+          "width": 150,
+          "height": 229.6
+        },
+        {
+          "width": 150,
+          "height": 224.8
+        },
+        {
+          "width": 150,
+          "height": 220
+        },
+        {
+          "width": 150,
+          "height": 220
+        },
+        {
+          "width": 150,
+          "height": 214.8
+        },
+        {
+          "width": 150,
+          "height": 210
+        },
+        {
+          "width": 150,
+          "height": 205.2
+        },
+        {
+          "width": 150,
+          "height": 200.4
+        },
+        {
+          "width": 150,
+          "height": 195.6
+        },
+        {
+          "width": 150,
+          "height": 190.8
+        },
+        {
+          "width": 150,
+          "height": 186
+        },
+        {
+          "width": 150,
+          "height": 181.2
+        },
+        {
+          "width": 150,
+          "height": 181.2
+        },
+        {
+          "width": 150,
+          "height": 176.4
+        },
+        {
+          "width": 150,
+          "height": 171.6
+        },
+        {
+          "width": 150,
+          "height": 166.8
+        },
+        {
+          "width": 150,
+          "height": 161.6
+        },
+        {
+          "width": 150,
+          "height": 161.6
+        },
+        {
+          "width": 150,
+          "height": 147.2
+        },
+        {
+          "width": 150,
+          "height": 122
+        },
+        {
+          "width": 150,
+          "height": 95.2
+        },
+        {
+          "width": 150,
+          "height": 70.8
+        },
+        {
+          "width": 150,
+          "height": 51.6
+        },
+        {
+          "width": 150,
+          "height": 36.8
+        },
+        {
+          "width": 150,
+          "height": 25.6
+        },
+        {
+          "width": 150,
+          "height": 17.2
+        },
+        {
+          "width": 150,
+          "height": 11.2
+        },
+        {
+          "width": 150,
+          "height": 6.8
+        },
+        {
+          "width": 150,
+          "height": 4
+        },
+        {
+          "width": 150,
+          "height": 2
+        },
+        {
+          "width": 150,
+          "height": 0.8
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.99979615,
+        0.8860379,
+        0.6869267,
+        0.4955439,
+        0.34154767,
+        0.22803628,
+        0.14868057,
+        0.09515619,
+        0.059987247,
+        0.037340224,
+        0.02299112,
+        0.01402092,
+        0.008477271,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragOpen.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragOpen.json
new file mode 100644
index 0000000..1bf6a62
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_dragOpen.json
@@ -0,0 +1,544 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "width": 150,
+          "height": 1.6
+        },
+        {
+          "width": 150,
+          "height": 1.6
+        },
+        {
+          "width": 150,
+          "height": 3.2
+        },
+        {
+          "width": 150,
+          "height": 4.8
+        },
+        {
+          "width": 150,
+          "height": 6.4
+        },
+        {
+          "width": 150,
+          "height": 8
+        },
+        {
+          "width": 150,
+          "height": 9.6
+        },
+        {
+          "width": 150,
+          "height": 11.2
+        },
+        {
+          "width": 150,
+          "height": 12.8
+        },
+        {
+          "width": 150,
+          "height": 14.4
+        },
+        {
+          "width": 150,
+          "height": 14.4
+        },
+        {
+          "width": 150,
+          "height": 16.4
+        },
+        {
+          "width": 150,
+          "height": 18
+        },
+        {
+          "width": 150,
+          "height": 19.6
+        },
+        {
+          "width": 150,
+          "height": 20.8
+        },
+        {
+          "width": 150,
+          "height": 22.8
+        },
+        {
+          "width": 150,
+          "height": 24.4
+        },
+        {
+          "width": 150,
+          "height": 26
+        },
+        {
+          "width": 150,
+          "height": 27.6
+        },
+        {
+          "width": 150,
+          "height": 27.6
+        },
+        {
+          "width": 150,
+          "height": 29.2
+        },
+        {
+          "width": 150,
+          "height": 30.8
+        },
+        {
+          "width": 150,
+          "height": 32.4
+        },
+        {
+          "width": 150,
+          "height": 34
+        },
+        {
+          "width": 150,
+          "height": 40.4
+        },
+        {
+          "width": 150,
+          "height": 52.4
+        },
+        {
+          "width": 150,
+          "height": 64.8
+        },
+        {
+          "width": 150,
+          "height": 83.2
+        },
+        {
+          "width": 150,
+          "height": 96
+        },
+        {
+          "width": 150,
+          "height": 114.8
+        },
+        {
+          "width": 150,
+          "height": 132
+        },
+        {
+          "width": 150,
+          "height": 148
+        },
+        {
+          "width": 150,
+          "height": 162
+        },
+        {
+          "width": 150,
+          "height": 168.4
+        },
+        {
+          "width": 150,
+          "height": 186
+        },
+        {
+          "width": 150,
+          "height": 208
+        },
+        {
+          "width": 150,
+          "height": 229.6
+        },
+        {
+          "width": 150,
+          "height": 248.4
+        },
+        {
+          "width": 150,
+          "height": 263.2
+        },
+        {
+          "width": 150,
+          "height": 274.8
+        },
+        {
+          "width": 150,
+          "height": 283.2
+        },
+        {
+          "width": 150,
+          "height": 289.2
+        },
+        {
+          "width": 150,
+          "height": 293.6
+        },
+        {
+          "width": 150,
+          "height": 296
+        },
+        {
+          "width": 150,
+          "height": 298
+        },
+        {
+          "width": 150,
+          "height": 298.8
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        },
+        {
+          "width": 150,
+          "height": 300
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        0,
+        0,
+        0,
+        0,
+        0.0067873597,
+        0.06125766,
+        0.19080031,
+        0.39327443,
+        0.5711931,
+        0.7085583,
+        0.8074065,
+        0.8754226,
+        0.9207788,
+        0.95032376,
+        0.9692185,
+        0.98112255,
+        0.9885286,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingClose.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingClose.json
new file mode 100644
index 0000000..ca87bc2
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingClose.json
@@ -0,0 +1,424 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 288.8
+        },
+        {
+          "width": 150,
+          "height": 278.8
+        },
+        {
+          "width": 150,
+          "height": 266
+        },
+        {
+          "width": 150,
+          "height": 252
+        },
+        {
+          "width": 150,
+          "height": 252
+        },
+        {
+          "width": 150,
+          "height": 224
+        },
+        {
+          "width": 150,
+          "height": 183.2
+        },
+        {
+          "width": 150,
+          "height": 141.6
+        },
+        {
+          "width": 150,
+          "height": 104.4
+        },
+        {
+          "width": 150,
+          "height": 72.4
+        },
+        {
+          "width": 150,
+          "height": 46.4
+        },
+        {
+          "width": 150,
+          "height": 28
+        },
+        {
+          "width": 150,
+          "height": 15.6
+        },
+        {
+          "width": 150,
+          "height": 7.2
+        },
+        {
+          "width": 150,
+          "height": 2
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.99532944,
+        0.8594856,
+        0.65783304,
+        0.47089338,
+        0.32286334,
+        0.21474117,
+        0.139602,
+        0.089136004,
+        0.056082606,
+        0.03485179,
+        0.02142787,
+        0.013050735,
+        0.007881463,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingOpen.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingOpen.json
new file mode 100644
index 0000000..98519db
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_flingOpen.json
@@ -0,0 +1,374 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "width": 150,
+          "height": 2
+        },
+        {
+          "width": 150,
+          "height": 4.4
+        },
+        {
+          "width": 150,
+          "height": 6.8
+        },
+        {
+          "width": 150,
+          "height": 10
+        },
+        {
+          "width": 150,
+          "height": 13.2
+        },
+        {
+          "width": 150,
+          "height": 16.8
+        },
+        {
+          "width": 150,
+          "height": 16.8
+        },
+        {
+          "width": 150,
+          "height": 23.6
+        },
+        {
+          "width": 150,
+          "height": 32.8
+        },
+        {
+          "width": 150,
+          "height": 76.8
+        },
+        {
+          "width": 150,
+          "height": 123.6
+        },
+        {
+          "width": 150,
+          "height": 164.8
+        },
+        {
+          "width": 150,
+          "height": 198.4
+        },
+        {
+          "width": 150,
+          "height": 225.6
+        },
+        {
+          "width": 150,
+          "height": 246.4
+        },
+        {
+          "width": 150,
+          "height": 262
+        },
+        {
+          "width": 150,
+          "height": 273.2
+        },
+        {
+          "width": 150,
+          "height": 281.6
+        },
+        {
+          "width": 150,
+          "height": 287.6
+        },
+        {
+          "width": 150,
+          "height": 292
+        },
+        {
+          "width": 150,
+          "height": 294.8
+        },
+        {
+          "width": 150,
+          "height": 296.4
+        },
+        {
+          "width": 150,
+          "height": 297.6
+        },
+        {
+          "width": 150,
+          "height": 298.4
+        },
+        {
+          "width": 150,
+          "height": 299.2
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        0,
+        0,
+        0.008216977,
+        0.06259775,
+        0.19032806,
+        0.39281356,
+        0.57081985,
+        0.7082821,
+        0.80721295,
+        0.8752918,
+        0.9206928,
+        0.95026827,
+        0.9691833,
+        0.98110056,
+        0.988515,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_magneticDetachAndReattach.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_magneticDetachAndReattach.json
new file mode 100644
index 0000000..850cee9
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_gesture_magneticDetachAndReattach.json
@@ -0,0 +1,744 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432,
+    448,
+    464,
+    480,
+    496,
+    512,
+    528,
+    544,
+    560,
+    576,
+    592,
+    608,
+    624,
+    640,
+    656,
+    672,
+    688,
+    704,
+    720,
+    736,
+    752,
+    768,
+    784,
+    800,
+    816,
+    832,
+    848,
+    864,
+    880,
+    896,
+    912,
+    928,
+    944,
+    960,
+    976,
+    992,
+    1008,
+    1024,
+    1040,
+    1056,
+    1072,
+    1088,
+    1104,
+    1120,
+    1136
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "width": 150,
+          "height": 2.8
+        },
+        {
+          "width": 150,
+          "height": 4.8
+        },
+        {
+          "width": 150,
+          "height": 6.8
+        },
+        {
+          "width": 150,
+          "height": 8.4
+        },
+        {
+          "width": 150,
+          "height": 10.4
+        },
+        {
+          "width": 150,
+          "height": 12.4
+        },
+        {
+          "width": 150,
+          "height": 14
+        },
+        {
+          "width": 150,
+          "height": 16
+        },
+        {
+          "width": 150,
+          "height": 17.6
+        },
+        {
+          "width": 150,
+          "height": 19.2
+        },
+        {
+          "width": 150,
+          "height": 20.8
+        },
+        {
+          "width": 150,
+          "height": 22.4
+        },
+        {
+          "width": 150,
+          "height": 24
+        },
+        {
+          "width": 150,
+          "height": 25.6
+        },
+        {
+          "width": 150,
+          "height": 26.8
+        },
+        {
+          "width": 150,
+          "height": 28
+        },
+        {
+          "width": 150,
+          "height": 29.2
+        },
+        {
+          "width": 150,
+          "height": 30.4
+        },
+        {
+          "width": 150,
+          "height": 31.6
+        },
+        {
+          "width": 150,
+          "height": 32.4
+        },
+        {
+          "width": 150,
+          "height": 33.2
+        },
+        {
+          "width": 150,
+          "height": 34
+        },
+        {
+          "width": 150,
+          "height": 36.8
+        },
+        {
+          "width": 150,
+          "height": 42.4
+        },
+        {
+          "width": 150,
+          "height": 50.8
+        },
+        {
+          "width": 150,
+          "height": 64
+        },
+        {
+          "width": 150,
+          "height": 78
+        },
+        {
+          "width": 150,
+          "height": 91.2
+        },
+        {
+          "width": 150,
+          "height": 102.4
+        },
+        {
+          "width": 150,
+          "height": 112.4
+        },
+        {
+          "width": 150,
+          "height": 120
+        },
+        {
+          "width": 150,
+          "height": 126
+        },
+        {
+          "width": 150,
+          "height": 130
+        },
+        {
+          "width": 150,
+          "height": 132.8
+        },
+        {
+          "width": 150,
+          "height": 134
+        },
+        {
+          "width": 150,
+          "height": 134
+        },
+        {
+          "width": 150,
+          "height": 133.2
+        },
+        {
+          "width": 150,
+          "height": 131.2
+        },
+        {
+          "width": 150,
+          "height": 128.8
+        },
+        {
+          "width": 150,
+          "height": 125.2
+        },
+        {
+          "width": 150,
+          "height": 121.6
+        },
+        {
+          "width": 150,
+          "height": 117.6
+        },
+        {
+          "width": 150,
+          "height": 112.8
+        },
+        {
+          "width": 150,
+          "height": 108
+        },
+        {
+          "width": 150,
+          "height": 102.4
+        },
+        {
+          "width": 150,
+          "height": 96.4
+        },
+        {
+          "width": 150,
+          "height": 91.2
+        },
+        {
+          "width": 150,
+          "height": 88
+        },
+        {
+          "width": 150,
+          "height": 81.6
+        },
+        {
+          "width": 150,
+          "height": 70.8
+        },
+        {
+          "width": 150,
+          "height": 59.2
+        },
+        {
+          "width": 150,
+          "height": 48
+        },
+        {
+          "width": 150,
+          "height": 38.4
+        },
+        {
+          "width": 150,
+          "height": 30
+        },
+        {
+          "width": 150,
+          "height": 22.8
+        },
+        {
+          "width": 150,
+          "height": 17.2
+        },
+        {
+          "width": 150,
+          "height": 12.4
+        },
+        {
+          "width": 150,
+          "height": 9.2
+        },
+        {
+          "width": 150,
+          "height": 6.4
+        },
+        {
+          "width": 150,
+          "height": 4.4
+        },
+        {
+          "width": 150,
+          "height": 2.8
+        },
+        {
+          "width": 150,
+          "height": 1.6
+        },
+        {
+          "width": 150,
+          "height": 1.2
+        },
+        {
+          "width": 150,
+          "height": 0.4
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        {
+          "type": "not_found"
+        },
+        0,
+        0,
+        0.0066464543,
+        0.059778452,
+        0.1875459,
+        0.39009166,
+        0.5686131,
+        0.70664865,
+        0.8060679,
+        0.87451804,
+        0.92018366,
+        0.94994,
+        0.9689752,
+        0.9809703,
+        0.98843443,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.98828065,
+        0.9288363,
+        0.7806658,
+        0.57941735,
+        0.40687433,
+        0.27529213,
+        0.18131107,
+        0.11697123,
+        0.074225225,
+        0.046460062,
+        0.028744182,
+        0.017604083,
+        0.010684598
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealCloseTransition.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealCloseTransition.json
new file mode 100644
index 0000000..afa005a
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealCloseTransition.json
@@ -0,0 +1,304 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352,
+    368,
+    384,
+    400,
+    416,
+    432
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 300
+        },
+        {
+          "width": 150,
+          "height": 278.8
+        },
+        {
+          "width": 150,
+          "height": 234.8
+        },
+        {
+          "width": 150,
+          "height": 185.2
+        },
+        {
+          "width": 150,
+          "height": 138.8
+        },
+        {
+          "width": 150,
+          "height": 100.4
+        },
+        {
+          "width": 150,
+          "height": 66.8
+        },
+        {
+          "width": 150,
+          "height": 41.6
+        },
+        {
+          "width": 150,
+          "height": 23.6
+        },
+        {
+          "width": 150,
+          "height": 12
+        },
+        {
+          "width": 150,
+          "height": 4.4
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 0
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        0.9762947,
+        0.8118515,
+        0.60931784,
+        0.43090785,
+        0.29299664,
+        0.19368339,
+        0.12531388,
+        0.079705715,
+        0.049988627,
+        0.030979574,
+        0.019001365,
+        0.011548042,
+        0,
+        0,
+        0,
+        0,
+        0,
+        0
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealOpenTransition.json b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealOpenTransition.json
new file mode 100644
index 0000000..317d480
--- /dev/null
+++ b/packages/SystemUI/compose/scene/tests/goldens/floating_verticalReveal_triggeredRevealOpenTransition.json
@@ -0,0 +1,254 @@
+{
+  "frame_ids": [
+    0,
+    16,
+    32,
+    48,
+    64,
+    80,
+    96,
+    112,
+    128,
+    144,
+    160,
+    176,
+    192,
+    208,
+    224,
+    240,
+    256,
+    272,
+    288,
+    304,
+    320,
+    336,
+    352
+  ],
+  "features": [
+    {
+      "name": "RevealElement_position",
+      "type": "dpOffset",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        },
+        {
+          "x": 5.2,
+          "y": 5.2
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_size",
+      "type": "dpSize",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        {
+          "width": 150,
+          "height": 0
+        },
+        {
+          "width": 150,
+          "height": 5.2
+        },
+        {
+          "width": 150,
+          "height": 16
+        },
+        {
+          "width": 150,
+          "height": 28.4
+        },
+        {
+          "width": 150,
+          "height": 63.6
+        },
+        {
+          "width": 150,
+          "height": 116.4
+        },
+        {
+          "width": 150,
+          "height": 161.2
+        },
+        {
+          "width": 150,
+          "height": 197.2
+        },
+        {
+          "width": 150,
+          "height": 225.2
+        },
+        {
+          "width": 150,
+          "height": 246.8
+        },
+        {
+          "width": 150,
+          "height": 262.4
+        },
+        {
+          "width": 150,
+          "height": 274
+        },
+        {
+          "width": 150,
+          "height": 282.4
+        },
+        {
+          "width": 150,
+          "height": 288.4
+        },
+        {
+          "width": 150,
+          "height": 292.4
+        },
+        {
+          "width": 150,
+          "height": 294.8
+        },
+        {
+          "width": 150,
+          "height": 296.4
+        },
+        {
+          "width": 150,
+          "height": 297.6
+        },
+        {
+          "width": 150,
+          "height": 298.4
+        },
+        {
+          "width": 150,
+          "height": 299.2
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        },
+        {
+          "width": 150,
+          "height": 299.6
+        }
+      ]
+    },
+    {
+      "name": "RevealElement_alpha",
+      "type": "float",
+      "data_points": [
+        {
+          "type": "not_found"
+        },
+        0,
+        0,
+        0.0951103,
+        0.2911651,
+        0.48551244,
+        0.6439433,
+        0.76157355,
+        0.8441935,
+        0.9001033,
+        0.9369305,
+        0.96069145,
+        0.97577035,
+        0.98520935,
+        0.9910494,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1,
+        1
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragFullyClose.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragFullyClose.json
deleted file mode 100644
index 57f6766..0000000
--- a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragFullyClose.json
+++ /dev/null
@@ -1,654 +0,0 @@
-{
-  "frame_ids": [
-    0,
-    16,
-    32,
-    48,
-    64,
-    80,
-    96,
-    112,
-    128,
-    144,
-    160,
-    176,
-    192,
-    208,
-    224,
-    240,
-    256,
-    272,
-    288,
-    304,
-    320,
-    336,
-    352,
-    368,
-    384,
-    400,
-    416,
-    432,
-    448,
-    464,
-    480,
-    496,
-    512,
-    528,
-    544,
-    560,
-    576,
-    592,
-    608,
-    624,
-    640,
-    656,
-    672,
-    688,
-    704,
-    720,
-    736,
-    752,
-    768,
-    784,
-    800,
-    816,
-    832,
-    848,
-    864,
-    880,
-    896,
-    912,
-    928,
-    944,
-    960,
-    976,
-    992
-  ],
-  "features": [
-    {
-      "name": "RevealElement_position",
-      "type": "dpOffset",
-      "data_points": [
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50.4
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 52.4,
-          "y": 50
-        },
-        {
-          "x": 56,
-          "y": 50
-        },
-        {
-          "x": 58.8,
-          "y": 50
-        },
-        {
-          "x": 60.8,
-          "y": 50
-        },
-        {
-          "x": 62,
-          "y": 50
-        },
-        {
-          "x": 62.8,
-          "y": 50
-        },
-        {
-          "x": 63.6,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_size",
-      "type": "dpSize",
-      "data_points": [
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 393.2
-        },
-        {
-          "width": 188,
-          "height": 393.2
-        },
-        {
-          "width": 188,
-          "height": 386
-        },
-        {
-          "width": 188,
-          "height": 379.6
-        },
-        {
-          "width": 188,
-          "height": 372.8
-        },
-        {
-          "width": 188,
-          "height": 366.8
-        },
-        {
-          "width": 188,
-          "height": 360.4
-        },
-        {
-          "width": 188,
-          "height": 354
-        },
-        {
-          "width": 188,
-          "height": 347.6
-        },
-        {
-          "width": 188,
-          "height": 341.2
-        },
-        {
-          "width": 188,
-          "height": 341.2
-        },
-        {
-          "width": 188,
-          "height": 334
-        },
-        {
-          "width": 188,
-          "height": 328
-        },
-        {
-          "width": 188,
-          "height": 321.6
-        },
-        {
-          "width": 188,
-          "height": 315.2
-        },
-        {
-          "width": 188,
-          "height": 308.8
-        },
-        {
-          "width": 188,
-          "height": 302.4
-        },
-        {
-          "width": 188,
-          "height": 296
-        },
-        {
-          "width": 188,
-          "height": 289.6
-        },
-        {
-          "width": 188,
-          "height": 289.6
-        },
-        {
-          "width": 188,
-          "height": 282.8
-        },
-        {
-          "width": 188,
-          "height": 276.4
-        },
-        {
-          "width": 188,
-          "height": 270
-        },
-        {
-          "width": 188,
-          "height": 263.6
-        },
-        {
-          "width": 188,
-          "height": 257.2
-        },
-        {
-          "width": 188,
-          "height": 250.8
-        },
-        {
-          "width": 188,
-          "height": 244.4
-        },
-        {
-          "width": 188,
-          "height": 238
-        },
-        {
-          "width": 188,
-          "height": 238
-        },
-        {
-          "width": 188,
-          "height": 231.2
-        },
-        {
-          "width": 188,
-          "height": 224.8
-        },
-        {
-          "width": 188,
-          "height": 218.4
-        },
-        {
-          "width": 188,
-          "height": 212
-        },
-        {
-          "width": 188,
-          "height": 212
-        },
-        {
-          "width": 188,
-          "height": 192.4
-        },
-        {
-          "width": 188,
-          "height": 159.6
-        },
-        {
-          "width": 188,
-          "height": 124.4
-        },
-        {
-          "width": 188,
-          "height": 92.8
-        },
-        {
-          "width": 183.2,
-          "height": 66.4
-        },
-        {
-          "width": 176,
-          "height": 46
-        },
-        {
-          "width": 170.4,
-          "height": 28.8
-        },
-        {
-          "width": 166.8,
-          "height": 15.2
-        },
-        {
-          "width": 164,
-          "height": 6.4
-        },
-        {
-          "width": 162.4,
-          "height": 0.8
-        },
-        {
-          "width": 161.2,
-          "height": 0
-        },
-        {
-          "width": 160.4,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_alpha",
-      "type": "float",
-      "data_points": [
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        0.9808927,
-        0.8211168,
-        0.61845565,
-        0.43834114,
-        0.29850912,
-        0.19755232,
-        0.12793064,
-        0.08142871,
-        0.051099956,
-        0.031684637,
-        0.019442618,
-        0.011821032,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragHalfClose.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragHalfClose.json
deleted file mode 100644
index 01bc852..0000000
--- a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragHalfClose.json
+++ /dev/null
@@ -1,644 +0,0 @@
-{
-  "frame_ids": [
-    0,
-    16,
-    32,
-    48,
-    64,
-    80,
-    96,
-    112,
-    128,
-    144,
-    160,
-    176,
-    192,
-    208,
-    224,
-    240,
-    256,
-    272,
-    288,
-    304,
-    320,
-    336,
-    352,
-    368,
-    384,
-    400,
-    416,
-    432,
-    448,
-    464,
-    480,
-    496,
-    512,
-    528,
-    544,
-    560,
-    576,
-    592,
-    608,
-    624,
-    640,
-    656,
-    672,
-    688,
-    704,
-    720,
-    736,
-    752,
-    768,
-    784,
-    800,
-    816,
-    832,
-    848,
-    864,
-    880,
-    896,
-    912,
-    928,
-    944,
-    960,
-    976
-  ],
-  "features": [
-    {
-      "name": "RevealElement_position",
-      "type": "dpOffset",
-      "data_points": [
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50.8,
-          "y": 52
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 52.4,
-          "y": 50
-        },
-        {
-          "x": 55.6,
-          "y": 50
-        },
-        {
-          "x": 58.4,
-          "y": 50
-        },
-        {
-          "x": 60.4,
-          "y": 50
-        },
-        {
-          "x": 61.6,
-          "y": 50
-        },
-        {
-          "x": 62.8,
-          "y": 50
-        },
-        {
-          "x": 63.2,
-          "y": 50
-        },
-        {
-          "x": 63.6,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_size",
-      "type": "dpSize",
-      "data_points": [
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 390
-        },
-        {
-          "width": 188,
-          "height": 390
-        },
-        {
-          "width": 188,
-          "height": 379.2
-        },
-        {
-          "width": 188,
-          "height": 371.2
-        },
-        {
-          "width": 188,
-          "height": 363.2
-        },
-        {
-          "width": 188,
-          "height": 355.2
-        },
-        {
-          "width": 188,
-          "height": 347.2
-        },
-        {
-          "width": 188,
-          "height": 339.2
-        },
-        {
-          "width": 188,
-          "height": 331.2
-        },
-        {
-          "width": 188,
-          "height": 323.2
-        },
-        {
-          "width": 188,
-          "height": 323.2
-        },
-        {
-          "width": 188,
-          "height": 314.8
-        },
-        {
-          "width": 188,
-          "height": 306.8
-        },
-        {
-          "width": 188,
-          "height": 298.8
-        },
-        {
-          "width": 188,
-          "height": 290.8
-        },
-        {
-          "width": 188,
-          "height": 282.8
-        },
-        {
-          "width": 188,
-          "height": 274.8
-        },
-        {
-          "width": 188,
-          "height": 266.8
-        },
-        {
-          "width": 188,
-          "height": 258.8
-        },
-        {
-          "width": 188,
-          "height": 258.8
-        },
-        {
-          "width": 188,
-          "height": 250.4
-        },
-        {
-          "width": 188,
-          "height": 242.4
-        },
-        {
-          "width": 188,
-          "height": 234.4
-        },
-        {
-          "width": 188,
-          "height": 226.4
-        },
-        {
-          "width": 188,
-          "height": 218.4
-        },
-        {
-          "width": 188,
-          "height": 210.4
-        },
-        {
-          "width": 188,
-          "height": 202.4
-        },
-        {
-          "width": 188,
-          "height": 194.4
-        },
-        {
-          "width": 188,
-          "height": 194.4
-        },
-        {
-          "width": 188,
-          "height": 185.6
-        },
-        {
-          "width": 188,
-          "height": 178
-        },
-        {
-          "width": 188,
-          "height": 170
-        },
-        {
-          "width": 188,
-          "height": 161.6
-        },
-        {
-          "width": 188,
-          "height": 161.6
-        },
-        {
-          "width": 188,
-          "height": 144.8
-        },
-        {
-          "width": 188,
-          "height": 118.8
-        },
-        {
-          "width": 188,
-          "height": 92
-        },
-        {
-          "width": 183.6,
-          "height": 68
-        },
-        {
-          "width": 176.8,
-          "height": 48.4
-        },
-        {
-          "width": 171.6,
-          "height": 32
-        },
-        {
-          "width": 167.6,
-          "height": 18
-        },
-        {
-          "width": 164.8,
-          "height": 8.8
-        },
-        {
-          "width": 162.8,
-          "height": 2.8
-        },
-        {
-          "width": 161.6,
-          "height": 0
-        },
-        {
-          "width": 160.8,
-          "height": 0
-        },
-        {
-          "width": 160.4,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_alpha",
-      "type": "float",
-      "data_points": [
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        0.9967737,
-        0.86538374,
-        0.66414475,
-        0.47619528,
-        0.32686388,
-        0.21757984,
-        0.14153665,
-        0.09041709,
-        0.05691254,
-        0.035380244,
-        0.02175957,
-        0.01325649,
-        0.008007765,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragOpen.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragOpen.json
deleted file mode 100644
index b6e423a..0000000
--- a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_dragOpen.json
+++ /dev/null
@@ -1,544 +0,0 @@
-{
-  "frame_ids": [
-    0,
-    16,
-    32,
-    48,
-    64,
-    80,
-    96,
-    112,
-    128,
-    144,
-    160,
-    176,
-    192,
-    208,
-    224,
-    240,
-    256,
-    272,
-    288,
-    304,
-    320,
-    336,
-    352,
-    368,
-    384,
-    400,
-    416,
-    432,
-    448,
-    464,
-    480,
-    496,
-    512,
-    528,
-    544,
-    560,
-    576,
-    592,
-    608,
-    624,
-    640,
-    656,
-    672,
-    688,
-    704,
-    720,
-    736,
-    752,
-    768,
-    784,
-    800,
-    816
-  ],
-  "features": [
-    {
-      "name": "RevealElement_position",
-      "type": "dpOffset",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "x": 62.8,
-          "y": 50
-        },
-        {
-          "x": 62.8,
-          "y": 50
-        },
-        {
-          "x": 61.6,
-          "y": 50
-        },
-        {
-          "x": 60.8,
-          "y": 50
-        },
-        {
-          "x": 59.6,
-          "y": 50
-        },
-        {
-          "x": 58.4,
-          "y": 50
-        },
-        {
-          "x": 57.2,
-          "y": 50
-        },
-        {
-          "x": 56,
-          "y": 50
-        },
-        {
-          "x": 55.2,
-          "y": 50
-        },
-        {
-          "x": 54,
-          "y": 50
-        },
-        {
-          "x": 54,
-          "y": 50
-        },
-        {
-          "x": 52.8,
-          "y": 50
-        },
-        {
-          "x": 51.6,
-          "y": 50
-        },
-        {
-          "x": 50.4,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_size",
-      "type": "dpSize",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "width": 162.4,
-          "height": 1.6
-        },
-        {
-          "width": 162.4,
-          "height": 1.6
-        },
-        {
-          "width": 164.8,
-          "height": 3.2
-        },
-        {
-          "width": 166.8,
-          "height": 4.8
-        },
-        {
-          "width": 169.2,
-          "height": 6.4
-        },
-        {
-          "width": 171.6,
-          "height": 8
-        },
-        {
-          "width": 173.6,
-          "height": 9.6
-        },
-        {
-          "width": 176,
-          "height": 11.2
-        },
-        {
-          "width": 178,
-          "height": 12.8
-        },
-        {
-          "width": 180.4,
-          "height": 14.4
-        },
-        {
-          "width": 180.4,
-          "height": 14.4
-        },
-        {
-          "width": 182.8,
-          "height": 16.4
-        },
-        {
-          "width": 185.2,
-          "height": 18
-        },
-        {
-          "width": 187.2,
-          "height": 19.6
-        },
-        {
-          "width": 188,
-          "height": 25.6
-        },
-        {
-          "width": 188,
-          "height": 36.4
-        },
-        {
-          "width": 188,
-          "height": 45.6
-        },
-        {
-          "width": 188,
-          "height": 59.2
-        },
-        {
-          "width": 188,
-          "height": 72.8
-        },
-        {
-          "width": 188,
-          "height": 79.6
-        },
-        {
-          "width": 188,
-          "height": 92.8
-        },
-        {
-          "width": 188,
-          "height": 104.4
-        },
-        {
-          "width": 188,
-          "height": 115.2
-        },
-        {
-          "width": 188,
-          "height": 125.2
-        },
-        {
-          "width": 188,
-          "height": 134.8
-        },
-        {
-          "width": 188,
-          "height": 143.2
-        },
-        {
-          "width": 188,
-          "height": 151.2
-        },
-        {
-          "width": 188,
-          "height": 158.8
-        },
-        {
-          "width": 188,
-          "height": 160
-        },
-        {
-          "width": 188,
-          "height": 167.2
-        },
-        {
-          "width": 188,
-          "height": 174.4
-        },
-        {
-          "width": 188,
-          "height": 180.8
-        },
-        {
-          "width": 188,
-          "height": 187.6
-        },
-        {
-          "width": 188,
-          "height": 188
-        },
-        {
-          "width": 188,
-          "height": 207.2
-        },
-        {
-          "width": 188,
-          "height": 240
-        },
-        {
-          "width": 188,
-          "height": 275.2
-        },
-        {
-          "width": 188,
-          "height": 306.8
-        },
-        {
-          "width": 188,
-          "height": 333.2
-        },
-        {
-          "width": 188,
-          "height": 353.6
-        },
-        {
-          "width": 188,
-          "height": 368.8
-        },
-        {
-          "width": 188,
-          "height": 380
-        },
-        {
-          "width": 188,
-          "height": 387.6
-        },
-        {
-          "width": 188,
-          "height": 392.4
-        },
-        {
-          "width": 188,
-          "height": 395.6
-        },
-        {
-          "width": 188,
-          "height": 398
-        },
-        {
-          "width": 188,
-          "height": 398.8
-        },
-        {
-          "width": 188,
-          "height": 399.6
-        },
-        {
-          "width": 188,
-          "height": 400
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_alpha",
-      "type": "float",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        0,
-        0,
-        0,
-        0,
-        0.0067873597,
-        0.0612576,
-        0.19080025,
-        0.39327443,
-        0.5711931,
-        0.70855826,
-        0.8074064,
-        0.8754226,
-        0.9207788,
-        0.95032376,
-        0.9692185,
-        0.98112255,
-        0.9885286,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingClose.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingClose.json
deleted file mode 100644
index a82db34..0000000
--- a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_flingClose.json
+++ /dev/null
@@ -1,444 +0,0 @@
-{
-  "frame_ids": [
-    0,
-    16,
-    32,
-    48,
-    64,
-    80,
-    96,
-    112,
-    128,
-    144,
-    160,
-    176,
-    192,
-    208,
-    224,
-    240,
-    256,
-    272,
-    288,
-    304,
-    320,
-    336,
-    352,
-    368,
-    384,
-    400,
-    416,
-    432,
-    448,
-    464,
-    480,
-    496,
-    512,
-    528,
-    544,
-    560,
-    576,
-    592,
-    608,
-    624,
-    640,
-    656
-  ],
-  "features": [
-    {
-      "name": "RevealElement_position",
-      "type": "dpOffset",
-      "data_points": [
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50.4,
-          "y": 50.8
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 51.2,
-          "y": 50
-        },
-        {
-          "x": 55.6,
-          "y": 50
-        },
-        {
-          "x": 58.8,
-          "y": 50
-        },
-        {
-          "x": 60.8,
-          "y": 50
-        },
-        {
-          "x": 62,
-          "y": 50
-        },
-        {
-          "x": 63.2,
-          "y": 50
-        },
-        {
-          "x": 63.6,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_size",
-      "type": "dpSize",
-      "data_points": [
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 389.6
-        },
-        {
-          "width": 188,
-          "height": 378.8
-        },
-        {
-          "width": 188,
-          "height": 366
-        },
-        {
-          "width": 188,
-          "height": 352
-        },
-        {
-          "width": 188,
-          "height": 352
-        },
-        {
-          "width": 188,
-          "height": 316.8
-        },
-        {
-          "width": 188,
-          "height": 261.2
-        },
-        {
-          "width": 188,
-          "height": 202.8
-        },
-        {
-          "width": 188,
-          "height": 150.8
-        },
-        {
-          "width": 188,
-          "height": 107.6
-        },
-        {
-          "width": 186,
-          "height": 74.4
-        },
-        {
-          "width": 177.2,
-          "height": 49.6
-        },
-        {
-          "width": 170.8,
-          "height": 29.6
-        },
-        {
-          "width": 166.8,
-          "height": 12.8
-        },
-        {
-          "width": 164,
-          "height": 2.4
-        },
-        {
-          "width": 162,
-          "height": 0
-        },
-        {
-          "width": 160.8,
-          "height": 0
-        },
-        {
-          "width": 160.4,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_alpha",
-      "type": "float",
-      "data_points": [
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        0.9833227,
-        0.8263634,
-        0.623688,
-        0.44261706,
-        0.3016883,
-        0.1997872,
-        0.12944388,
-        0.08242595,
-        0.051743627,
-        0.032093227,
-        0.019698441,
-        0.0119793415,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_magneticDetachAndReattach.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_magneticDetachAndReattach.json
deleted file mode 100644
index 1cd971a..0000000
--- a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_gesture_magneticDetachAndReattach.json
+++ /dev/null
@@ -1,724 +0,0 @@
-{
-  "frame_ids": [
-    0,
-    16,
-    32,
-    48,
-    64,
-    80,
-    96,
-    112,
-    128,
-    144,
-    160,
-    176,
-    192,
-    208,
-    224,
-    240,
-    256,
-    272,
-    288,
-    304,
-    320,
-    336,
-    352,
-    368,
-    384,
-    400,
-    416,
-    432,
-    448,
-    464,
-    480,
-    496,
-    512,
-    528,
-    544,
-    560,
-    576,
-    592,
-    608,
-    624,
-    640,
-    656,
-    672,
-    688,
-    704,
-    720,
-    736,
-    752,
-    768,
-    784,
-    800,
-    816,
-    832,
-    848,
-    864,
-    880,
-    896,
-    912,
-    928,
-    944,
-    960,
-    976,
-    992,
-    1008,
-    1024,
-    1040,
-    1056,
-    1072,
-    1088,
-    1104
-  ],
-  "features": [
-    {
-      "name": "RevealElement_position",
-      "type": "dpOffset",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "x": 62.8,
-          "y": 50
-        },
-        {
-          "x": 62,
-          "y": 50
-        },
-        {
-          "x": 61.2,
-          "y": 50
-        },
-        {
-          "x": 60.4,
-          "y": 50
-        },
-        {
-          "x": 59.6,
-          "y": 50
-        },
-        {
-          "x": 58.8,
-          "y": 50
-        },
-        {
-          "x": 58,
-          "y": 50
-        },
-        {
-          "x": 57.2,
-          "y": 50
-        },
-        {
-          "x": 56.4,
-          "y": 50
-        },
-        {
-          "x": 55.6,
-          "y": 50
-        },
-        {
-          "x": 55.2,
-          "y": 50
-        },
-        {
-          "x": 54.4,
-          "y": 50
-        },
-        {
-          "x": 53.6,
-          "y": 50
-        },
-        {
-          "x": 53.2,
-          "y": 50
-        },
-        {
-          "x": 52.8,
-          "y": 50
-        },
-        {
-          "x": 52,
-          "y": 50
-        },
-        {
-          "x": 51.6,
-          "y": 50
-        },
-        {
-          "x": 51.2,
-          "y": 50
-        },
-        {
-          "x": 50.8,
-          "y": 50
-        },
-        {
-          "x": 50.4,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50.4,
-          "y": 50
-        },
-        {
-          "x": 50.8,
-          "y": 50
-        },
-        {
-          "x": 51.2,
-          "y": 50
-        },
-        {
-          "x": 51.6,
-          "y": 50
-        },
-        {
-          "x": 52,
-          "y": 50
-        },
-        {
-          "x": 52.8,
-          "y": 50
-        },
-        {
-          "x": 53.2,
-          "y": 50
-        },
-        {
-          "x": 53.6,
-          "y": 50
-        },
-        {
-          "x": 54.4,
-          "y": 50
-        },
-        {
-          "x": 55.2,
-          "y": 50
-        },
-        {
-          "x": 55.6,
-          "y": 50
-        },
-        {
-          "x": 56.4,
-          "y": 50
-        },
-        {
-          "x": 57.2,
-          "y": 50
-        },
-        {
-          "x": 58,
-          "y": 50
-        },
-        {
-          "x": 58.8,
-          "y": 50
-        },
-        {
-          "x": 59.6,
-          "y": 50
-        },
-        {
-          "x": 60.4,
-          "y": 50
-        },
-        {
-          "x": 61.2,
-          "y": 50
-        },
-        {
-          "x": 62,
-          "y": 50
-        },
-        {
-          "x": 62.8,
-          "y": 50
-        },
-        {
-          "x": 63.6,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_size",
-      "type": "dpSize",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "width": 162.4,
-          "height": 1.6
-        },
-        {
-          "width": 164,
-          "height": 2.8
-        },
-        {
-          "width": 166,
-          "height": 4
-        },
-        {
-          "width": 167.6,
-          "height": 5.2
-        },
-        {
-          "width": 169.2,
-          "height": 6.4
-        },
-        {
-          "width": 170.8,
-          "height": 7.6
-        },
-        {
-          "width": 172.4,
-          "height": 8.8
-        },
-        {
-          "width": 174,
-          "height": 10
-        },
-        {
-          "width": 175.2,
-          "height": 10.8
-        },
-        {
-          "width": 176.8,
-          "height": 12
-        },
-        {
-          "width": 178,
-          "height": 12.8
-        },
-        {
-          "width": 179.2,
-          "height": 13.6
-        },
-        {
-          "width": 180.8,
-          "height": 14.8
-        },
-        {
-          "width": 182,
-          "height": 15.6
-        },
-        {
-          "width": 182.8,
-          "height": 16.4
-        },
-        {
-          "width": 184,
-          "height": 17.2
-        },
-        {
-          "width": 184.8,
-          "height": 17.6
-        },
-        {
-          "width": 186,
-          "height": 18.4
-        },
-        {
-          "width": 186.8,
-          "height": 19.2
-        },
-        {
-          "width": 187.6,
-          "height": 19.6
-        },
-        {
-          "width": 188,
-          "height": 21.2
-        },
-        {
-          "width": 188,
-          "height": 24.8
-        },
-        {
-          "width": 188,
-          "height": 30
-        },
-        {
-          "width": 188,
-          "height": 38
-        },
-        {
-          "width": 188,
-          "height": 46
-        },
-        {
-          "width": 188,
-          "height": 54
-        },
-        {
-          "width": 188,
-          "height": 61.2
-        },
-        {
-          "width": 188,
-          "height": 66.8
-        },
-        {
-          "width": 188,
-          "height": 71.6
-        },
-        {
-          "width": 188,
-          "height": 75.6
-        },
-        {
-          "width": 188,
-          "height": 78
-        },
-        {
-          "width": 188,
-          "height": 79.6
-        },
-        {
-          "width": 188,
-          "height": 80.8
-        },
-        {
-          "width": 188,
-          "height": 80.8
-        },
-        {
-          "width": 188,
-          "height": 80.4
-        },
-        {
-          "width": 188,
-          "height": 79.6
-        },
-        {
-          "width": 187.6,
-          "height": 78
-        },
-        {
-          "width": 186.8,
-          "height": 76.4
-        },
-        {
-          "width": 186,
-          "height": 74
-        },
-        {
-          "width": 184.8,
-          "height": 71.6
-        },
-        {
-          "width": 184,
-          "height": 69.2
-        },
-        {
-          "width": 182.8,
-          "height": 66
-        },
-        {
-          "width": 182,
-          "height": 62.8
-        },
-        {
-          "width": 180.8,
-          "height": 59.2
-        },
-        {
-          "width": 179.2,
-          "height": 55.6
-        },
-        {
-          "width": 178,
-          "height": 52
-        },
-        {
-          "width": 176.8,
-          "height": 48
-        },
-        {
-          "width": 175.2,
-          "height": 44
-        },
-        {
-          "width": 174,
-          "height": 40
-        },
-        {
-          "width": 172.4,
-          "height": 37.6
-        },
-        {
-          "width": 170.8,
-          "height": 38
-        },
-        {
-          "width": 169.2,
-          "height": 30.4
-        },
-        {
-          "width": 167.6,
-          "height": 25.2
-        },
-        {
-          "width": 166,
-          "height": 20.4
-        },
-        {
-          "width": 164,
-          "height": 16
-        },
-        {
-          "width": 162.4,
-          "height": 12.4
-        },
-        {
-          "width": 160.8,
-          "height": 9.2
-        },
-        {
-          "width": 160,
-          "height": 6.8
-        },
-        {
-          "width": 160,
-          "height": 5.2
-        },
-        {
-          "width": 160,
-          "height": 3.6
-        },
-        {
-          "width": 160,
-          "height": 2.4
-        },
-        {
-          "width": 160,
-          "height": 1.6
-        },
-        {
-          "width": 160,
-          "height": 0.8
-        },
-        {
-          "width": 160,
-          "height": 0.4
-        },
-        {
-          "width": 160,
-          "height": 0.4
-        },
-        {
-          "width": 160,
-          "height": 0
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_alpha",
-      "type": "float",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        {
-          "type": "not_found"
-        },
-        0,
-        0,
-        0,
-        0,
-        0.012518823,
-        0.0741024,
-        0.2254293,
-        0.42628878,
-        0.5976641,
-        0.7280312,
-        0.82100236,
-        0.8845844,
-        0.9267946,
-        0.95419544,
-        0.9716705,
-        0.98265487,
-        0.98947525,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        0.9944124,
-        0.9417388,
-        0.8184184,
-        0.6157812,
-        0.4361611,
-        0.2968906,
-        0.19641554,
-        0.12716137,
-        0.080921985,
-        0.050773025,
-        0.03147719,
-        0.019312752,
-        0.011740655,
-        0
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealCloseTransition.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealCloseTransition.json
deleted file mode 100644
index 1030455..0000000
--- a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealCloseTransition.json
+++ /dev/null
@@ -1,324 +0,0 @@
-{
-  "frame_ids": [
-    0,
-    16,
-    32,
-    48,
-    64,
-    80,
-    96,
-    112,
-    128,
-    144,
-    160,
-    176,
-    192,
-    208,
-    224,
-    240,
-    256,
-    272,
-    288,
-    304,
-    320,
-    336,
-    352,
-    368,
-    384,
-    400,
-    416,
-    432,
-    448,
-    464
-  ],
-  "features": [
-    {
-      "name": "RevealElement_position",
-      "type": "dpOffset",
-      "data_points": [
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 53.2,
-          "y": 50
-        },
-        {
-          "x": 57.2,
-          "y": 50
-        },
-        {
-          "x": 59.6,
-          "y": 50
-        },
-        {
-          "x": 61.6,
-          "y": 50
-        },
-        {
-          "x": 62.8,
-          "y": 50
-        },
-        {
-          "x": 63.6,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 64,
-          "y": 50
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_size",
-      "type": "dpSize",
-      "data_points": [
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 400
-        },
-        {
-          "width": 188,
-          "height": 372
-        },
-        {
-          "width": 188,
-          "height": 312.8
-        },
-        {
-          "width": 188,
-          "height": 246.8
-        },
-        {
-          "width": 188,
-          "height": 185.2
-        },
-        {
-          "width": 188,
-          "height": 133.6
-        },
-        {
-          "width": 188,
-          "height": 93.2
-        },
-        {
-          "width": 181.6,
-          "height": 62.8
-        },
-        {
-          "width": 174,
-          "height": 40.8
-        },
-        {
-          "width": 168.8,
-          "height": 22.4
-        },
-        {
-          "width": 165.2,
-          "height": 10
-        },
-        {
-          "width": 162.8,
-          "height": 2.4
-        },
-        {
-          "width": 161.2,
-          "height": 0
-        },
-        {
-          "width": 160.4,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 160,
-          "height": 0
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_alpha",
-      "type": "float",
-      "data_points": [
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        0.91758585,
-        0.72435355,
-        0.52812576,
-        0.3665868,
-        0.24600428,
-        0.16102076,
-        0.103373945,
-        0.06533456,
-        0.04075712,
-        0.025142312,
-        0.015358448,
-        0.0092999935,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealOpenTransition.json b/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealOpenTransition.json
deleted file mode 100644
index 622c29e..0000000
--- a/packages/SystemUI/compose/scene/tests/goldens/verticalReveal_triggeredRevealOpenTransition.json
+++ /dev/null
@@ -1,244 +0,0 @@
-{
-  "frame_ids": [
-    0,
-    16,
-    32,
-    48,
-    64,
-    80,
-    96,
-    112,
-    128,
-    144,
-    160,
-    176,
-    192,
-    208,
-    224,
-    240,
-    256,
-    272,
-    288,
-    304,
-    320,
-    336
-  ],
-  "features": [
-    {
-      "name": "RevealElement_position",
-      "type": "dpOffset",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        {
-          "x": 64,
-          "y": 50
-        },
-        {
-          "x": 59.2,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        },
-        {
-          "x": 50,
-          "y": 50
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_size",
-      "type": "dpSize",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        {
-          "width": 160,
-          "height": 0
-        },
-        {
-          "width": 169.6,
-          "height": 6.8
-        },
-        {
-          "width": 188,
-          "height": 26.8
-        },
-        {
-          "width": 188,
-          "height": 95.6
-        },
-        {
-          "width": 188,
-          "height": 163.2
-        },
-        {
-          "width": 188,
-          "height": 222
-        },
-        {
-          "width": 188,
-          "height": 269.6
-        },
-        {
-          "width": 188,
-          "height": 307.2
-        },
-        {
-          "width": 188,
-          "height": 335.2
-        },
-        {
-          "width": 188,
-          "height": 356
-        },
-        {
-          "width": 188,
-          "height": 370.4
-        },
-        {
-          "width": 188,
-          "height": 380.8
-        },
-        {
-          "width": 188,
-          "height": 387.6
-        },
-        {
-          "width": 188,
-          "height": 392.4
-        },
-        {
-          "width": 188,
-          "height": 395.2
-        },
-        {
-          "width": 188,
-          "height": 397.2
-        },
-        {
-          "width": 188,
-          "height": 398
-        },
-        {
-          "width": 188,
-          "height": 398.8
-        },
-        {
-          "width": 188,
-          "height": 399.2
-        },
-        {
-          "width": 188,
-          "height": 399.2
-        },
-        {
-          "width": 188,
-          "height": 399.6
-        }
-      ]
-    },
-    {
-      "name": "RevealElement_alpha",
-      "type": "float",
-      "data_points": [
-        {
-          "type": "not_found"
-        },
-        0,
-        0.05698657,
-        0.24197984,
-        0.44158113,
-        0.6097554,
-        0.73685503,
-        0.8271309,
-        0.8886989,
-        0.9294886,
-        0.9559254,
-        0.97276413,
-        0.98333716,
-        0.98989624,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1,
-        1
-      ]
-    }
-  ]
-}
\ No newline at end of file
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt
index f4e2328..1bc83e0 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/reveal/ContentRevealTest.kt
@@ -37,7 +37,6 @@
 import androidx.compose.ui.test.swipeWithVelocity
 import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
-import androidx.test.ext.junit.runners.AndroidJUnit4
 import com.android.compose.animation.scene.ContentScope
 import com.android.compose.animation.scene.ElementKey
 import com.android.compose.animation.scene.FeatureCaptures.elementAlpha
@@ -47,8 +46,8 @@
 import com.android.compose.animation.scene.Swipe
 import com.android.compose.animation.scene.featureOfElement
 import com.android.compose.animation.scene.transitions
-import com.android.mechanics.behavior.EdgeContainerExpansionSpec
-import com.android.mechanics.behavior.edgeContainerExpansionBackground
+import com.android.mechanics.behavior.VerticalExpandContainerSpec
+import com.android.mechanics.behavior.verticalExpandContainerBackground
 import kotlin.math.sin
 import kotlinx.coroutines.CoroutineScope
 import org.junit.Rule
@@ -63,26 +62,48 @@
 import platform.test.motion.compose.recordMotion
 import platform.test.motion.compose.runTest
 import platform.test.motion.testing.createGoldenPathManager
+import platform.test.runner.parameterized.ParameterizedAndroidJunit4
+import platform.test.runner.parameterized.Parameters
+import platform.test.screenshot.PathConfig
+import platform.test.screenshot.PathElementNoContext
 
-@RunWith(AndroidJUnit4::class)
 @MotionTest
-class ContentRevealTest {
+@RunWith(ParameterizedAndroidJunit4::class)
+class ContentRevealTest(private val isFloating: Boolean) {
+
+    private val pathConfig =
+        PathConfig(
+            PathElementNoContext("floating", isDir = false) {
+                if (isFloating) "floating" else "edge"
+            }
+        )
 
     private val goldenPaths =
-        createGoldenPathManager("frameworks/base/packages/SystemUI/compose/scene/tests/goldens")
+        createGoldenPathManager(
+            "frameworks/base/packages/SystemUI/compose/scene/tests/goldens",
+            pathConfig,
+        )
 
     @get:Rule val motionRule = createFixedConfigurationComposeMotionTestRule(goldenPaths)
 
     private val fakeHaptics = FakeHaptics()
 
+    private val motionSpec = VerticalExpandContainerSpec(isFloating)
+
     @Test
     fun verticalReveal_triggeredRevealOpenTransition() {
-        assertVerticalContainerRevealMotion(TriggeredRevealMotion(SceneClosed, SceneOpen))
+        assertVerticalContainerRevealMotion(
+            TriggeredRevealMotion(SceneClosed, SceneOpen),
+            "verticalReveal_triggeredRevealOpenTransition",
+        )
     }
 
     @Test
     fun verticalReveal_triggeredRevealCloseTransition() {
-        assertVerticalContainerRevealMotion(TriggeredRevealMotion(SceneOpen, SceneClosed))
+        assertVerticalContainerRevealMotion(
+            TriggeredRevealMotion(SceneOpen, SceneClosed),
+            "verticalReveal_triggeredRevealCloseTransition",
+        )
     }
 
     @Test
@@ -90,15 +111,18 @@
         assertVerticalContainerRevealMotion(
             GestureRevealMotion(SceneClosed) {
                 val gestureDurationMillis = 1000L
+                // detach position for the floating container is larger
+                val gestureHeight = if (isFloating) 160.dp.toPx() else 100.dp.toPx()
                 swipe(
                     curve = {
                         val progress = it / gestureDurationMillis.toFloat()
-                        val y = sin(progress * Math.PI).toFloat() * 100.dp.toPx()
+                        val y = sin(progress * Math.PI).toFloat() * gestureHeight
                         Offset(centerX, y)
                     },
                     gestureDurationMillis,
                 )
-            }
+            },
+            "verticalReveal_gesture_magneticDetachAndReattach",
         )
     }
 
@@ -107,7 +131,8 @@
         assertVerticalContainerRevealMotion(
             GestureRevealMotion(SceneClosed) {
                 swipeDown(endY = 200.dp.toPx(), durationMillis = 500)
-            }
+            },
+            "verticalReveal_gesture_dragOpen",
         )
     }
 
@@ -117,7 +142,8 @@
             GestureRevealMotion(SceneClosed) {
                 val end = Offset(centerX, 80.dp.toPx())
                 swipeWithVelocity(start = topCenter, end = end, endVelocity = FlingVelocity.toPx())
-            }
+            },
+            "verticalReveal_gesture_flingOpen",
         )
     }
 
@@ -126,7 +152,8 @@
         assertVerticalContainerRevealMotion(
             GestureRevealMotion(SceneOpen) {
                 swipeUp(200.dp.toPx(), 0.dp.toPx(), durationMillis = 500)
-            }
+            },
+            "verticalReveal_gesture_dragFullyClose",
         )
     }
 
@@ -134,8 +161,9 @@
     fun verticalReveal_gesture_dragHalfClose() {
         assertVerticalContainerRevealMotion(
             GestureRevealMotion(SceneOpen) {
-                swipeUp(350.dp.toPx(), 100.dp.toPx(), durationMillis = 500)
-            }
+                swipeUp(250.dp.toPx(), 100.dp.toPx(), durationMillis = 500)
+            },
+            "verticalReveal_gesture_dragHalfClose",
         )
     }
 
@@ -146,7 +174,8 @@
                 val start = Offset(centerX, 260.dp.toPx())
                 val end = Offset(centerX, 200.dp.toPx())
                 swipeWithVelocity(start, end, FlingVelocity.toPx())
-            }
+            },
+            "verticalReveal_gesture_flingClose",
         )
     }
 
@@ -164,11 +193,14 @@
         val gestureControl: TouchInjectionScope.() -> Unit,
     ) : RevealMotion
 
-    private fun assertVerticalContainerRevealMotion(testInstructions: RevealMotion) =
+    private fun assertVerticalContainerRevealMotion(
+        testInstructions: RevealMotion,
+        goldenName: String,
+    ) =
         motionRule.runTest {
             val transitions = transitions {
                 from(SceneClosed, to = SceneOpen) {
-                    verticalContainerReveal(RevealElement, MotionSpec, fakeHaptics)
+                    verticalContainerReveal(RevealElement, motionSpec, fakeHaptics)
                 }
             }
 
@@ -221,9 +253,9 @@
                         SceneTransitionLayoutForTesting(
                             state,
                             modifier =
-                                Modifier.padding(50.dp)
+                                Modifier.padding(5.dp)
                                     .background(Color.Yellow)
-                                    .size(ContainerSize.width, ContainerSize.height + 200.dp)
+                                    .size(ContainerSize.width, ContainerSize.height + 100.dp)
                                     .testTag("stl"),
                         ) {
                             scene(
@@ -241,7 +273,7 @@
                     recordingSpec,
                 )
 
-            assertThat(motion).timeSeriesMatchesGolden()
+            assertThat(motion).timeSeriesMatchesGolden(goldenName)
         }
 
     @Composable
@@ -256,7 +288,7 @@
                 modifier =
                     Modifier.element(RevealElement)
                         .size(ContainerSize)
-                        .edgeContainerExpansionBackground(Color.DarkGray, MotionSpec)
+                        .verticalExpandContainerBackground(Color.DarkGray, motionSpec)
             )
         }
     }
@@ -266,7 +298,9 @@
     }
 
     companion object {
-        val ContainerSize = DpSize(200.dp, 400.dp)
+        @get:Parameters @JvmStatic val parameterValues = listOf(true, false)
+
+        val ContainerSize = DpSize(150.dp, 300.dp)
 
         val FlingVelocity = 1000.dp // dp/sec
 
@@ -274,6 +308,5 @@
         val SceneOpen = SceneKey("SceneB")
 
         val RevealElement = ElementKey("RevealElement")
-        val MotionSpec = EdgeContainerExpansionSpec()
     }
 }
diff --git a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/testing/ElementStateAccessTest.kt b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/testing/ElementStateAccessTest.kt
index e4a87ba..7d9a32b 100644
--- a/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/testing/ElementStateAccessTest.kt
+++ b/packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/testing/ElementStateAccessTest.kt
@@ -58,17 +58,24 @@
                 assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(1f, 1f))
             }
 
+            at(16) {
+                val semanticNode = onElement(TestElements.Foo).fetchSemanticsNode()
+                assertThat(semanticNode.lastAlphaForTesting).isEqualTo(0.75f)
+                assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(0.75f, 0.75f))
+            }
+
             at(32) {
                 val semanticNode = onElement(TestElements.Foo).fetchSemanticsNode()
                 assertThat(semanticNode.lastAlphaForTesting).isEqualTo(0.5f)
                 assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(0.5f, 0.5f))
             }
 
-            at(64) {
+            at(48) {
                 val semanticNode = onElement(TestElements.Foo).fetchSemanticsNode()
-                assertThat(semanticNode.lastAlphaForTesting).isEqualTo(0f)
-                assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(0f, 0f))
+                assertThat(semanticNode.lastAlphaForTesting).isEqualTo(0.25f)
+                assertThat(semanticNode.lastScaleForTesting).isEqualTo(Scale(0.25f, 0.25f))
             }
+
             after { onElement(TestElements.Foo).assertDoesNotExist() }
         }
     }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
index 37acbe2..5f71b19 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ComposedDigitalLayerController.kt
@@ -22,10 +22,10 @@
 import com.android.systemui.log.core.Logger
 import com.android.systemui.plugins.clocks.AlarmData
 import com.android.systemui.plugins.clocks.ClockAnimations
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockEvents
 import com.android.systemui.plugins.clocks.ClockFaceConfig
 import com.android.systemui.plugins.clocks.ClockFaceEvents
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
 import com.android.systemui.plugins.clocks.ThemeConfig
 import com.android.systemui.plugins.clocks.WeatherData
 import com.android.systemui.plugins.clocks.ZenData
@@ -111,7 +111,7 @@
 
             override fun onZenDataChanged(data: ZenData) {}
 
-            override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) {
+            override fun onFontAxesChanged(axes: ClockAxisStyle) {
                 view.updateAxes(axes)
             }
 
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
index bc4bdf4..3cfa78d 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockController.kt
@@ -26,6 +26,7 @@
 import com.android.systemui.log.core.MessageBuffer
 import com.android.systemui.plugins.clocks.AlarmData
 import com.android.systemui.plugins.clocks.ClockAnimations
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockConfig
 import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.plugins.clocks.ClockEventListener
@@ -33,7 +34,6 @@
 import com.android.systemui.plugins.clocks.ClockFaceConfig
 import com.android.systemui.plugins.clocks.ClockFaceController
 import com.android.systemui.plugins.clocks.ClockFaceEvents
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
 import com.android.systemui.plugins.clocks.ClockMessageBuffers
 import com.android.systemui.plugins.clocks.ClockSettings
 import com.android.systemui.plugins.clocks.DefaultClockFaceLayout
@@ -232,7 +232,7 @@
 
         override fun onZenDataChanged(data: ZenData) {}
 
-        override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) {}
+        override fun onFontAxesChanged(axes: ClockAxisStyle) {}
     }
 
     open inner class DefaultClockAnimations(
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
index c3935e6..d778bc0 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
@@ -20,6 +20,8 @@
 import android.view.LayoutInflater
 import com.android.systemui.customization.R
 import com.android.systemui.log.core.MessageBuffer
+import com.android.systemui.plugins.clocks.AxisPresetConfig
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge
 import com.android.systemui.plugins.clocks.ClockLogger
@@ -28,7 +30,7 @@
 import com.android.systemui.plugins.clocks.ClockPickerConfig
 import com.android.systemui.plugins.clocks.ClockProvider
 import com.android.systemui.plugins.clocks.ClockSettings
-import com.android.systemui.shared.clocks.FlexClockController.Companion.AXIS_PRESETS
+import com.android.systemui.shared.clocks.FlexClockController.Companion.buildPresetGroup
 import com.android.systemui.shared.clocks.FlexClockController.Companion.getDefaultAxes
 
 private val TAG = DefaultClockProvider::class.simpleName
@@ -80,7 +82,7 @@
         return if (isClockReactiveVariantsEnabled) {
             val buffers = messageBuffers ?: ClockMessageBuffers(ClockLogger.DEFAULT_MESSAGE_BUFFER)
             val fontAxes = getDefaultAxes(settings).merge(settings.axes)
-            val clockSettings = settings.copy(axes = fontAxes.map { it.toSetting() })
+            val clockSettings = settings.copy(axes = ClockAxisStyle(fontAxes))
             val typefaceCache =
                 TypefaceCache(buffers.infraMessageBuffer, NUM_CLOCK_FONT_ANIMATION_STEPS) {
                     FLEX_TYPEFACE
@@ -106,17 +108,35 @@
             throw IllegalArgumentException("${settings.clockId} is unsupported by $TAG")
         }
 
-        return ClockPickerConfig(
-            settings.clockId ?: DEFAULT_CLOCK_ID,
-            resources.getString(R.string.clock_default_name),
-            resources.getString(R.string.clock_default_description),
-            resources.getDrawable(R.drawable.clock_default_thumbnail, null),
-            isReactiveToTone = true,
-            axes =
-                if (!isClockReactiveVariantsEnabled) emptyList()
-                else getDefaultAxes(settings).merge(settings.axes),
-            axisPresets = if (!isClockReactiveVariantsEnabled) emptyList() else AXIS_PRESETS,
-        )
+        if (!isClockReactiveVariantsEnabled) {
+            return ClockPickerConfig(
+                settings.clockId ?: DEFAULT_CLOCK_ID,
+                resources.getString(R.string.clock_default_name),
+                resources.getString(R.string.clock_default_description),
+                resources.getDrawable(R.drawable.clock_default_thumbnail, null),
+                isReactiveToTone = true,
+                axes = emptyList(),
+                presetConfig = null,
+            )
+        } else {
+            val fontAxes = getDefaultAxes(settings).merge(settings.axes)
+            return ClockPickerConfig(
+                settings.clockId ?: DEFAULT_CLOCK_ID,
+                resources.getString(R.string.clock_default_name),
+                resources.getString(R.string.clock_default_description),
+                resources.getDrawable(R.drawable.clock_default_thumbnail, null),
+                isReactiveToTone = true,
+                axes = fontAxes,
+                presetConfig =
+                    AxisPresetConfig(
+                            listOf(
+                                buildPresetGroup(resources, isRound = true),
+                                buildPresetGroup(resources, isRound = false),
+                            )
+                        )
+                        .let { cfg -> cfg.copy(current = cfg.findStyle(ClockAxisStyle(fontAxes))) },
+            )
+        }
     }
 
     companion object {
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
index 5acd446..96c3ac7 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockController.kt
@@ -16,20 +16,24 @@
 
 package com.android.systemui.shared.clocks
 
+import android.content.res.Resources
 import com.android.systemui.animation.GSFAxes
 import com.android.systemui.customization.R
 import com.android.systemui.plugins.clocks.AlarmData
+import com.android.systemui.plugins.clocks.AxisPresetConfig
 import com.android.systemui.plugins.clocks.AxisType
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockConfig
 import com.android.systemui.plugins.clocks.ClockController
 import com.android.systemui.plugins.clocks.ClockEventListener
 import com.android.systemui.plugins.clocks.ClockEvents
 import com.android.systemui.plugins.clocks.ClockFontAxis
 import com.android.systemui.plugins.clocks.ClockFontAxis.Companion.merge
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
 import com.android.systemui.plugins.clocks.ClockSettings
 import com.android.systemui.plugins.clocks.WeatherData
 import com.android.systemui.plugins.clocks.ZenData
+import com.android.systemui.shared.clocks.FontUtils.put
+import com.android.systemui.shared.clocks.FontUtils.toClockAxis
 import com.android.systemui.shared.clocks.view.FlexClockView
 import java.io.PrintWriter
 import java.util.Locale
@@ -96,8 +100,8 @@
                 largeClock.events.onZenDataChanged(data)
             }
 
-            override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) {
-                val fontAxes = getDefaultAxes(clockCtx.settings).merge(axes).map { it.toSetting() }
+            override fun onFontAxesChanged(axes: ClockAxisStyle) {
+                val fontAxes = ClockAxisStyle(getDefaultAxes(clockCtx.settings).merge(axes))
                 smallClock.events.onFontAxesChanged(fontAxes)
                 largeClock.events.onFontAxesChanged(fontAxes)
             }
@@ -162,66 +166,46 @@
                 ),
             )
 
-        private val LEGACY_FLEX_SETTINGS =
-            listOf(
-                GSFAxes.WEIGHT.toClockAxisSetting(600f),
-                GSFAxes.WIDTH.toClockAxisSetting(100f),
-                GSFAxes.ROUND.toClockAxisSetting(100f),
-                GSFAxes.SLANT.toClockAxisSetting(0f),
-            )
+        private val LEGACY_FLEX_SETTINGS = ClockAxisStyle {
+            put(GSFAxes.WEIGHT, 600f)
+            put(GSFAxes.WIDTH, 100f)
+            put(GSFAxes.ROUND, 100f)
+            put(GSFAxes.SLANT, 0f)
+        }
 
-        val AXIS_PRESETS =
-            listOf(
-                FONT_AXES.map { it.toSetting() },
-                LEGACY_FLEX_SETTINGS,
-                listOf( // Porcelain
-                    GSFAxes.WEIGHT.toClockAxisSetting(500f),
-                    GSFAxes.WIDTH.toClockAxisSetting(100f),
-                    GSFAxes.ROUND.toClockAxisSetting(0f),
-                    GSFAxes.SLANT.toClockAxisSetting(0f),
-                ),
-                listOf( // Midnight
-                    GSFAxes.WEIGHT.toClockAxisSetting(300f),
-                    GSFAxes.WIDTH.toClockAxisSetting(100f),
-                    GSFAxes.ROUND.toClockAxisSetting(100f),
-                    GSFAxes.SLANT.toClockAxisSetting(-10f),
-                ),
-                listOf( // Sterling
-                    GSFAxes.WEIGHT.toClockAxisSetting(1000f),
-                    GSFAxes.WIDTH.toClockAxisSetting(100f),
-                    GSFAxes.ROUND.toClockAxisSetting(0f),
-                    GSFAxes.SLANT.toClockAxisSetting(0f),
-                ),
-                listOf( // Smoky Green
-                    GSFAxes.WEIGHT.toClockAxisSetting(150f),
-                    GSFAxes.WIDTH.toClockAxisSetting(50f),
-                    GSFAxes.ROUND.toClockAxisSetting(0f),
-                    GSFAxes.SLANT.toClockAxisSetting(0f),
-                ),
-                listOf( // Iris
-                    GSFAxes.WEIGHT.toClockAxisSetting(500f),
-                    GSFAxes.WIDTH.toClockAxisSetting(100f),
-                    GSFAxes.ROUND.toClockAxisSetting(100f),
-                    GSFAxes.SLANT.toClockAxisSetting(0f),
-                ),
-                listOf( // Margarita
-                    GSFAxes.WEIGHT.toClockAxisSetting(300f),
-                    GSFAxes.WIDTH.toClockAxisSetting(30f),
-                    GSFAxes.ROUND.toClockAxisSetting(100f),
-                    GSFAxes.SLANT.toClockAxisSetting(-10f),
-                ),
-                listOf( // Raspberry
-                    GSFAxes.WEIGHT.toClockAxisSetting(700f),
-                    GSFAxes.WIDTH.toClockAxisSetting(140f),
-                    GSFAxes.ROUND.toClockAxisSetting(100f),
-                    GSFAxes.SLANT.toClockAxisSetting(-7f),
-                ),
-                listOf( // Ultra Blue
-                    GSFAxes.WEIGHT.toClockAxisSetting(850f),
-                    GSFAxes.WIDTH.toClockAxisSetting(130f),
-                    GSFAxes.ROUND.toClockAxisSetting(0f),
-                    GSFAxes.SLANT.toClockAxisSetting(0f),
-                ),
+        private val PRESET_COUNT = 8
+        private val PRESET_WIDTH_INIT = 30f
+        private val PRESET_WIDTH_STEP = 12.5f
+        private val PRESET_WEIGHT_INIT = 800f
+        private val PRESET_WEIGHT_STEP = -100f
+        private val BASE_PRESETS: List<ClockAxisStyle> = run {
+            val presets = mutableListOf<ClockAxisStyle>()
+            var weight = PRESET_WEIGHT_INIT
+            var width = PRESET_WIDTH_INIT
+            for (i in 1..PRESET_COUNT) {
+                presets.add(
+                    ClockAxisStyle {
+                        put(GSFAxes.WEIGHT, weight)
+                        put(GSFAxes.WIDTH, width)
+                        put(GSFAxes.ROUND, 0f)
+                        put(GSFAxes.SLANT, 0f)
+                    }
+                )
+
+                weight += PRESET_WEIGHT_STEP
+                width += PRESET_WIDTH_STEP
+            }
+
+            return@run presets
+        }
+
+        fun buildPresetGroup(resources: Resources, isRound: Boolean): AxisPresetConfig.Group {
+            val round = if (isRound) GSFAxes.ROUND.maxValue else GSFAxes.ROUND.minValue
+            return AxisPresetConfig.Group(
+                presets = BASE_PRESETS.map { it.copy { put(GSFAxes.ROUND, round) } },
+                // TODO(b/395647577): Placeholder Icon; Replace or remove
+                icon = resources.getDrawable(R.drawable.clock_default_thumbnail, null),
             )
+        }
     }
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
index 578a489..171a68f 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FlexClockFaceController.kt
@@ -25,16 +25,18 @@
 import com.android.systemui.customization.R
 import com.android.systemui.plugins.clocks.AlarmData
 import com.android.systemui.plugins.clocks.ClockAnimations
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockEvents
 import com.android.systemui.plugins.clocks.ClockFaceConfig
 import com.android.systemui.plugins.clocks.ClockFaceController
 import com.android.systemui.plugins.clocks.ClockFaceEvents
 import com.android.systemui.plugins.clocks.ClockFaceLayout
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
 import com.android.systemui.plugins.clocks.DefaultClockFaceLayout
 import com.android.systemui.plugins.clocks.ThemeConfig
 import com.android.systemui.plugins.clocks.WeatherData
 import com.android.systemui.plugins.clocks.ZenData
+import com.android.systemui.shared.clocks.FontUtils.get
+import com.android.systemui.shared.clocks.FontUtils.set
 import com.android.systemui.shared.clocks.ViewUtils.computeLayoutDiff
 import com.android.systemui.shared.clocks.view.FlexClockView
 import com.android.systemui.shared.clocks.view.HorizontalAlignment
@@ -129,17 +131,10 @@
             layerController.faceEvents.onThemeChanged(theme)
         }
 
-        override fun onFontAxesChanged(settings: List<ClockFontAxisSetting>) {
-            var axes = settings
-            if (!isLargeClock) {
-                axes =
-                    axes.map { axis ->
-                        if (axis.key == GSFAxes.WIDTH.tag && axis.value > SMALL_CLOCK_MAX_WDTH) {
-                            axis.copy(value = SMALL_CLOCK_MAX_WDTH)
-                        } else {
-                            axis
-                        }
-                    }
+        override fun onFontAxesChanged(settings: ClockAxisStyle) {
+            var axes = ClockAxisStyle(settings)
+            if (!isLargeClock && axes[GSFAxes.WIDTH] > SMALL_CLOCK_MAX_WDTH) {
+                axes[GSFAxes.WIDTH] = SMALL_CLOCK_MAX_WDTH
             }
 
             layerController.events.onFontAxesChanged(axes)
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt
index 212b1e2..722d76b 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/FontUtils.kt
@@ -18,26 +18,36 @@
 
 import com.android.systemui.animation.AxisDefinition
 import com.android.systemui.plugins.clocks.AxisType
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockFontAxis
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
 
-fun AxisDefinition.toClockAxis(
-    type: AxisType,
-    currentValue: Float? = null,
-    name: String,
-    description: String,
-): ClockFontAxis {
-    return ClockFontAxis(
-        key = this.tag,
-        type = type,
-        maxValue = this.maxValue,
-        minValue = this.minValue,
-        currentValue = currentValue ?: this.defaultValue,
-        name = name,
-        description = description,
-    )
-}
+object FontUtils {
+    fun AxisDefinition.toClockAxis(
+        type: AxisType,
+        currentValue: Float? = null,
+        name: String,
+        description: String,
+    ): ClockFontAxis {
+        return ClockFontAxis(
+            key = this.tag,
+            type = type,
+            maxValue = this.maxValue,
+            minValue = this.minValue,
+            currentValue = currentValue ?: this.defaultValue,
+            name = name,
+            description = description,
+        )
+    }
 
-fun AxisDefinition.toClockAxisSetting(value: Float? = null): ClockFontAxisSetting {
-    return ClockFontAxisSetting(this.tag, value ?: this.defaultValue)
+    fun ClockAxisStyle.put(def: AxisDefinition, value: Float? = null) {
+        this.put(def.tag, value ?: def.defaultValue)
+    }
+
+    operator fun ClockAxisStyle.set(def: AxisDefinition, value: Float) {
+        this[def.tag] = value
+    }
+
+    operator fun ClockAxisStyle.get(def: AxisDefinition): Float {
+        return this[def.tag] ?: def.defaultValue
+    }
 }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
index 1d963af..7be9a93 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/SimpleDigitalHandLayerController.kt
@@ -26,10 +26,10 @@
 import com.android.systemui.log.core.Logger
 import com.android.systemui.plugins.clocks.AlarmData
 import com.android.systemui.plugins.clocks.ClockAnimations
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockEvents
 import com.android.systemui.plugins.clocks.ClockFaceConfig
 import com.android.systemui.plugins.clocks.ClockFaceEvents
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
 import com.android.systemui.plugins.clocks.ThemeConfig
 import com.android.systemui.plugins.clocks.WeatherData
 import com.android.systemui.plugins.clocks.ZenData
@@ -172,7 +172,7 @@
 
             override fun onZenDataChanged(data: ZenData) {}
 
-            override fun onFontAxesChanged(axes: List<ClockFontAxisSetting>) {
+            override fun onFontAxesChanged(axes: ClockAxisStyle) {
                 view.updateAxes(axes)
             }
         }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
index ba32ab0..4531aed 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/FlexClockView.kt
@@ -26,7 +26,7 @@
 import androidx.core.view.children
 import com.android.app.animation.Interpolators
 import com.android.systemui.customization.R
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockLogger
 import com.android.systemui.plugins.clocks.VPoint
 import com.android.systemui.plugins.clocks.VPointF
@@ -272,7 +272,7 @@
         invalidate()
     }
 
-    fun updateAxes(axes: List<ClockFontAxisSetting>) {
+    fun updateAxes(axes: ClockAxisStyle) {
         childViews.forEach { view -> view.updateAxes(axes) }
         requestLayout()
     }
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
index da9e26a..377a24c 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/view/SimpleDigitalClockTextView.kt
@@ -36,13 +36,12 @@
 import android.widget.TextView
 import com.android.app.animation.Interpolators
 import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.animation.AxisDefinition
 import com.android.systemui.animation.GSFAxes
 import com.android.systemui.animation.TextAnimator
 import com.android.systemui.animation.TextAnimatorListener
 import com.android.systemui.customization.R
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.replace
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting.Companion.toFVar
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockLogger
 import com.android.systemui.plugins.clocks.VPoint
 import com.android.systemui.plugins.clocks.VPointF
@@ -56,9 +55,9 @@
 import com.android.systemui.shared.clocks.DimensionParser
 import com.android.systemui.shared.clocks.FLEX_CLOCK_ID
 import com.android.systemui.shared.clocks.FontTextStyle
+import com.android.systemui.shared.clocks.FontUtils.set
 import com.android.systemui.shared.clocks.ViewUtils.measuredSize
 import com.android.systemui.shared.clocks.ViewUtils.size
-import com.android.systemui.shared.clocks.toClockAxisSetting
 import java.lang.Thread
 import kotlin.math.max
 import kotlin.math.min
@@ -123,9 +122,9 @@
     private val isLegacyFlex = clockCtx.settings.clockId == FLEX_CLOCK_ID
     private val fixedAodAxes =
         when {
-            !isLegacyFlex -> listOf(AOD_WEIGHT_AXIS, WIDTH_AXIS)
-            isLargeClock -> listOf(FLEX_AOD_LARGE_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS)
-            else -> listOf(FLEX_AOD_SMALL_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS)
+            !isLegacyFlex -> fromAxes(AOD_WEIGHT_AXIS, WIDTH_AXIS)
+            isLargeClock -> fromAxes(FLEX_AOD_LARGE_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS)
+            else -> fromAxes(FLEX_AOD_SMALL_WEIGHT_AXIS, FLEX_AOD_WIDTH_AXIS)
         }
 
     private var lsFontVariation: String
@@ -135,11 +134,11 @@
     init {
         val roundAxis = if (!isLegacyFlex) ROUND_AXIS else FLEX_ROUND_AXIS
         val lsFontAxes =
-            if (!isLegacyFlex) listOf(LS_WEIGHT_AXIS, WIDTH_AXIS, ROUND_AXIS, SLANT_AXIS)
-            else listOf(FLEX_LS_WEIGHT_AXIS, FLEX_LS_WIDTH_AXIS, FLEX_ROUND_AXIS, SLANT_AXIS)
+            if (!isLegacyFlex) fromAxes(LS_WEIGHT_AXIS, WIDTH_AXIS, ROUND_AXIS, SLANT_AXIS)
+            else fromAxes(FLEX_LS_WEIGHT_AXIS, FLEX_LS_WIDTH_AXIS, FLEX_ROUND_AXIS, SLANT_AXIS)
 
         lsFontVariation = lsFontAxes.toFVar()
-        aodFontVariation = (fixedAodAxes + listOf(roundAxis, SLANT_AXIS)).toFVar()
+        aodFontVariation = fixedAodAxes.copyWith(fromAxes(roundAxis, SLANT_AXIS)).toFVar()
         fidgetFontVariation = buildFidgetVariation(lsFontAxes).toFVar()
     }
 
@@ -201,9 +200,9 @@
         invalidate()
     }
 
-    fun updateAxes(lsAxes: List<ClockFontAxisSetting>) {
+    fun updateAxes(lsAxes: ClockAxisStyle) {
         lsFontVariation = lsAxes.toFVar()
-        aodFontVariation = lsAxes.replace(fixedAodAxes).toFVar()
+        aodFontVariation = lsAxes.copyWith(fixedAodAxes).toFVar()
         fidgetFontVariation = buildFidgetVariation(lsAxes).toFVar()
         logger.updateAxes(lsFontVariation, aodFontVariation)
 
@@ -220,19 +219,16 @@
         invalidate()
     }
 
-    fun buildFidgetVariation(axes: List<ClockFontAxisSetting>): List<ClockFontAxisSetting> {
-        val result = mutableListOf<ClockFontAxisSetting>()
-        for (axis in axes) {
-            result.add(
-                FIDGET_DISTS.get(axis.key)?.let { (dist, midpoint) ->
-                    ClockFontAxisSetting(
-                        axis.key,
-                        axis.value + dist * if (axis.value > midpoint) -1 else 1,
-                    )
-                } ?: axis
-            )
-        }
-        return result
+    fun buildFidgetVariation(axes: ClockAxisStyle): ClockAxisStyle {
+        return ClockAxisStyle(
+            axes.items
+                .map { (key, value) ->
+                    FIDGET_DISTS.get(key)?.let { (dist, midpoint) ->
+                        key to value + dist * if (value > midpoint) -1 else 1
+                    } ?: (key to value)
+                }
+                .toMap()
+        )
     }
 
     override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
@@ -666,18 +662,22 @@
             )
 
         val AOD_COLOR = Color.WHITE
-        val LS_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(400f)
-        val AOD_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(200f)
-        val WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(85f)
-        val ROUND_AXIS = GSFAxes.ROUND.toClockAxisSetting(0f)
-        val SLANT_AXIS = GSFAxes.SLANT.toClockAxisSetting(0f)
+        private val LS_WEIGHT_AXIS = GSFAxes.WEIGHT to 400f
+        private val AOD_WEIGHT_AXIS = GSFAxes.WEIGHT to 200f
+        private val WIDTH_AXIS = GSFAxes.WIDTH to 85f
+        private val ROUND_AXIS = GSFAxes.ROUND to 0f
+        private val SLANT_AXIS = GSFAxes.SLANT to 0f
 
         // Axes for Legacy version of the Flex Clock
-        val FLEX_LS_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(600f)
-        val FLEX_AOD_LARGE_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(74f)
-        val FLEX_AOD_SMALL_WEIGHT_AXIS = GSFAxes.WEIGHT.toClockAxisSetting(133f)
-        val FLEX_LS_WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(100f)
-        val FLEX_AOD_WIDTH_AXIS = GSFAxes.WIDTH.toClockAxisSetting(43f)
-        val FLEX_ROUND_AXIS = GSFAxes.ROUND.toClockAxisSetting(100f)
+        private val FLEX_LS_WEIGHT_AXIS = GSFAxes.WEIGHT to 600f
+        private val FLEX_AOD_LARGE_WEIGHT_AXIS = GSFAxes.WEIGHT to 74f
+        private val FLEX_AOD_SMALL_WEIGHT_AXIS = GSFAxes.WEIGHT to 133f
+        private val FLEX_LS_WIDTH_AXIS = GSFAxes.WIDTH to 100f
+        private val FLEX_AOD_WIDTH_AXIS = GSFAxes.WIDTH to 43f
+        private val FLEX_ROUND_AXIS = GSFAxes.ROUND to 100f
+
+        private fun fromAxes(vararg axes: Pair<AxisDefinition, Float>): ClockAxisStyle {
+            return ClockAxisStyle(axes.map { (def, value) -> def.tag to value }.toMap())
+        }
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/ActiveUnlockConfigTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
index 14d34d7..162218d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
@@ -87,7 +87,7 @@
                 contentResolver,
                 selectedUserInteractor,
                 lazyKeyguardUpdateMonitor,
-                dumpManager
+                dumpManager,
             )
     }
 
@@ -116,9 +116,9 @@
             )
         )
         assertFalse(
-                activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
-                        ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
-                )
+            activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+                ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT_LEGACY
+            )
         )
         assertTrue(
             activeUnlockConfig.shouldAllowActiveUnlockFromOrigin(
@@ -212,7 +212,7 @@
         secureSettings.putStringForUser(
             ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
             "",
-            currentUser
+            currentUser,
         )
         updateSetting(
             secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
@@ -285,7 +285,7 @@
             ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO,
             "${BiometricFaceConstants.FACE_ACQUIRED_MOUTH_COVERING_DETECTED}" +
                 "|${BiometricFaceConstants.FACE_ACQUIRED_DARK_GLASSES_DETECTED}",
-            currentUser
+            currentUser,
         )
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_ON_FACE_ACQUIRE_INFO))
 
@@ -328,7 +328,7 @@
         secureSettings.putStringForUser(
             ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
             "${ActiveUnlockConfig.BiometricType.NONE.intValue}",
-            currentUser
+            currentUser,
         )
         updateSetting(
             secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
@@ -358,7 +358,7 @@
             ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
             "${ActiveUnlockConfig.BiometricType.ANY_FACE.intValue}" +
                 "|${ActiveUnlockConfig.BiometricType.ANY_FINGERPRINT.intValue}",
-            currentUser
+            currentUser,
         )
         updateSetting(
             secureSettings.getUriFor(ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED)
@@ -397,10 +397,10 @@
     @Test
     fun isWakeupConsideredUnlockIntent_singleValue() {
         // GIVEN lift is considered an unlock intent
-        secureSettings.putIntForUser(
+        secureSettings.putStringForUser(
             ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
-            PowerManager.WAKE_REASON_LIFT,
-            currentUser
+            PowerManager.WAKE_REASON_LIFT.toString(),
+            currentUser,
         )
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS))
 
@@ -422,7 +422,7 @@
             PowerManager.WAKE_REASON_LIFT.toString() +
                 "|" +
                 PowerManager.WAKE_REASON_TAP.toString(),
-            currentUser
+            currentUser,
         )
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS))
 
@@ -452,7 +452,7 @@
         secureSettings.putStringForUser(
             ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS,
             " ",
-            currentUser
+            currentUser,
         )
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_CONSIDERED_UNLOCK_INTENTS))
 
@@ -479,7 +479,7 @@
         secureSettings.putStringForUser(
             ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
             PowerManager.WAKE_REASON_LIFT.toString(),
-            currentUser
+            currentUser,
         )
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD))
 
@@ -501,7 +501,7 @@
         secureSettings.putStringForUser(
             ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD,
             " ",
-            currentUser
+            currentUser,
         )
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD))
 
@@ -521,7 +521,7 @@
             PowerManager.WAKE_REASON_LIFT.toString() +
                 "|" +
                 PowerManager.WAKE_REASON_TAP.toString(),
-            currentUser
+            currentUser,
         )
         updateSetting(secureSettings.getUriFor(ACTIVE_UNLOCK_WAKEUPS_TO_FORCE_DISMISS_KEYGUARD))
 
@@ -544,7 +544,7 @@
         secureSettings.putStringForUser(
             ACTIVE_UNLOCK_ON_UNLOCK_INTENT_WHEN_BIOMETRIC_ENROLLED,
             "-1",
-            currentUser
+            currentUser,
         )
 
         // WHEN the setting updates
@@ -581,7 +581,7 @@
                 eq(uri),
                 eq(false),
                 capture(settingsObserverCaptor),
-                eq(UserHandle.USER_ALL)
+                eq(UserHandle.USER_ALL),
             )
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
index 245388c..b0db8b7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardUnfoldTransitionTest.kt
@@ -22,12 +22,12 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.customization.R as customR
 import com.android.systemui.keyguard.ui.view.KeyguardRootView
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.res.R
 import com.android.systemui.shade.NotificationShadeWindowView
 import com.android.systemui.statusbar.StatusBarState.KEYGUARD
 import com.android.systemui.statusbar.StatusBarState.SHADE
+import com.android.systemui.testKosmos
 import com.android.systemui.unfold.FakeUnfoldTransitionProvider
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
 import com.android.systemui.unfold.fakeUnfoldTransitionProgressProvider
@@ -47,16 +47,14 @@
 @RunWith(AndroidJUnit4::class)
 class KeyguardUnfoldTransitionTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
 
     private val progressProvider: FakeUnfoldTransitionProvider =
         kosmos.fakeUnfoldTransitionProgressProvider
 
-    @Mock
-    private lateinit var keyguardRootView: KeyguardRootView
+    @Mock private lateinit var keyguardRootView: KeyguardRootView
 
-    @Mock
-    private lateinit var notificationShadeWindowView: NotificationShadeWindowView
+    @Mock private lateinit var notificationShadeWindowView: NotificationShadeWindowView
 
     @Mock private lateinit var statusBarStateController: StatusBarStateController
 
@@ -71,10 +69,14 @@
         xTranslationMax =
             context.resources.getDimensionPixelSize(R.dimen.keyguard_unfold_translation_x).toFloat()
 
-        underTest = KeyguardUnfoldTransition(
-            context, keyguardRootView, notificationShadeWindowView,
-            statusBarStateController, progressProvider
-        )
+        underTest =
+            KeyguardUnfoldTransition(
+                context,
+                keyguardRootView,
+                notificationShadeWindowView,
+                statusBarStateController,
+                progressProvider,
+            )
 
         underTest.setup()
         underTest.statusViewCentered = false
@@ -88,9 +90,8 @@
         underTest.statusViewCentered = true
 
         val view = View(context)
-        whenever(keyguardRootView.findViewById<View>(customR.id.lockscreen_clock_view_large)).thenReturn(
-            view
-        )
+        whenever(keyguardRootView.findViewById<View>(customR.id.lockscreen_clock_view_large))
+            .thenReturn(view)
 
         progressListener.onTransitionStarted()
         assertThat(view.translationX).isZero()
@@ -110,9 +111,8 @@
         whenever(statusBarStateController.getState()).thenReturn(SHADE)
 
         val view = View(context)
-        whenever(keyguardRootView.findViewById<View>(customR.id.lockscreen_clock_view_large)).thenReturn(
-            view
-        )
+        whenever(keyguardRootView.findViewById<View>(customR.id.lockscreen_clock_view_large))
+            .thenReturn(view)
 
         progressListener.onTransitionStarted()
         assertThat(view.translationX).isZero()
@@ -133,9 +133,11 @@
 
         val view = View(context)
         whenever(
-            notificationShadeWindowView
-                .findViewById<View>(customR.id.lockscreen_clock_view_large)
-        ).thenReturn(view)
+                notificationShadeWindowView.findViewById<View>(
+                    customR.id.lockscreen_clock_view_large
+                )
+            )
+            .thenReturn(view)
 
         progressListener.onTransitionStarted()
         assertThat(view.translationX).isZero()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt
index cde42bd..7660623 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/extradim/ExtraDimDialogDelegateTest.kt
@@ -23,7 +23,6 @@
 import com.android.internal.accessibility.AccessibilityShortcutController
 import com.android.internal.accessibility.common.ShortcutConstants
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
@@ -31,6 +30,7 @@
 import com.android.systemui.res.R
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.testKosmos
 import kotlinx.coroutines.test.advanceUntilIdle
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -58,7 +58,7 @@
 
     private lateinit var extraDimDialogDelegate: ExtraDimDialogDelegate
 
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
     private val testScope = kosmos.testScope
 
     @Mock private lateinit var dialog: SystemUIDialog
@@ -79,7 +79,7 @@
                 kosmos.testDispatcher,
                 dialogFactory,
                 accessibilityManager,
-                userTracker
+                userTracker,
             )
     }
 
@@ -94,7 +94,7 @@
             verify(dialog)
                 .setPositiveButton(
                     eq(R.string.accessibility_deprecate_extra_dim_dialog_button),
-                    clickListener.capture()
+                    clickListener.capture(),
                 )
 
             clickListener.firstValue.onClick(dialog, 0)
@@ -110,7 +110,7 @@
                                 .flattenToString()
                         )
                     ),
-                    anyInt()
+                    anyInt(),
                 )
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt
index 2713bb0..3040c12 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogDelegateTest.kt
@@ -83,10 +83,11 @@
         MockitoAnnotations.initMocks(this)
         testableLooper = TestableLooper.get(this)
         val mainHandler = Handler(testableLooper.looper)
-        systemSettings = FakeSettings()
+        val fakeSettings = FakeSettings()
+        systemSettings = fakeSettings
         // Guarantee that the systemSettings always starts with the default font scale.
         systemSettings.putFloatForUser(Settings.System.FONT_SCALE, 1.0f, userTracker.userId)
-        secureSettings = FakeSettings()
+        secureSettings = fakeSettings
         systemClock = FakeSystemClock()
         backgroundDelayableExecutor = FakeExecutor(systemClock)
         whenever(sysuiState.setFlag(anyLong(), anyBoolean())).thenReturn(sysuiState)
@@ -207,9 +208,9 @@
         dialog.show()
 
         val iconStartFrame: ViewGroup = dialog.findViewById(R.id.icon_start_frame)!!
-        secureSettings.putIntForUser(
+        secureSettings.putStringForUser(
             Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
-            OFF,
+            OFF.toString(),
             userTracker.userId,
         )
 
@@ -220,12 +221,11 @@
         backgroundDelayableExecutor.runAllReady()
 
         val currentSettings =
-            secureSettings.getIntForUser(
+            secureSettings.getStringForUser(
                 Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
-                /* def = */ OFF,
                 userTracker.userId,
             )
-        assertThat(currentSettings).isEqualTo(ON)
+        assertThat(currentSettings).isEqualTo(ON.toString())
 
         dialog.dismiss()
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
index 7e4704a..d118ace 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegateTest.java
@@ -141,6 +141,10 @@
     @Mock
     private QSSettingsPackageRepository mQSSettingsPackageRepository;
     @Mock
+    private HearingDevicesInputRoutingController.Factory mInputRoutingFactory;
+    @Mock
+    private HearingDevicesInputRoutingController mInputRoutingController;
+    @Mock
     private CachedBluetoothDevice mCachedDevice;
     @Mock
     private BluetoothDevice mDevice;
@@ -184,6 +188,7 @@
         when(mCachedDevice.getBondState()).thenReturn(BOND_BONDED);
         when(mCachedDevice.getDeviceSide()).thenReturn(SIDE_LEFT);
         when(mHearingDeviceItem.getCachedBluetoothDevice()).thenReturn(mCachedDevice);
+        when(mInputRoutingFactory.create(any())).thenReturn(mInputRoutingController);
 
         mContext.setMockPackageManager(mPackageManager);
     }
@@ -349,6 +354,7 @@
 
         setUpDeviceDialogWithoutPairNewDeviceButton();
         mDialog.show();
+        mExecutor.runAllReady();
 
         ViewGroup ambientLayout = getAmbientLayout(mDialog);
         assertThat(ambientLayout.getVisibility()).isEqualTo(View.VISIBLE);
@@ -401,7 +407,8 @@
                 mExecutor,
                 mAudioManager,
                 mUiEventLogger,
-                mQSSettingsPackageRepository
+                mQSSettingsPackageRepository,
+                mInputRoutingFactory
         );
         mDialog = mDialogDelegate.createDialog();
     }
@@ -438,7 +445,6 @@
         return dialog.requireViewById(R.id.ambient_layout);
     }
 
-
     private int countChildWithoutSpace(ViewGroup viewGroup) {
         int spaceCount = 0;
         for (int i = 0; i < viewGroup.getChildCount(); i++) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingControllerTest.kt
new file mode 100644
index 0000000..0a41b77
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingControllerTest.kt
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid
+
+import android.media.AudioDeviceInfo
+import android.media.AudioManager
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.HapClientProfile
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.accessibility.hearingaid.HearingDevicesInputRoutingController.InputRoutingControlAvailableCallback
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.stub
+import org.mockito.kotlin.verify
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class HearingDevicesInputRoutingControllerTest : SysuiTestCase() {
+
+    private val kosmos = Kosmos()
+    private val testScope = kosmos.testScope
+    private var hapClientProfile: HapClientProfile = mock()
+    private var cachedDevice: CachedBluetoothDevice = mock()
+    private var memberCachedDevice: CachedBluetoothDevice = mock()
+    private var btDevice: android.bluetooth.BluetoothDevice = mock()
+    private var audioManager: AudioManager = mock()
+    private lateinit var underTest: HearingDevicesInputRoutingController
+    private val testDispatcher = kosmos.testDispatcher
+
+    @Before
+    fun setUp() {
+        hapClientProfile.stub { on { isProfileReady } doReturn true }
+        cachedDevice.stub {
+            on { device } doReturn btDevice
+            on { profiles } doReturn listOf(hapClientProfile)
+        }
+        memberCachedDevice.stub {
+            on { device } doReturn btDevice
+            on { profiles } doReturn listOf(hapClientProfile)
+        }
+
+        underTest = HearingDevicesInputRoutingController(mContext, audioManager, testDispatcher)
+        underTest.setDevice(cachedDevice)
+    }
+
+    @Test
+    fun isInputRoutingControlAvailable_validInput_supportHapProfile_returnTrue() {
+        testScope.runTest {
+            val mockInfoAddress = arrayOf(mockTestAddressInfo(TEST_ADDRESS))
+            cachedDevice.stub {
+                on { address } doReturn TEST_ADDRESS
+                on { profiles } doReturn listOf(hapClientProfile)
+            }
+            audioManager.stub {
+                on { getDevices(AudioManager.GET_DEVICES_INPUTS) } doReturn mockInfoAddress
+            }
+
+            var result: Boolean? = null
+            underTest.isInputRoutingControlAvailable(
+                object : InputRoutingControlAvailableCallback {
+                    override fun onResult(available: Boolean) {
+                        result = available
+                    }
+                }
+            )
+
+            runCurrent()
+            assertThat(result).isTrue()
+        }
+    }
+
+    @Test
+    fun isInputRoutingControlAvailable_notSupportHapProfile_returnFalse() {
+        testScope.runTest {
+            val mockInfoAddress = arrayOf(mockTestAddressInfo(TEST_ADDRESS))
+            cachedDevice.stub {
+                on { address } doReturn TEST_ADDRESS
+                on { profiles } doReturn emptyList()
+            }
+            audioManager.stub {
+                on { getDevices(AudioManager.GET_DEVICES_INPUTS) } doReturn mockInfoAddress
+            }
+
+            var result: Boolean? = null
+            underTest.isInputRoutingControlAvailable(
+                object : InputRoutingControlAvailableCallback {
+                    override fun onResult(available: Boolean) {
+                        result = available
+                    }
+                }
+            )
+
+            runCurrent()
+            assertThat(result).isFalse()
+        }
+    }
+
+    @Test
+    fun isInputRoutingControlAvailable_validInputMember_supportHapProfile_returnTrue() {
+        testScope.runTest {
+            val mockInfoAddress2 = arrayOf(mockTestAddressInfo(TEST_ADDRESS_2))
+            cachedDevice.stub {
+                on { address } doReturn TEST_ADDRESS
+                on { profiles } doReturn listOf(hapClientProfile)
+                on { memberDevice } doReturn (setOf(memberCachedDevice))
+            }
+            memberCachedDevice.stub { on { address } doReturn TEST_ADDRESS_2 }
+            audioManager.stub {
+                on { getDevices(AudioManager.GET_DEVICES_INPUTS) } doReturn mockInfoAddress2
+            }
+
+            var result: Boolean? = null
+            underTest.isInputRoutingControlAvailable(
+                object : InputRoutingControlAvailableCallback {
+                    override fun onResult(available: Boolean) {
+                        result = available
+                    }
+                }
+            )
+
+            runCurrent()
+            assertThat(result).isTrue()
+        }
+    }
+
+    @Test
+    fun isAvailable_notValidInputDevice_returnFalse() {
+        testScope.runTest {
+            cachedDevice.stub {
+                on { address } doReturn TEST_ADDRESS
+                on { profiles } doReturn listOf(hapClientProfile)
+            }
+            audioManager.stub {
+                on { getDevices(AudioManager.GET_DEVICES_INPUTS) } doReturn emptyArray()
+            }
+
+            var result: Boolean? = null
+            underTest.isInputRoutingControlAvailable(
+                object : InputRoutingControlAvailableCallback {
+                    override fun onResult(available: Boolean) {
+                        result = available
+                    }
+                }
+            )
+
+            runCurrent()
+            assertThat(result).isFalse()
+        }
+    }
+
+    @Test
+    fun selectInputRouting_builtinMic_setMicrophonePreferredForCallsFalse() {
+        underTest.selectInputRouting(
+            HearingDevicesInputRoutingController.InputRoutingValue.BUILTIN_MIC.ordinal
+        )
+
+        verify(btDevice).isMicrophonePreferredForCalls = false
+    }
+
+    private fun mockTestAddressInfo(address: String): AudioDeviceInfo {
+        val info: AudioDeviceInfo = mock()
+        info.stub {
+            on { type } doReturn AudioDeviceInfo.TYPE_BLE_HEADSET
+            on { this.address } doReturn address
+        }
+
+        return info
+    }
+
+    companion object {
+        private const val TEST_ADDRESS = "55:66:77:88:99:AA"
+        private const val TEST_ADDRESS_2 = "55:66:77:88:99:BB"
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
index 8c5fad3..8573312 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/back/domain/interactor/BackActionInteractorTest.kt
@@ -32,7 +32,6 @@
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
@@ -50,6 +49,7 @@
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
 import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
@@ -74,7 +74,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BackActionInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val executor = FakeExecutor(FakeSystemClock())
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt
index 648d74d..29a0b69 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraAutoRotateRepositoryImplTest.kt
@@ -22,8 +22,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
@@ -34,7 +34,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CameraAutoRotateRepositoryImplTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val settings = kosmos.fakeSettings
     private val testUser = UserHandle.of(1)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt
index b73a212..2e357d8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/CameraSensorPrivacyRepositoryImplTest.kt
@@ -22,8 +22,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
@@ -38,7 +38,7 @@
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
 class CameraSensorPrivacyRepositoryImplTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val testUser = UserHandle.of(1)
     private val privacyManager = mock<SensorPrivacyManager>()
@@ -46,7 +46,7 @@
         CameraSensorPrivacyRepositoryImpl(
             testScope.testScheduler,
             testScope.backgroundScope,
-            privacyManager
+            privacyManager,
         )
 
     @Test
@@ -87,7 +87,7 @@
                 .addSensorPrivacyListener(
                     ArgumentMatchers.eq(SensorPrivacyManager.Sensors.CAMERA),
                     ArgumentMatchers.eq(testUser.identifier),
-                    captor.capture()
+                    captor.capture(),
                 )
             val sensorPrivacyCallback = captor.value!!
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt
index 6c8097e..b3d8983 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraAutoRotateRepositoryTest.kt
@@ -21,7 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -32,7 +32,7 @@
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
 class FakeCameraAutoRotateRepositoryTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val underTest = kosmos.fakeCameraAutoRotateRepository
     private val testUser = UserHandle.of(1)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt
index 7161c2c..6b9a7de 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/camera/data/repository/FakeCameraSensorPrivacyRepositoryTest.kt
@@ -21,7 +21,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -32,7 +32,7 @@
 @RunWith(AndroidJUnit4::class)
 @android.platform.test.annotations.EnabledOnRavenwood
 class FakeCameraSensorPrivacyRepositoryTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val underTest = kosmos.fakeCameraSensorPrivacyRepository
     private val testUser = UserHandle.of(1)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/ActionIntentCreatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/ActionIntentCreatorTest.kt
index 239e026..652a2ff 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/ActionIntentCreatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/ActionIntentCreatorTest.kt
@@ -25,6 +25,10 @@
 import androidx.test.runner.AndroidJUnit4
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.res.R
+import kotlinx.coroutines.test.TestCoroutineScheduler
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertTrue
 import org.junit.Test
@@ -33,7 +37,11 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ActionIntentCreatorTest : SysuiTestCase() {
-    val creator = ActionIntentCreator()
+    private val scheduler = TestCoroutineScheduler()
+    private val mainDispatcher = UnconfinedTestDispatcher(scheduler)
+    private val testScope = TestScope(mainDispatcher)
+
+    val creator = ActionIntentCreator(testScope.backgroundScope)
 
     @Test
     fun test_getTextEditorIntent() {
@@ -65,7 +73,7 @@
     }
 
     @Test
-    fun test_getImageEditIntent() {
+    fun test_getImageEditIntent() = runTest {
         context.getOrCreateTestableResources().addOverride(R.string.config_screenshotEditor, "")
         val fakeUri = Uri.parse("content://foo")
         var intent = creator.getImageEditIntent(fakeUri, context)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/DefaultIntentCreatorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/DefaultIntentCreatorTest.java
index 126b3fa..10c5c52 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/DefaultIntentCreatorTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/clipboardoverlay/DefaultIntentCreatorTest.java
@@ -34,6 +34,8 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
+import java.util.concurrent.atomic.AtomicReference;
+
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class DefaultIntentCreatorTest extends SysuiTestCase {
@@ -73,12 +75,16 @@
     }
 
     @Test
-    public void test_getImageEditIntent() {
+    public void test_getImageEditIntentAsync() {
         getContext().getOrCreateTestableResources().addOverride(R.string.config_screenshotEditor,
                 "");
         Uri fakeUri = Uri.parse("content://foo");
-        Intent intent = mIntentCreator.getImageEditIntent(fakeUri, getContext());
+        final AtomicReference<Intent> intentHolder = new AtomicReference<>(null);
+        mIntentCreator.getImageEditIntentAsync(fakeUri, getContext(), output -> {
+            intentHolder.set(output);
+        });
 
+        Intent intent = intentHolder.get();
         assertEquals(Intent.ACTION_EDIT, intent.getAction());
         assertEquals("image/*", intent.getType());
         assertEquals(null, intent.getComponent());
@@ -90,8 +96,10 @@
                 "com.android.remotecopy.RemoteCopyActivity");
         getContext().getOrCreateTestableResources().addOverride(R.string.config_screenshotEditor,
                 fakeComponent.flattenToString());
-        intent = mIntentCreator.getImageEditIntent(fakeUri, getContext());
-        assertEquals(fakeComponent, intent.getComponent());
+        mIntentCreator.getImageEditIntentAsync(fakeUri, getContext(), output -> {
+            intentHolder.set(output);
+        });
+        assertEquals(fakeComponent, intentHolder.get().getComponent());
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/DeviceInactiveConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/DeviceInactiveConditionTest.kt
index 0c97750..6710575 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/DeviceInactiveConditionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/DeviceInactiveConditionTest.kt
@@ -20,6 +20,7 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.keyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.condition.testStart
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP
 import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWAKE
@@ -55,6 +56,7 @@
         Kosmos.Fixture {
             DeviceInactiveCondition(
                 applicationCoroutineScope,
+                applicationCoroutineScope,
                 keyguardStateController,
                 wakefulnessLifecycle,
                 keyguardUpdateMonitor,
@@ -67,7 +69,7 @@
     fun asleep_conditionTrue() =
         kosmos.runTest {
             // Condition is false to start.
-            underTest.start()
+            testStart(underTest)
             assertThat(underTest.isConditionMet).isFalse()
 
             // Condition is true when device goes to sleep.
@@ -79,7 +81,7 @@
     fun dozingAndAsleep_conditionFalse() =
         kosmos.runTest {
             // Condition is true when device is asleep.
-            underTest.start()
+            testStart(underTest)
             sleep()
             assertThat(underTest.isConditionMet).isTrue()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt
index f4a1c90..95334b5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractorTest.kt
@@ -55,9 +55,11 @@
     fun setUp() {
         runBlocking { kosmos.fakeUserRepository.asMainUser() }
         with(kosmos.fakeSettings) {
-            putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, false, MAIN_USER_ID)
-            putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK, false, MAIN_USER_ID)
-            putBoolForUser(Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED, false, MAIN_USER_ID)
+            putIntForUser(
+                Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB,
+                Settings.Secure.GLANCEABLE_HUB_START_NEVER,
+                MAIN_USER_ID,
+            )
         }
     }
 
@@ -67,9 +69,9 @@
             val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen)
             val suppressionReason by collectLastValue(underTest.suppressionReason)
 
-            fakeSettings.putBoolForUser(
-                Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
-                true,
+            fakeSettings.putIntForUser(
+                Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB,
+                Settings.Secure.GLANCEABLE_HUB_START_CHARGING,
                 MAIN_USER_ID,
             )
 
@@ -91,9 +93,9 @@
             val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen)
             val suppressionReason by collectLastValue(underTest.suppressionReason)
 
-            fakeSettings.putBoolForUser(
-                Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
-                true,
+            fakeSettings.putIntForUser(
+                Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB,
+                Settings.Secure.GLANCEABLE_HUB_START_DOCKED,
                 MAIN_USER_ID,
             )
 
@@ -118,9 +120,9 @@
             val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen)
             val suppressionReason by collectLastValue(underTest.suppressionReason)
 
-            fakeSettings.putBoolForUser(
-                Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED,
-                true,
+            fakeSettings.putIntForUser(
+                Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB,
+                Settings.Secure.GLANCEABLE_HUB_START_CHARGING_UPRIGHT,
                 MAIN_USER_ID,
             )
 
@@ -144,19 +146,9 @@
             val shouldAutoOpen by collectLastValue(underTest.shouldAutoOpen)
             val suppressionReason by collectLastValue(underTest.suppressionReason)
 
-            fakeSettings.putBoolForUser(
-                Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP,
-                false,
-                MAIN_USER_ID,
-            )
-            fakeSettings.putBoolForUser(
-                Settings.Secure.SCREENSAVER_ACTIVATE_ON_DOCK,
-                false,
-                MAIN_USER_ID,
-            )
-            fakeSettings.putBoolForUser(
-                Settings.Secure.SCREENSAVER_ACTIVATE_ON_POSTURED,
-                false,
+            fakeSettings.putIntForUser(
+                Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB,
+                Settings.Secure.GLANCEABLE_HUB_START_NEVER,
                 MAIN_USER_ID,
             )
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt
index 310bf64..d6f7145 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractorTest.kt
@@ -21,10 +21,12 @@
 import android.content.Intent
 import android.content.pm.UserInfo
 import android.os.UserManager
+import android.provider.Settings
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.communal.shared.model.WhenToStartHub
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.collectLastValue
 import com.android.systemui.kosmos.runTest
@@ -32,6 +34,7 @@
 import com.android.systemui.settings.fakeUserTracker
 import com.android.systemui.testKosmos
 import com.android.systemui.user.data.repository.fakeUserRepository
+import com.android.systemui.util.settings.fakeSettings
 import org.junit.Assert.assertEquals
 import org.junit.Assert.assertNotNull
 import org.junit.Assert.assertNull
@@ -82,6 +85,19 @@
             assertEquals(USER_INFO_WORK.id, disallowedUser!!.id)
         }
 
+    @Test
+    fun whenToStartHub_matchesRepository() =
+        kosmos.runTest {
+            fakeSettings.putIntForUser(
+                Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB,
+                Settings.Secure.GLANCEABLE_HUB_START_CHARGING,
+                MAIN_USER_INFO.id,
+            )
+
+            val startCondition by collectLastValue(underTest.whenToStartHub)
+            assertEquals(startCondition, WhenToStartHub.WHILE_CHARGING)
+        }
+
     private fun setKeyguardFeaturesDisabled(user: UserInfo, disabledFlags: Int) {
         whenever(
                 kosmos.devicePolicyManager.getKeyguardDisabledFeatures(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
index df10d05..b08e676 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartableTest.kt
@@ -16,12 +16,14 @@
 
 package com.android.systemui.communal.widgets
 
+import android.appwidget.AppWidgetProviderInfo
 import android.content.pm.UserInfo
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.communal.data.repository.fakeCommunalWidgetRepository
+import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.domain.interactor.communalInteractor
 import com.android.systemui.communal.domain.interactor.communalSettingsInteractor
 import com.android.systemui.communal.domain.interactor.setCommunalEnabled
@@ -49,6 +51,7 @@
 import org.junit.runner.RunWith
 import org.mockito.Mock
 import org.mockito.Mockito.never
+import org.mockito.Mockito.spy
 import org.mockito.Mockito.verify
 import org.mockito.MockitoAnnotations
 
@@ -65,6 +68,7 @@
 
     private lateinit var appWidgetIdToRemove: MutableSharedFlow<Int>
 
+    private lateinit var communalInteractorSpy: CommunalInteractor
     private lateinit var underTest: CommunalAppWidgetHostStartable
 
     @Before
@@ -78,12 +82,13 @@
         helper = kosmos.fakeGlanceableHubMultiUserHelper
         appWidgetIdToRemove = MutableSharedFlow()
         whenever(appWidgetHost.appWidgetIdToRemove).thenReturn(appWidgetIdToRemove)
+        communalInteractorSpy = spy(kosmos.communalInteractor)
 
         underTest =
             CommunalAppWidgetHostStartable(
                 { appWidgetHost },
                 { communalWidgetHost },
-                { kosmos.communalInteractor },
+                { communalInteractorSpy },
                 { kosmos.communalSettingsInteractor },
                 { kosmos.keyguardInteractor },
                 { kosmos.fakeUserTracker },
@@ -259,6 +264,41 @@
         }
 
     @Test
+    fun removeNotLockscreenWidgets_whenCommunalIsAvailable() =
+        with(kosmos) {
+            testScope.runTest {
+                // Communal is available
+                setCommunalAvailable(true)
+                kosmos.fakeUserTracker.set(
+                    userInfos = listOf(MAIN_USER_INFO),
+                    selectedUserIndex = 0,
+                )
+                fakeCommunalWidgetRepository.addWidget(
+                    appWidgetId = 1,
+                    userId = MAIN_USER_INFO.id,
+                    category = AppWidgetProviderInfo.WIDGET_CATEGORY_NOT_KEYGUARD,
+                )
+                fakeCommunalWidgetRepository.addWidget(appWidgetId = 2, userId = MAIN_USER_INFO.id)
+                fakeCommunalWidgetRepository.addWidget(
+                    appWidgetId = 3,
+                    userId = MAIN_USER_INFO.id,
+                    category = AppWidgetProviderInfo.WIDGET_CATEGORY_NOT_KEYGUARD,
+                )
+
+                underTest.start()
+                runCurrent()
+
+                val communalWidgets by
+                    collectLastValue(fakeCommunalWidgetRepository.communalWidgets)
+                assertThat(communalWidgets).hasSize(1)
+                assertThat(communalWidgets!![0].appWidgetId).isEqualTo(2)
+
+                verify(communalInteractorSpy).deleteWidget(1)
+                verify(communalInteractorSpy).deleteWidget(3)
+            }
+        }
+
+    @Test
     fun onStartHeadlessSystemUser_registerWidgetManager_whenCommunalIsAvailable() =
         with(kosmos) {
             testScope.runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
index 197b0ee..358635e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayRepositoryTest.kt
@@ -26,6 +26,7 @@
 import android.view.IWindowManager
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.app.displaylib.DisplayRepository.PendingDisplay
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.FlowValue
 import com.android.systemui.coroutines.collectLastValue
@@ -71,19 +72,26 @@
     // that the initial state (soon after construction) contains the expected ones set in every
     // test.
     private val displayRepository: DisplayRepositoryImpl by lazy {
-        DisplayRepositoryImpl(
+        // TODO b/401305290 - move this to kosmos
+        val displayRepositoryFromLib =
+            com.android.app.displaylib.DisplayRepositoryImpl(
                 displayManager,
-                commandQueue,
-                windowManager,
                 testHandler,
-                TestScope(UnconfinedTestDispatcher()),
+                testScope.backgroundScope,
                 UnconfinedTestDispatcher(),
             )
-            .also {
-                verify(displayManager, never()).registerDisplayListener(any(), any())
-                // It needs to be called, just once, for the initial value.
-                verify(displayManager).getDisplays()
-            }
+        val displaysWithDecorRepository =
+            DisplaysWithDecorationsRepositoryImpl(
+                commandQueue,
+                windowManager,
+                testScope.backgroundScope,
+                displayRepositoryFromLib,
+            )
+        DisplayRepositoryImpl(displayRepositoryFromLib, displaysWithDecorRepository).also {
+            verify(displayManager, never()).registerDisplayListener(any(), any())
+            // It needs to be called, just once, for the initial value.
+            verify(displayManager).getDisplays()
+        }
     }
 
     @Before
@@ -403,7 +411,7 @@
             val pendingDisplay by lastPendingDisplay()
 
             sendOnDisplayConnected(1, TYPE_EXTERNAL)
-            val initialPendingDisplay: DisplayRepository.PendingDisplay? = pendingDisplay
+            val initialPendingDisplay: PendingDisplay? = pendingDisplay
             assertThat(pendingDisplay).isNotNull()
             sendOnDisplayChanged(1)
 
@@ -416,7 +424,7 @@
             val pendingDisplay by lastPendingDisplay()
 
             sendOnDisplayConnected(1, TYPE_EXTERNAL)
-            val initialPendingDisplay: DisplayRepository.PendingDisplay? = pendingDisplay
+            val initialPendingDisplay: PendingDisplay? = pendingDisplay
             assertThat(pendingDisplay).isNotNull()
             sendOnDisplayConnected(2, TYPE_EXTERNAL)
 
@@ -648,7 +656,7 @@
         return flowValue
     }
 
-    private fun TestScope.lastPendingDisplay(): FlowValue<DisplayRepository.PendingDisplay?> {
+    private fun TestScope.lastPendingDisplay(): FlowValue<PendingDisplay?> {
         val flowValue = collectLastValue(displayRepository.pendingDisplay)
         captureAddedRemovedListener()
         verify(displayManager)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt
deleted file mode 100644
index da7a723..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryImplTest.kt
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.display.data.repository
-
-import android.platform.test.annotations.EnableFlags
-import androidx.test.ext.junit.runners.AndroidJUnit4
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.kosmos.applicationCoroutineScope
-import com.android.systemui.kosmos.testDispatcher
-import com.android.systemui.kosmos.testScope
-import com.android.systemui.kosmos.useUnconfinedTestDispatcher
-import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
-import com.android.systemui.testKosmos
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.isActive
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-
-@EnableFlags(StatusBarConnectedDisplays.FLAG_NAME)
-@RunWith(AndroidJUnit4::class)
-@SmallTest
-class DisplayScopeRepositoryImplTest : SysuiTestCase() {
-
-    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
-    private val testScope = kosmos.testScope
-    private val fakeDisplayRepository = kosmos.displayRepository
-
-    private val repo =
-        DisplayScopeRepositoryImpl(
-            kosmos.applicationCoroutineScope,
-            kosmos.testDispatcher,
-            fakeDisplayRepository,
-        )
-
-    @Before
-    fun setUp() {
-        repo.start()
-    }
-
-    @Test
-    fun scopeForDisplay_multipleCallsForSameDisplayId_returnsSameInstance() {
-        val scopeForDisplay = repo.scopeForDisplay(displayId = 1)
-
-        assertThat(repo.scopeForDisplay(displayId = 1)).isSameInstanceAs(scopeForDisplay)
-    }
-
-    @Test
-    fun scopeForDisplay_differentDisplayId_returnsNewInstance() {
-        val scopeForDisplay1 = repo.scopeForDisplay(displayId = 1)
-        val scopeForDisplay2 = repo.scopeForDisplay(displayId = 2)
-
-        assertThat(scopeForDisplay1).isNotSameInstanceAs(scopeForDisplay2)
-    }
-
-    @Test
-    fun scopeForDisplay_activeByDefault() =
-        testScope.runTest {
-            val scopeForDisplay = repo.scopeForDisplay(displayId = 1)
-
-            assertThat(scopeForDisplay.isActive).isTrue()
-        }
-
-    @Test
-    fun scopeForDisplay_afterDisplayRemoved_scopeIsCancelled() =
-        testScope.runTest {
-            val scopeForDisplay = repo.scopeForDisplay(displayId = 1)
-
-            fakeDisplayRepository.removeDisplay(displayId = 1)
-
-            assertThat(scopeForDisplay.isActive).isFalse()
-        }
-
-    @Test
-    fun scopeForDisplay_afterDisplayRemoved_returnsNewInstance() =
-        testScope.runTest {
-            val initialScope = repo.scopeForDisplay(displayId = 1)
-
-            fakeDisplayRepository.removeDisplay(displayId = 1)
-
-            val newScope = repo.scopeForDisplay(displayId = 1)
-            assertThat(newScope).isNotSameInstanceAs(initialScope)
-        }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryInstanceProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryInstanceProviderTest.kt
new file mode 100644
index 0000000..8afaea3
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryInstanceProviderTest.kt
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.display.data.repository
+
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.isActive
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class DisplayScopeRepositoryInstanceProviderTest : SysuiTestCase() {
+
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
+    private val testScope = kosmos.testScope
+
+    private val underTest =
+        DisplayScopeRepositoryInstanceProvider(
+            kosmos.applicationCoroutineScope,
+            kosmos.testDispatcher,
+        )
+
+    @Test
+    fun createInstance_activeByDefault() =
+        testScope.runTest {
+            val scopeForDisplay = underTest.createInstance(displayId = 1)
+
+            assertThat(scopeForDisplay.isActive).isTrue()
+        }
+
+    @Test
+    fun destroyInstance_afterDisplayRemoved_scopeIsCancelled() =
+        testScope.runTest {
+            val scopeForDisplay = underTest.createInstance(displayId = 1)
+
+            underTest.destroyInstance(scopeForDisplay)
+
+            assertThat(scopeForDisplay.isActive).isFalse()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
index e41d46c..bf49d92 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/display/data/repository/PerDisplayInstanceRepositoryImplTest.kt
@@ -19,6 +19,7 @@
 import android.view.Display
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.dumpManager
 import com.android.systemui.kosmos.testScope
@@ -31,7 +32,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers.anyString
-import org.mockito.kotlin.eq
+import org.mockito.kotlin.any
 import org.mockito.kotlin.verify
 
 @RunWith(AndroidJUnit4::class)
@@ -43,9 +44,10 @@
     private val fakeDisplayRepository = kosmos.displayRepository
     private val fakePerDisplayInstanceProviderWithTeardown =
         kosmos.fakePerDisplayInstanceProviderWithTeardown
+    private val lifecycleManager = kosmos.fakeDisplayInstanceLifecycleManager
 
     private val underTest: PerDisplayInstanceRepositoryImpl<TestPerDisplayInstance> =
-        kosmos.fakePerDisplayInstanceRepository
+        kosmos.createPerDisplayInstanceRepository(overrideLifecycleManager = null)
 
     @Before
     fun addDisplays() = runBlocking {
@@ -105,9 +107,46 @@
 
     @Test
     fun start_registersDumpable() {
-        verify(kosmos.dumpManager).registerNormalDumpable(anyString(), eq(underTest))
+        verify(kosmos.dumpManager).registerNormalDumpable(anyString(), any())
     }
 
+    @Test
+    fun perDisplay_afterCustomLifecycleManagerRemovesDisplay_destroyInstanceInvoked() =
+        testScope.runTest {
+            val underTest =
+                kosmos.createPerDisplayInstanceRepository(
+                    overrideLifecycleManager = lifecycleManager
+                )
+            // Let's start with both
+            lifecycleManager.displayIds.value = setOf(DEFAULT_DISPLAY_ID, NON_DEFAULT_DISPLAY_ID)
+
+            val instance = underTest[NON_DEFAULT_DISPLAY_ID]
+
+            lifecycleManager.displayIds.value = setOf(DEFAULT_DISPLAY_ID)
+
+            // Now that the lifecycle manager says so, let's make sure it was destroyed
+            assertThat(fakePerDisplayInstanceProviderWithTeardown.destroyed)
+                .containsExactly(instance)
+        }
+
+    @Test
+    fun perDisplay_lifecycleManagerDoesNotContainIt_displayRepositoryDoes_returnsNull() =
+        testScope.runTest {
+            val underTest =
+                kosmos.createPerDisplayInstanceRepository(
+                    overrideLifecycleManager = lifecycleManager
+                )
+            // only default display, so getting for the non-default one should fail, despite the
+            // repository having both displays already
+            lifecycleManager.displayIds.value = setOf(DEFAULT_DISPLAY_ID)
+
+            assertThat(underTest[NON_DEFAULT_DISPLAY_ID]).isNull()
+
+            lifecycleManager.displayIds.value = setOf(DEFAULT_DISPLAY_ID, NON_DEFAULT_DISPLAY_ID)
+
+            assertThat(underTest[NON_DEFAULT_DISPLAY_ID]).isNotNull()
+        }
+
     private fun createDisplay(displayId: Int): Display =
         display(type = Display.TYPE_INTERNAL, id = displayId)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
deleted file mode 100644
index ccadd14..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.conditions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener;
-import com.android.systemui.shared.condition.Condition;
-
-import kotlinx.coroutines.CoroutineScope;
-
-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;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@android.platform.test.annotations.EnabledOnRavenwood
-public class AssistantAttentionConditionTest extends SysuiTestCase {
-    @Mock
-    Condition.Callback mCallback;
-    @Mock
-    AssistManager mAssistManager;
-    @Mock
-    CoroutineScope mScope;
-
-    private AssistantAttentionCondition mAssistantAttentionCondition;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        mAssistantAttentionCondition = new AssistantAttentionCondition(mScope, mAssistManager);
-        // Adding a callback also starts the condition.
-        mAssistantAttentionCondition.addCallback(mCallback);
-    }
-
-    @Test
-    public void testEnableVisualQueryDetection() {
-        verify(mAssistManager).addVisualQueryAttentionListener(
-                any(VisualQueryAttentionListener.class));
-    }
-
-    @Test
-    public void testDisableVisualQueryDetection() {
-        mAssistantAttentionCondition.stop();
-        verify(mAssistManager).removeVisualQueryAttentionListener(
-                any(VisualQueryAttentionListener.class));
-    }
-
-    @Test
-    public void testAttentionChangedTriggersCondition() {
-        final ArgumentCaptor<VisualQueryAttentionListener> argumentCaptor =
-                ArgumentCaptor.forClass(VisualQueryAttentionListener.class);
-        verify(mAssistManager).addVisualQueryAttentionListener(argumentCaptor.capture());
-
-        argumentCaptor.getValue().onAttentionGained();
-        assertThat(mAssistantAttentionCondition.isConditionMet()).isTrue();
-
-        argumentCaptor.getValue().onAttentionLost();
-        assertThat(mAssistantAttentionCondition.isConditionMet()).isFalse();
-
-        verify(mCallback, times(2)).onConditionChanged(eq(mAssistantAttentionCondition));
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.kt
new file mode 100644
index 0000000..eefc61a
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/AssistantAttentionConditionTest.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dreams.conditions
+
+import android.platform.test.annotations.EnabledOnRavenwood
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.assist.AssistManager
+import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shared.condition.Condition
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnabledOnRavenwood
+class AssistantAttentionConditionTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+
+    @Mock private lateinit var callback: Condition.Callback
+
+    @Mock private lateinit var assistManager: AssistManager
+
+    private lateinit var underTest: AssistantAttentionCondition
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        underTest = AssistantAttentionCondition(kosmos.testScope, assistManager)
+        // Adding a callback also starts the condition.
+        underTest.addCallback(callback)
+    }
+
+    @Test
+    fun testEnableVisualQueryDetection() =
+        kosmos.runTest { Mockito.verify(assistManager).addVisualQueryAttentionListener(any()) }
+
+    @Test
+    fun testDisableVisualQueryDetection() =
+        kosmos.runTest {
+            underTest.stop()
+            Mockito.verify(assistManager).removeVisualQueryAttentionListener(any())
+        }
+
+    @Test
+    fun testAttentionChangedTriggersCondition() =
+        kosmos.runTest {
+            val argumentCaptor = argumentCaptor<VisualQueryAttentionListener>()
+            Mockito.verify(assistManager).addVisualQueryAttentionListener(argumentCaptor.capture())
+
+            argumentCaptor.lastValue.onAttentionGained()
+            Truth.assertThat(underTest.isConditionMet).isTrue()
+
+            argumentCaptor.lastValue.onAttentionLost()
+            Truth.assertThat(underTest.isConditionMet).isFalse()
+
+            Mockito.verify(callback, Mockito.times(2)).onConditionChanged(eq(underTest))
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
deleted file mode 100644
index 58c17e2..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.conditions;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.DreamManager;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.shared.condition.Condition;
-
-import kotlinx.coroutines.CoroutineScope;
-
-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;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-@android.platform.test.annotations.EnabledOnRavenwood
-public class DreamConditionTest extends SysuiTestCase {
-    @Mock
-    Condition.Callback mCallback;
-
-    @Mock
-    DreamManager mDreamManager;
-
-    @Mock
-    KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-
-    @Mock
-    CoroutineScope mScope;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    /**
-     * Ensure a dreaming state immediately triggers the condition.
-     */
-    @Test
-    public void testInitialDreamingState() {
-        when(mDreamManager.isDreaming()).thenReturn(true);
-        final DreamCondition condition = new DreamCondition(mScope, mDreamManager,
-                mKeyguardUpdateMonitor);
-        condition.addCallback(mCallback);
-
-        verify(mCallback).onConditionChanged(eq(condition));
-        assertThat(condition.isConditionMet()).isTrue();
-    }
-
-    /**
-     * Ensure a non-dreaming state does not trigger the condition.
-     */
-    @Test
-    public void testInitialNonDreamingState() {
-        when(mDreamManager.isDreaming()).thenReturn(false);
-        final DreamCondition condition = new DreamCondition(mScope, mDreamManager,
-                mKeyguardUpdateMonitor);
-        condition.addCallback(mCallback);
-
-        verify(mCallback, never()).onConditionChanged(eq(condition));
-        assertThat(condition.isConditionMet()).isFalse();
-    }
-
-    /**
-     * Ensure that changing dream state triggers condition.
-     */
-    @Test
-    public void testChange() {
-        final ArgumentCaptor<KeyguardUpdateMonitorCallback> callbackCaptor =
-                ArgumentCaptor.forClass(KeyguardUpdateMonitorCallback.class);
-        when(mDreamManager.isDreaming()).thenReturn(true);
-        final DreamCondition condition = new DreamCondition(mScope, mDreamManager,
-                mKeyguardUpdateMonitor);
-        condition.addCallback(mCallback);
-        verify(mKeyguardUpdateMonitor).registerCallback(callbackCaptor.capture());
-
-        clearInvocations(mCallback);
-        callbackCaptor.getValue().onDreamingStateChanged(false);
-        verify(mCallback).onConditionChanged(eq(condition));
-        assertThat(condition.isConditionMet()).isFalse();
-
-        clearInvocations(mCallback);
-        callbackCaptor.getValue().onDreamingStateChanged(true);
-        verify(mCallback).onConditionChanged(eq(condition));
-        assertThat(condition.isConditionMet()).isTrue();
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.kt
new file mode 100644
index 0000000..302a6e1
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/dreams/conditions/DreamConditionTest.kt
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dreams.conditions
+
+import android.app.DreamManager
+import android.platform.test.annotations.EnabledOnRavenwood
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shared.condition.Condition
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+@EnabledOnRavenwood
+class DreamConditionTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+
+    @Mock private lateinit var callback: Condition.Callback
+
+    @Mock private lateinit var dreamManager: DreamManager
+
+    @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    /** Ensure a dreaming state immediately triggers the condition. */
+    @Test
+    fun testInitialDreamingState() =
+        kosmos.runTest {
+            whenever(dreamManager.isDreaming).thenReturn(true)
+            val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor)
+            condition.addCallback(callback)
+            runCurrent()
+
+            Mockito.verify(callback).onConditionChanged(eq(condition))
+            Truth.assertThat(condition.isConditionMet).isTrue()
+        }
+
+    /** Ensure a non-dreaming state does not trigger the condition. */
+    @Test
+    fun testInitialNonDreamingState() =
+        kosmos.runTest {
+            whenever(dreamManager.isDreaming).thenReturn(false)
+            val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor)
+            condition.addCallback(callback)
+
+            Mockito.verify(callback, Mockito.never()).onConditionChanged(eq(condition))
+            Truth.assertThat(condition.isConditionMet).isFalse()
+        }
+
+    /** Ensure that changing dream state triggers condition. */
+    @Test
+    fun testChange() =
+        kosmos.runTest {
+            val callbackCaptor = argumentCaptor<KeyguardUpdateMonitorCallback>()
+            whenever(dreamManager.isDreaming).thenReturn(true)
+            val condition = DreamCondition(testScope, dreamManager, keyguardUpdateMonitor)
+            condition.addCallback(callback)
+            runCurrent()
+            Mockito.verify(keyguardUpdateMonitor).registerCallback(callbackCaptor.capture())
+
+            Mockito.clearInvocations(callback)
+            callbackCaptor.lastValue.onDreamingStateChanged(false)
+            runCurrent()
+            Mockito.verify(callback).onConditionChanged(eq(condition))
+            Truth.assertThat(condition.isConditionMet).isFalse()
+
+            Mockito.clearInvocations(callback)
+            callbackCaptor.lastValue.onDreamingStateChanged(true)
+            runCurrent()
+            Mockito.verify(callback).onConditionChanged(eq(condition))
+            Truth.assertThat(condition.isConditionMet).isTrue()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
index f2a6c11..7229761 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/education/data/repository/ContextualEducationRepositoryTest.kt
@@ -26,9 +26,9 @@
 import com.android.systemui.education.data.model.EduDeviceConnectionTime
 import com.android.systemui.education.data.model.GestureEduModel
 import com.android.systemui.education.domain.interactor.mockEduInputManager
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import java.io.File
 import javax.inject.Provider
@@ -48,7 +48,7 @@
 class ContextualEducationRepositoryTest : SysuiTestCase() {
 
     private lateinit var underTest: UserContextualEducationRepository
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val dsScopeProvider: Provider<CoroutineScope> = Provider {
         TestScope(kosmos.testDispatcher).backgroundScope
@@ -70,7 +70,7 @@
                 testContext,
                 dsScopeProvider,
                 kosmos.mockEduInputManager,
-                kosmos.testDispatcher
+                kosmos.testDispatcher,
             )
         underTest.setUser(testUserId)
     }
@@ -109,7 +109,7 @@
                     lastEducationTime = kosmos.fakeEduClock.instant(),
                     usageSessionStartTime = kosmos.fakeEduClock.instant(),
                     userId = testUserId,
-                    gestureType = BACK
+                    gestureType = BACK,
                 )
             underTest.updateGestureEduModel(BACK) { newModel }
             val model by collectLastValue(underTest.readGestureEduModelFlow(BACK))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt
index 5030d1e..0f75e57c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/haptics/slider/HapticSliderPluginTest.kt
@@ -21,9 +21,9 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.haptics.msdl.msdlPlayer
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.statusbar.VibratorHelper
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.fakeSystemClock
 import com.google.common.truth.Truth.assertThat
@@ -45,7 +45,7 @@
 @RunWith(AndroidJUnit4::class)
 class HapticSliderPluginTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
 
     @Rule @JvmField val mMockitoRule: MockitoRule = MockitoJUnit.rule()
     @Mock private lateinit var vibratorHelper: VibratorHelper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt
index 798c5ab..39b5e81 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputdevice/data/repository/UserInputDeviceRepositoryTest.kt
@@ -23,9 +23,9 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.inputdevice.data.model.UserDeviceConnectionStatus
 import com.android.systemui.keyboard.data.repository.keyboardRepository
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.android.systemui.touchpad.data.repository.touchpadRepository
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.android.systemui.user.data.repository.userRepository
@@ -41,7 +41,7 @@
 class UserInputDeviceRepositoryTest : SysuiTestCase() {
 
     private lateinit var underTest: UserInputDeviceRepository
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val keyboardRepository = kosmos.keyboardRepository
     private val touchpadRepository = kosmos.touchpadRepository
@@ -54,7 +54,7 @@
                 kosmos.testDispatcher,
                 keyboardRepository,
                 touchpadRepository,
-                kosmos.userRepository
+                kosmos.userRepository,
             )
         userRepository.setUserInfos(USER_INFOS)
     }
@@ -72,7 +72,7 @@
             assertThat(isAnyKeyboardConnected)
                 .containsExactly(
                     UserDeviceConnectionStatus(isConnected = true, USER_INFOS[0].id),
-                    UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id)
+                    UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id),
                 )
                 .inOrder()
         }
@@ -90,16 +90,13 @@
             assertThat(isAnyTouchpadConnected)
                 .containsExactly(
                     UserDeviceConnectionStatus(isConnected = true, USER_INFOS[0].id),
-                    UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id)
+                    UserDeviceConnectionStatus(isConnected = true, USER_INFOS[1].id),
                 )
                 .inOrder()
         }
 
     companion object {
         private val USER_INFOS =
-            listOf(
-                UserInfo(100, "First User", 0),
-                UserInfo(101, "Second User", 0),
-            )
+            listOf(UserInfo(100, "First User", 0), UserInfo(101, "Second User", 0))
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt
index 274880b..6bd0fb0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/data/repository/InputMethodRepositoryTest.kt
@@ -23,9 +23,9 @@
 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.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
@@ -47,7 +47,7 @@
 
     @Mock private lateinit var inputMethodManager: InputMethodManager
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
     private lateinit var underTest: InputMethodRepository
@@ -72,7 +72,7 @@
                     inputMethodManager.getEnabledInputMethodSubtypeListAsUser(
                         any(),
                         anyBoolean(),
-                        eq(USER_HANDLE)
+                        eq(USER_HANDLE),
                     )
                 )
                 .thenReturn(listOf())
@@ -97,7 +97,7 @@
                     inputMethodManager.getEnabledInputMethodSubtypeListAsUser(
                         eq(selectedImiId),
                         anyBoolean(),
-                        eq(USER_HANDLE)
+                        eq(USER_HANDLE),
                     )
                 )
                 .thenReturn(
@@ -125,7 +125,7 @@
             verify(inputMethodManager)
                 .showInputMethodPickerFromSystem(
                     /* showAuxiliarySubtypes = */ eq(true),
-                    /* displayId = */ eq(displayId)
+                    /* displayId = */ eq(displayId),
                 )
         }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt
index 8e6de2f..9e129a4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/inputmethod/domain/interactor/InputMethodInteractorTest.kt
@@ -22,8 +22,8 @@
 import com.android.systemui.inputmethod.data.model.InputMethodModel
 import com.android.systemui.inputmethod.data.repository.fakeInputMethodRepository
 import com.android.systemui.inputmethod.data.repository.inputMethodRepository
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import java.util.UUID
 import kotlinx.coroutines.test.runTest
@@ -34,7 +34,7 @@
 @RunWith(AndroidJUnit4::class)
 class InputMethodInteractorTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val fakeInputMethodRepository = kosmos.fakeInputMethodRepository
 
@@ -148,7 +148,7 @@
             subtypes =
                 List(auxiliarySubtypes + nonAuxiliarySubtypes) {
                     InputMethodModel.Subtype(subtypeId = it, isAuxiliary = it < auxiliarySubtypes)
-                }
+                },
         )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
index 1bb4805..655c646 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperDialogStarterTest.kt
@@ -34,7 +34,6 @@
 import com.android.systemui.keyboard.shortcut.shortcutHelperSystemShortcutsSource
 import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
 import com.android.systemui.keyboard.shortcut.shortcutHelperViewModel
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testDispatcher
@@ -43,6 +42,7 @@
 import com.android.systemui.settings.FakeUserTracker
 import com.android.systemui.settings.userTracker
 import com.android.systemui.statusbar.phone.systemUIDialogFactory
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import kotlinx.coroutines.test.runTest
@@ -60,7 +60,7 @@
     private val fakeMultiTaskingSource = FakeKeyboardShortcutGroupsSource()
     private val mockUserContext: Context = mock()
     private val kosmos =
-        Kosmos().also {
+        testKosmos().also {
             it.testCase = this
             it.testDispatcher = UnconfinedTestDispatcher()
             it.shortcutHelperSystemShortcutsSource = fakeSystemSource
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt
index be9e93c..ba57ffd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/StickyKeysIndicatorCoordinatorTest.kt
@@ -26,7 +26,7 @@
 import com.android.systemui.keyboard.stickykeys.shared.model.Locked
 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.SHIFT
 import com.android.systemui.keyboard.stickykeys.ui.viewmodel.StickyKeysIndicatorViewModel
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -52,19 +52,19 @@
     fun setup() {
         val dialogFactory = mock<StickyKeyDialogFactory>()
         whenever(dialogFactory.create(any())).thenReturn(dialog)
-        val keyboardRepository = Kosmos().keyboardRepository
+        val keyboardRepository = testKosmos().keyboardRepository
         val viewModel =
             StickyKeysIndicatorViewModel(
                 stickyKeysRepository,
                 keyboardRepository,
-                testScope.backgroundScope
+                testScope.backgroundScope,
             )
         coordinator =
             StickyKeysIndicatorCoordinator(
                 testScope.backgroundScope,
                 dialogFactory,
                 viewModel,
-                mock<StickyKeysLogger>()
+                mock<StickyKeysLogger>(),
             )
         coordinator.startListening()
         keyboardRepository.setIsAnyKeyboardConnected(true)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt
index 9daf0ff..642b2e3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyboard/stickykeys/ui/viewmodel/StickyKeysIndicatorViewModelTest.kt
@@ -33,7 +33,6 @@
 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.CTRL
 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.META
 import com.android.systemui.keyboard.stickykeys.shared.model.ModifierKey.SHIFT
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
@@ -64,7 +63,7 @@
     private val inputManager = mock<InputManager>()
     private val keyboardRepository = FakeKeyboardRepository()
     private val secureSettings = kosmos.fakeSettings
-    private val userRepository = Kosmos().fakeUserRepository
+    private val userRepository = testKosmos().fakeUserRepository
     private val captor =
         ArgumentCaptor.forClass(InputManager.StickyModifierStateListener::class.java)
 
@@ -117,9 +116,9 @@
     }
 
     private fun setStickyKeySetting(enabled: Boolean) {
-        val newValue = if (enabled) "1" else "0"
+        val newValue = if (enabled) 1 else 0
         val defaultUser = userRepository.getSelectedUserInfo().id
-        secureSettings.putStringForUser(ACCESSIBILITY_STICKY_KEYS, newValue, defaultUser)
+        secureSettings.putIntForUser(ACCESSIBILITY_STICKY_KEYS, newValue, defaultUser)
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
index baf3b5b..3f1cadc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
@@ -23,12 +23,12 @@
 import com.android.systemui.defaultDeviceState
 import com.android.systemui.deviceStateManager
 import com.android.systemui.flags.FeatureFlags
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.shared.system.smartspace.ILauncherUnlockAnimationController
 import com.android.systemui.statusbar.NotificationShadeWindowController
 import com.android.systemui.statusbar.SysuiStatusBarStateController
 import com.android.systemui.statusbar.phone.BiometricUnlockController
 import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argThat
 import java.util.function.Predicate
@@ -68,7 +68,7 @@
     @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
     @Mock private lateinit var powerManager: PowerManager
     @Mock private lateinit var wallpaperManager: WallpaperManager
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val deviceStateManager = kosmos.deviceStateManager
 
     @Mock
@@ -92,7 +92,7 @@
             surfaceControl1,
             Rect(),
             mock(ActivityManager.RunningTaskInfo::class.java),
-            false
+            false,
         )
 
     private var surfaceControl2 = mock(SurfaceControl::class.java)
@@ -113,7 +113,7 @@
             surfaceControl2,
             Rect(),
             mock(ActivityManager.RunningTaskInfo::class.java),
-            false
+            false,
         )
     private lateinit var remoteAnimationTargets: Array<RemoteAnimationTarget>
 
@@ -135,7 +135,7 @@
             surfaceControlWp,
             Rect(),
             mock(ActivityManager.RunningTaskInfo::class.java),
-            false
+            false,
         )
     private lateinit var wallpaperTargets: Array<RemoteAnimationTarget>
 
@@ -157,7 +157,7 @@
             surfaceControlLockWp,
             Rect(),
             mock(ActivityManager.RunningTaskInfo::class.java),
-            false
+            false,
         )
     private lateinit var lockWallpaperTargets: Array<RemoteAnimationTarget>
     private var shouldPerformSmartspaceTransition = false
@@ -179,14 +179,14 @@
                     notificationShadeWindowController,
                     powerManager,
                     wallpaperManager,
-                    deviceStateManager
+                    deviceStateManager,
                 ) {
                 override fun shouldPerformSmartspaceTransition(): Boolean =
                     shouldPerformSmartspaceTransition
             }
         keyguardUnlockAnimationController.setLauncherUnlockController(
             "",
-            launcherUnlockAnimationController
+            launcherUnlockAnimationController,
         )
 
         whenever(keyguardViewController.viewRootImpl).thenReturn(mock(ViewRootImpl::class.java))
@@ -227,7 +227,7 @@
             arrayOf(),
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         val captorSb = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
@@ -259,7 +259,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         // Since the animation is running, we should not have finished the remote animation.
@@ -282,7 +282,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         verify(listener).onUnlockAnimationStarted(any(), eq(true), any(), any())
@@ -303,7 +303,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         verify(listener).onUnlockAnimationStarted(any(), eq(false), any(), any())
@@ -327,7 +327,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            true /* requestedShowSurfaceBehindKeyguard */
+            true, /* requestedShowSurfaceBehindKeyguard */
         )
 
         assertTrue(keyguardUnlockAnimationController.surfaceBehindAlphaAnimator.isRunning)
@@ -351,7 +351,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            true /* requestedShowSurfaceBehindKeyguard */
+            true, /* requestedShowSurfaceBehindKeyguard */
         )
 
         assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
@@ -373,7 +373,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
@@ -389,7 +389,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            true /* requestedShowSurfaceBehindKeyguard */
+            true, /* requestedShowSurfaceBehindKeyguard */
         )
 
         assertFalse(keyguardUnlockAnimationController.canPerformInWindowLauncherAnimations())
@@ -406,7 +406,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         assertTrue(keyguardUnlockAnimationController.isPlayingCannedUnlockAnimation())
@@ -427,7 +427,7 @@
             wallpaperTargets,
             lockWallpaperTargets,
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         for (i in 0..10) {
@@ -471,7 +471,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         // Cancel the animator so we can verify only the setSurfaceBehind call below.
@@ -492,7 +492,7 @@
         val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
         verify(
                 surfaceTransactionApplier,
-                times(1).description("WallpaperSurface was expected to receive scheduleApply once")
+                times(1).description("WallpaperSurface was expected to receive scheduleApply once"),
             )
             .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp })
 
@@ -523,7 +523,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         // Cancel the animator so we can verify only the setSurfaceBehind call below.
@@ -539,7 +539,7 @@
         val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
         verify(
                 surfaceTransactionApplier,
-                atLeastOnce().description("Wallpaper surface has  not " + "received scheduleApply")
+                atLeastOnce().description("Wallpaper surface has  not " + "received scheduleApply"),
             )
             .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp })
 
@@ -562,7 +562,7 @@
             wallpaperTargets,
             arrayOf(),
             0 /* startTime */,
-            false /* requestedShowSurfaceBehindKeyguard */
+            false, /* requestedShowSurfaceBehindKeyguard */
         )
 
         // Stop the animator - we just want to test whether the override is not applied.
@@ -578,7 +578,7 @@
         val captorWp = ArgThatCaptor<SyncRtSurfaceTransactionApplier.SurfaceParams>()
         verify(
                 surfaceTransactionApplier,
-                atLeastOnce().description("Wallpaper surface has  not " + "received scheduleApply")
+                atLeastOnce().description("Wallpaper surface has  not " + "received scheduleApply"),
             )
             .scheduleApply(captorWp.capture { sp -> sp.surface == surfaceControlWp })
 
@@ -588,7 +588,7 @@
         assertEquals(
             "Wallpaper surface was expected to have opacity 1",
             1f,
-            captorWp.getLastValue().alpha
+            captorWp.getLastValue().alpha,
         )
 
         verifyNoMoreInteractions(surfaceTransactionApplier)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
index 6bc8000..04f7fe1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/mediarouter/data/repository/MediaRouterRepositoryTest.kt
@@ -21,10 +21,10 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.statusbar.policy.CastDevice
 import com.android.systemui.statusbar.policy.fakeCastController
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlinx.coroutines.test.runCurrent
@@ -34,7 +34,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MediaRouterRepositoryTest : SysuiTestCase() {
-    val kosmos = Kosmos()
+    val kosmos = testKosmos()
     val testScope = kosmos.testScope
     val castController = kosmos.fakeCastController
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java
deleted file mode 100644
index 5250d56..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.process.condition;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-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.process.ProcessWrapper;
-import com.android.systemui.shared.condition.Condition;
-import com.android.systemui.shared.condition.Monitor;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidJUnit4.class)
-@TestableLooper.RunWithLooper
-@SmallTest
-public class SystemProcessConditionTest extends SysuiTestCase {
-    @Mock
-    ProcessWrapper mProcessWrapper;
-
-    @Mock
-    Monitor.Callback mCallback;
-
-    @Mock
-    CoroutineScope mScope;
-
-    private final FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-    }
-
-    /**
-     * Verifies condition reports false when tracker reports the process is being ran by the
-     * system user.
-     */
-    @Test
-    public void testConditionFailsWithNonSystemProcess() {
-
-        final Condition condition = new SystemProcessCondition(mScope, mProcessWrapper);
-        when(mProcessWrapper.isSystemUser()).thenReturn(false);
-
-        final Monitor monitor = new Monitor(mExecutor);
-
-        monitor.addSubscription(new Monitor.Subscription.Builder(mCallback)
-                .addCondition(condition)
-                .build());
-
-        mExecutor.runAllReady();
-
-        verify(mCallback).onConditionsChanged(false);
-    }
-
-    /**
-     * Verifies condition reports true when tracker reports the process is being ran by the
-     * system user.
-     */
-    @Test
-    public void testConditionSucceedsWithSystemProcess() {
-
-        final Condition condition = new SystemProcessCondition(mScope, mProcessWrapper);
-        when(mProcessWrapper.isSystemUser()).thenReturn(true);
-
-        final Monitor monitor = new Monitor(mExecutor);
-
-        monitor.addSubscription(new Monitor.Subscription.Builder(mCallback)
-                .addCondition(condition)
-                .build());
-
-        mExecutor.runAllReady();
-
-        verify(mCallback).onConditionsChanged(true);
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.kt
new file mode 100644
index 0000000..21524d9
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/process/condition/SystemProcessConditionTest.kt
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.process.condition
+
+import android.testing.TestableLooper.RunWithLooper
+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.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.process.ProcessWrapper
+import com.android.systemui.shared.condition.Condition
+import com.android.systemui.shared.condition.Monitor
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.whenever
+
+@RunWith(AndroidJUnit4::class)
+@RunWithLooper
+@SmallTest
+class SystemProcessConditionTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+
+    @Mock private lateinit var processWrapper: ProcessWrapper
+
+    @Mock private lateinit var callback: Monitor.Callback
+
+    private val executor = FakeExecutor(FakeSystemClock())
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+    }
+
+    /**
+     * Verifies condition reports false when tracker reports the process is being ran by the system
+     * user.
+     */
+    @Test
+    fun testConditionFailsWithNonSystemProcess() =
+        kosmos.runTest {
+            val condition: Condition = SystemProcessCondition(kosmos.testScope, processWrapper)
+            whenever(processWrapper.isSystemUser).thenReturn(false)
+
+            val monitor = Monitor(executor)
+
+            monitor.addSubscription(
+                Monitor.Subscription.Builder(callback).addCondition(condition).build()
+            )
+
+            executor.runAllReady()
+            runCurrent()
+            executor.runAllReady()
+
+            Mockito.verify(callback).onConditionsChanged(false)
+        }
+
+    /**
+     * Verifies condition reports true when tracker reports the process is being ran by the system
+     * user.
+     */
+    @Test
+    fun testConditionSucceedsWithSystemProcess() =
+        kosmos.runTest {
+            val condition: Condition = SystemProcessCondition(testScope, processWrapper)
+            whenever(processWrapper.isSystemUser).thenReturn(true)
+
+            val monitor = Monitor(executor)
+
+            monitor.addSubscription(
+                Monitor.Subscription.Builder(callback).addCondition(condition).build()
+            )
+
+            executor.runAllReady()
+            runCurrent()
+            executor.runAllReady()
+
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java
index 0f63150..d9990ba 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qrcodescanner/controller/QRCodeScannerControllerTest.java
@@ -275,14 +275,14 @@
         setUpLocal(/* deviceConfigActivity */ null, /* defaultActivity */
                 "abc/.def", /* validateActivity */ true, /* enableSetting */true,
                 /* enableOnLockScreen */ true);
-        mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "0",
+        mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 0,
                 UserHandle.USER_CURRENT);
-        mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "0",
+        mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 0,
                 UserHandle.USER_CURRENT);
 
-        mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "1",
+        mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 1,
                 UserHandle.USER_CURRENT);
-        mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "1",
+        mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 1,
                 UserHandle.USER_CURRENT);
         // Once from setup + twice from this function
         verify(mCallback, times(3)).onQRCodeScannerPreferenceChanged();
@@ -297,14 +297,14 @@
         assertThat(mController.isEnabledForLockScreenButton()).isTrue();
         assertThat(mController.isAbleToLaunchScannerActivity()).isTrue();
 
-        mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "0",
+        mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 0,
                 UserHandle.USER_CURRENT);
         verifyActivityDetails("abc/.def");
         assertThat(mController.isEnabledForLockScreenButton()).isTrue();
         assertThat(mController.isAllowedOnLockScreen()).isTrue();
         assertThat(mController.isAbleToLaunchScannerActivity()).isTrue();
 
-        mSecureSettings.putStringForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, "1",
+        mSecureSettings.putIntForUser(LOCK_SCREEN_SHOW_QR_CODE_SCANNER, 1,
                 UserHandle.USER_CURRENT);
         verifyActivityDetails("abc/.def");
         assertThat(mController.isEnabledForLockScreenButton()).isTrue();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt
index 858ed6a..473d7b6d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/UserSettingObserverTest.kt
@@ -22,8 +22,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.SecureSettings
 import com.android.systemui.util.settings.fakeSettings
 import com.google.common.truth.Truth.assertThat
@@ -64,7 +64,7 @@
         mSetFlagsRule.setFlagsParameterization(flags)
     }
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
     private lateinit var testableLooper: TestableLooper
@@ -85,7 +85,7 @@
                     Handler(testableLooper.looper),
                     TEST_SETTING,
                     USER,
-                    DEFAULT_VALUE
+                    DEFAULT_VALUE,
                 ) {
                 override fun handleValueChanged(value: Int, observedChange: Boolean) {
                     callback(value, observedChange)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
index 053a59a..5f8adf0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorTest.kt
@@ -32,12 +32,12 @@
 import com.android.systemui.qs.pipeline.data.repository.fakeInstalledTilesRepository
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.shared.model.TileCategory
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.fakeQSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.qSTileConfigProvider
 import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
 import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
 import com.android.systemui.qs.tiles.impl.internet.qsInternetTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.fakeQSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider
 import com.android.systemui.settings.userTracker
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
@@ -58,12 +58,7 @@
     private val batteryTileConfig = kosmos.qsBatterySaverTileConfig
 
     private val serviceInfo =
-        FakeInstalledTilesComponentRepository.ServiceInfo(
-            component,
-            tileName,
-            icon,
-            appName,
-        )
+        FakeInstalledTilesComponentRepository.ServiceInfo(component, tileName, icon, appName)
 
     private val underTest =
         with(kosmos) {
@@ -79,7 +74,7 @@
         with(kosmos) {
             fakeInstalledTilesRepository.setInstalledServicesForUser(
                 userTracker.userId,
-                listOf(serviceInfo)
+                listOf(serviceInfo),
             )
 
             with(fakeQSTileConfigProvider) {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorTest.kt
index 9d2528d..530ca95 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorTest.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
 import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.AIRPLANE_MODE_TILE_SPEC
 import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.HOTSPOT_TILE_SPEC
 import com.android.systemui.statusbar.policy.PolicyModule.Companion.WORK_MODE_TILE_SPEC
@@ -38,61 +38,72 @@
 @RunWith(AndroidJUnit4::class)
 @SmallTest
 class NewTilesAvailabilityInteractorTest : SysuiTestCase() {
-    private val kosmos = testKosmos().apply {
-        tileAvailabilityInteractorsMap = buildMap {
-            put(AIRPLANE_MODE_TILE_SPEC, QSTileAvailabilityInteractor.AlwaysAvailableInteractor)
-            put(WORK_MODE_TILE_SPEC, FakeTileAvailabilityInteractor(
-                    mapOf(
-                       fakeUserRepository.getSelectedUserInfo().id to flowOf(true),
-                    ).withDefault { flowOf(false) }
-            ))
-            put(HOTSPOT_TILE_SPEC, FakeTileAvailabilityInteractor(
-                    emptyMap<Int, Flow<Boolean>>().withDefault { flowOf(false) }
-            ))
+    private val kosmos =
+        testKosmos().apply {
+            tileAvailabilityInteractorsMap = buildMap {
+                put(AIRPLANE_MODE_TILE_SPEC, QSTileAvailabilityInteractor.AlwaysAvailableInteractor)
+                put(
+                    WORK_MODE_TILE_SPEC,
+                    FakeTileAvailabilityInteractor(
+                        mapOf(fakeUserRepository.getSelectedUserInfo().id to flowOf(true))
+                            .withDefault { flowOf(false) }
+                    ),
+                )
+                put(
+                    HOTSPOT_TILE_SPEC,
+                    FakeTileAvailabilityInteractor(
+                        emptyMap<Int, Flow<Boolean>>().withDefault { flowOf(false) }
+                    ),
+                )
+            }
         }
-    }
 
     private val underTest by lazy { kosmos.newTilesAvailabilityInteractor }
 
     @Test
-    fun defaultUser_getAvailabilityFlow() = with(kosmos) {
-        testScope.runTest {
-            val availability by collectLastValue(underTest.newTilesAvailable)
+    fun defaultUser_getAvailabilityFlow() =
+        with(kosmos) {
+            testScope.runTest {
+                val availability by collectLastValue(underTest.newTilesAvailable)
 
-            assertThat(availability).isEqualTo(
-                    mapOf(
+                assertThat(availability)
+                    .isEqualTo(
+                        mapOf(
                             TileSpec.create(AIRPLANE_MODE_TILE_SPEC) to true,
                             TileSpec.create(WORK_MODE_TILE_SPEC) to true,
                             TileSpec.create(HOTSPOT_TILE_SPEC) to false,
+                        )
                     )
-            )
+            }
         }
-    }
 
     @Test
-    fun getAvailabilityFlow_userChange() = with(kosmos) {
-        testScope.runTest {
-            val availability by collectLastValue(underTest.newTilesAvailable)
-            fakeUserRepository.asMainUser()
+    fun getAvailabilityFlow_userChange() =
+        with(kosmos) {
+            testScope.runTest {
+                val availability by collectLastValue(underTest.newTilesAvailable)
+                fakeUserRepository.asMainUser()
 
-            assertThat(availability).isEqualTo(
-                    mapOf(
+                assertThat(availability)
+                    .isEqualTo(
+                        mapOf(
                             TileSpec.create(AIRPLANE_MODE_TILE_SPEC) to true,
                             TileSpec.create(WORK_MODE_TILE_SPEC) to false,
                             TileSpec.create(HOTSPOT_TILE_SPEC) to false,
+                        )
                     )
-            )
+            }
         }
-    }
 
     @Test
-    fun noAvailabilityInteractor_emptyMap() = with(kosmos) {
-        testScope.runTest {
-            tileAvailabilityInteractorsMap = emptyMap()
+    fun noAvailabilityInteractor_emptyMap() =
+        with(kosmos) {
+            testScope.runTest {
+                tileAvailabilityInteractorsMap = emptyMap()
 
-            val availability by collectLastValue(underTest.newTilesAvailable)
+                val availability by collectLastValue(underTest.newTilesAvailable)
 
-            assertThat(availability).isEmpty()
+                assertThat(availability).isEmpty()
+            }
         }
-    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/TilesAvailabilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/TilesAvailabilityInteractorTest.kt
index 67fb100..7743c2c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/TilesAvailabilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/domain/interactor/TilesAvailabilityInteractorTest.kt
@@ -28,7 +28,7 @@
 import com.android.systemui.qs.FakeQSTile
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.qsTileFactory
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
 import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.AIRPLANE_MODE_TILE_SPEC
 import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.HOTSPOT_TILE_SPEC
 import com.android.systemui.statusbar.connectivity.ConnectivityModule.Companion.INTERNET_TILE_SPEC
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
index 1d42424..8d50cdc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelTest.kt
@@ -19,13 +19,17 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.FakeQSTile
 import com.android.systemui.qs.pipeline.data.repository.tileSpecRepository
 import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
 import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.shade.domain.interactor.disableDualShade
+import com.android.systemui.shade.domain.interactor.enableDualShade
 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
@@ -34,6 +38,7 @@
 
 @RunWith(AndroidJUnit4::class)
 @SmallTest
+@EnableSceneContainer
 class DetailsViewModelTest : SysuiTestCase() {
     private val kosmos = testKosmos()
     private lateinit var underTest: DetailsViewModel
@@ -45,10 +50,12 @@
         underTest = kosmos.detailsViewModel
     }
 
+    @OptIn(ExperimentalCoroutinesApi::class)
     @Test
-    fun changeTileDetailsViewModel() =
+    fun changeTileDetailsViewModelWithDualShadeEnabled() =
         with(kosmos) {
             testScope.runTest {
+                kosmos.enableDualShade()
                 val specs = listOf(spec, specNoDetails)
                 tileSpecRepository.setTiles(0, specs)
                 runCurrent()
@@ -85,4 +92,36 @@
                 assertThat(underTest.onTileClicked(null)).isFalse()
             }
         }
+
+    @OptIn(ExperimentalCoroutinesApi::class)
+    @Test
+    fun ignoreChangingTileDetailsViewModelWithDualShadeDisabled() =
+        with(kosmos) {
+            testScope.runTest {
+                kosmos.disableDualShade()
+                val specs = listOf(spec, specNoDetails)
+                tileSpecRepository.setTiles(0, specs)
+                runCurrent()
+
+                val tiles = currentTilesInteractor.currentTiles.value
+
+                assertThat(currentTilesInteractor.currentTilesSpecs.size).isEqualTo(2)
+                assertThat(tiles[1].spec).isEqualTo(specNoDetails)
+                (tiles[1].tile as FakeQSTile).hasDetailsViewModel = false
+
+                assertThat(underTest.activeTileDetails).isNull()
+
+                // Click on the tile who has the `spec`.
+                assertThat(underTest.onTileClicked(spec)).isFalse()
+                assertThat(underTest.activeTileDetails).isNull()
+
+                // Click on a tile who dose not have a valid spec.
+                assertThat(underTest.onTileClicked(null)).isFalse()
+                assertThat(underTest.activeTileDetails).isNull()
+
+                // Click on a tile who dose not have a detailed view.
+                assertThat(underTest.onTileClicked(specNoDetails)).isFalse()
+                assertThat(underTest.activeTileDetails).isNull()
+            }
+        }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
index 50229eb..71ab0a2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/panels/ui/viewmodel/EditModeViewModelTest.kt
@@ -49,6 +49,9 @@
 import com.android.systemui.qs.pipeline.shared.metricSpec
 import com.android.systemui.qs.qsTileFactory
 import com.android.systemui.qs.shared.model.TileCategory
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.fakeQSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.qSTileConfigProvider
 import com.android.systemui.qs.tiles.impl.airplane.qsAirplaneModeTileConfig
 import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig
 import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
@@ -56,9 +59,6 @@
 import com.android.systemui.qs.tiles.impl.internet.qsInternetTileConfig
 import com.android.systemui.qs.tiles.impl.sensorprivacy.qsCameraSensorPrivacyToggleTileConfig
 import com.android.systemui.qs.tiles.impl.sensorprivacy.qsMicrophoneSensorPrivacyToggleTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.fakeQSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider
 import com.android.systemui.settings.userTracker
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
index 0049042..a2829b5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/autoaddable/WorkTileAutoAddableTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.pipeline.data.model.RestoreData
 import com.android.systemui.qs.pipeline.data.model.RestoreProcessor
 import com.android.systemui.qs.pipeline.data.model.workTileRestoreProcessor
@@ -36,6 +35,7 @@
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tiles.WorkModeTile
 import com.android.systemui.settings.FakeUserTracker
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -47,7 +47,7 @@
 @RunWith(AndroidJUnit4::class)
 class WorkTileAutoAddableTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
 
     private val restoreProcessor: RestoreProcessor
         get() = kosmos.workTileRestoreProcessor
@@ -62,7 +62,7 @@
             FakeUserTracker(
                 _userId = USER_INFO_0.id,
                 _userInfo = USER_INFO_0,
-                _userProfiles = listOf(USER_INFO_0)
+                _userProfiles = listOf(USER_INFO_0),
             )
 
         underTest = WorkTileAutoAddable(userTracker, kosmos.workTileRestoreProcessor)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
index 5bde7ad..12f1e66 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorImplTest.kt
@@ -49,7 +49,7 @@
 import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
 import com.android.systemui.qs.pipeline.shared.logging.qsLogger
 import com.android.systemui.qs.qsTileFactory
-import com.android.systemui.qs.tiles.di.newQSTileFactory
+import com.android.systemui.qs.tiles.base.ui.model.newQSTileFactory
 import com.android.systemui.qs.toProto
 import com.android.systemui.settings.fakeUserTracker
 import com.android.systemui.testKosmos
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
index 3a9c3d0..4e0adca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/NoLowNumberOfTilesTest.kt
@@ -22,7 +22,6 @@
 import androidx.test.filters.MediumTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.qs.FakeQSFactory
@@ -39,6 +38,7 @@
 import com.android.systemui.qs.qsTileFactory
 import com.android.systemui.settings.fakeUserTracker
 import com.android.systemui.settings.userTracker
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -55,22 +55,12 @@
 @RunWith(AndroidJUnit4::class)
 class NoLowNumberOfTilesTest : SysuiTestCase() {
 
-    private val USER_0_INFO =
-        UserInfo(
-            0,
-            "zero",
-            "",
-            UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
-        )
+    private val USER_0_INFO = UserInfo(0, "zero", "", UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL)
 
-    private val defaultTiles =
-        listOf(
-            TileSpec.create("internet"),
-            TileSpec.create("bt"),
-        )
+    private val defaultTiles = listOf(TileSpec.create("internet"), TileSpec.create("bt"))
 
     private val kosmos =
-        Kosmos().apply {
+        testKosmos().apply {
             fakeMinimumTilesRepository = MinimumTilesFixedRepository(minNumberOfTiles = 2)
             fakeUserTracker.set(listOf(USER_0_INFO), 0)
             qsTileFactory = FakeQSFactory(::tileCreator)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
index 9d9bfda..77030ac 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/pipeline/domain/interactor/WorkProfileAutoAddedAfterRestoreTest.kt
@@ -22,7 +22,6 @@
 import androidx.test.filters.MediumTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.qs.FakeQSFactory
@@ -34,6 +33,7 @@
 import com.android.systemui.qs.qsTileFactory
 import com.android.systemui.settings.fakeUserTracker
 import com.android.systemui.settings.userTracker
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.runCurrent
@@ -52,7 +52,9 @@
 @RunWith(AndroidJUnit4::class)
 class WorkProfileAutoAddedAfterRestoreTest : SysuiTestCase() {
 
-    private val kosmos by lazy { Kosmos().apply { fakeUserTracker.set(listOf(USER_0_INFO), 0) } }
+    private val kosmos by lazy {
+        testKosmos().apply { fakeUserTracker.set(listOf(USER_0_INFO), 0) }
+    }
     // Getter here so it can change when there is a managed profile.
     private val workTileAvailable: Boolean
         get() = hasManagedProfile()
@@ -143,30 +145,15 @@
     }
 
     private fun TestScope.createManagedProfileAndAdd() {
-        kosmos.fakeUserTracker.set(
-            listOf(USER_0_INFO, MANAGED_USER_INFO),
-            0,
-        )
+        kosmos.fakeUserTracker.set(listOf(USER_0_INFO, MANAGED_USER_INFO), 0)
         runCurrent()
     }
 
     private companion object {
         val WORK_TILE_SPEC = "work".toTileSpec()
-        val USER_0_INFO =
-            UserInfo(
-                0,
-                "zero",
-                "",
-                UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL,
-            )
+        val USER_0_INFO = UserInfo(0, "zero", "", UserInfo.FLAG_ADMIN or UserInfo.FLAG_FULL)
         val MANAGED_USER_INFO =
-            UserInfo(
-                10,
-                "ten-managed",
-                "",
-                0,
-                UserManager.USER_TYPE_PROFILE_MANAGED,
-            )
+            UserInfo(10, "ten-managed", "", 0, UserManager.USER_TYPE_PROFILE_MANAGED)
 
         fun String.toTileSpec() = TileSpec.create(this)
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesDndTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesDndTileTest.kt
index 1adba6f..6e5a700 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesDndTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesDndTileTest.kt
@@ -38,14 +38,14 @@
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileDataInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel
 import com.android.systemui.qs.tiles.impl.modes.ui.ModesDndTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
@@ -184,12 +184,12 @@
                     state = Tile.STATE_INACTIVE
                     secondaryLabel = "Old secondary label"
                 }
-            val model = ModesDndTileModel(isActivated = true)
+            val model = ModesDndTileModel(isActivated = true, extraStatus = "Until 14:30")
 
             underTest.handleUpdateState(tileState, model)
 
             assertThat(tileState.state).isEqualTo(Tile.STATE_ACTIVE)
-            assertThat(tileState.secondaryLabel).isEqualTo("On")
+            assertThat(tileState.secondaryLabel).isEqualTo("Until 14:30")
         }
 
     @Test
@@ -206,6 +206,6 @@
             underTest.handleUpdateState(tileState, null)
 
             assertThat(tileState.state).isEqualTo(Tile.STATE_ACTIVE)
-            assertThat(tileState.secondaryLabel).isEqualTo("On")
+            assertThat(tileState.secondaryLabel).isEqualTo(null) // Tile will use default On text
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt
index bbc0dbc..c218a1b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/ModesTileTest.kt
@@ -37,14 +37,14 @@
 import com.android.systemui.qs.QSHost
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.logging.QSLogger
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
-import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.qs.tiles.impl.modes.ui.mapper.ModesTileMapper
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerTest.kt
similarity index 96%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerTest.kt
index 02a8141..9444963 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.actions
+package com.android.systemui.qs.tiles.base.domain.actions
 
 import android.app.PendingIntent
 import android.content.ComponentName
@@ -119,7 +119,7 @@
             .postStartActivityDismissingKeyguard(
                 argThat(IntentMatcher(expectedIntent)),
                 eq(0),
-                any()
+                any(),
             )
     }
 
@@ -149,7 +149,7 @@
                 packageManager.queryIntentActivitiesAsUser(
                     any(Intent::class.java),
                     any(ResolveInfoFlags::class.java),
-                    eq(user.identifier)
+                    eq(user.identifier),
                 )
             )
             .thenReturn(infos.map { ResolveInfo().apply { activityInfo = it } })
@@ -157,6 +157,7 @@
 
     private class IntentMatcher(intent: Intent) : ArgumentMatcher<Intent> {
         private val expectedIntent = intent
+
         override fun matches(argument: Intent?): Boolean {
             return argument?.action.equals(expectedIntent.action) &&
                 argument?.`package`.equals(expectedIntent.`package`) &&
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorTest.kt
similarity index 97%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorTest.kt
index c0e5a9b..5c2edc2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.interactor
 
 import android.content.ComponentName
 import android.content.Context
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLoggerTest.kt
similarity index 95%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLoggerTest.kt
index 6a33b5f..ec88f71 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/logging/QSTileLoggerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLoggerTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.logging
+package com.android.systemui.qs.tiles.base.shared.logging
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -26,8 +26,8 @@
 import com.android.systemui.log.LogcatEchoTrackerAlways
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderTest.kt
similarity index 89%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderTest.kt
index 40971a8..fd83895 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import android.platform.test.annotations.EnabledOnRavenwood
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -34,7 +34,7 @@
 
     private val underTest =
         createQSTileConfigProviderImpl(
-            mapOf(VALID_SPEC.spec to QSTileConfigTestBuilder.build { tileSpec = VALID_SPEC }),
+            mapOf(VALID_SPEC.spec to QSTileConfigTestBuilder.build { tileSpec = VALID_SPEC })
         )
 
     @Test
@@ -66,11 +66,7 @@
 
     private fun createQSTileConfigProviderImpl(
         configs: Map<String, QSTileConfig>
-    ): QSTileConfigProviderImpl =
-        QSTileConfigProviderImpl(
-            configs,
-            mock<QsEventLogger>(),
-        )
+    ): QSTileConfigProviderImpl = QSTileConfigProviderImpl(configs, mock<QsEventLogger>())
 
     private companion object {
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsTest.kt
similarity index 85%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsTest.kt
index fd09e3c..ee0f5cd5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.analytics
+package com.android.systemui.qs.tiles.base.ui.analytics
 
 import android.platform.test.annotations.EnabledOnRavenwood
 import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -23,8 +23,8 @@
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.qs.QSEvent
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -57,7 +57,7 @@
                 eq(QSEvent.QS_ACTION_CLICK),
                 eq(0),
                 eq("test_spec"),
-                eq(InstanceId.fakeInstanceId(0))
+                eq(InstanceId.fakeInstanceId(0)),
             )
     }
 
@@ -70,7 +70,7 @@
                 eq(QSEvent.QS_ACTION_LONG_PRESS),
                 eq(0),
                 eq("test_spec"),
-                eq(InstanceId.fakeInstanceId(0))
+                eq(InstanceId.fakeInstanceId(0)),
             )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImplTest.kt
similarity index 84%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImplTest.kt
index da3cebd..4ebd22a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImplTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
@@ -23,16 +23,16 @@
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.qs.FakeTileDetailsViewModel
-import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
-import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor
-import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor
-import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
-import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelTest.kt
similarity index 87%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelTest.kt
index 4e9b635..d2f8b07 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
 import android.os.UserHandle
 import android.platform.test.annotations.EnabledOnRavenwood
@@ -26,14 +26,17 @@
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.qs.FakeTileDetailsViewModel
-import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor
-import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor
-import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelImpl
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.time.FakeSystemClock
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelUserInputTest.kt
similarity index 85%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelUserInputTest.kt
index 166e950..0f939a95 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelUserInputTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelUserInputTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.MediumTest
@@ -23,16 +23,21 @@
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.qs.FakeTileDetailsViewModel
-import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor
-import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION
-import com.android.systemui.qs.tiles.base.interactor.FakeDisabledByPolicyInteractor.Companion.ENABLED_RESTRICTION
-import com.android.systemui.qs.tiles.base.interactor.FakeQSTileDataInteractor
-import com.android.systemui.qs.tiles.base.interactor.FakeQSTileUserActionInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelImpl
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor.Companion.DISABLED_RESTRICTION_2
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeDisabledByPolicyInteractor.Companion.ENABLED_RESTRICTION
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.FakeQSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
+import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.user.data.repository.FakeUserRepository
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
@@ -171,10 +176,7 @@
                 QSTileConfigTestBuilder.build {
                     policy =
                         QSTilePolicy.Restricted(
-                            listOf(
-                                DISABLED_RESTRICTION,
-                                FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2,
-                            )
+                            listOf(DISABLED_RESTRICTION, DISABLED_RESTRICTION_2)
                         )
                 }
 
@@ -199,7 +201,7 @@
                 .logUserActionRejectedByPolicy(
                     eq(userAction),
                     eq(tileConfig.tileSpec),
-                    eq(FakeDisabledByPolicyInteractor.DISABLED_RESTRICTION_2),
+                    eq(DISABLED_RESTRICTION_2),
                 )
             verify(qsTileAnalytics, never()).trackUserAction(any(), any())
         }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt
index fda75ca..78756d6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractorTest.kt
@@ -22,7 +22,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
 import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
index d27e810..ce6bcdf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractorTest.kt
@@ -22,10 +22,10 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject.Companion.assertThat
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.longClick
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject.Companion.assertThat
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.longClick
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
 import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
 import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/AirplaneModeMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapperTest.kt
similarity index 86%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/AirplaneModeMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapperTest.kt
index 557f4ea..ccb2386 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/AirplaneModeMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl
+package com.android.systemui.qs.tiles.impl.airplane.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.service.quicksettings.Tile
@@ -23,29 +23,28 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.airplane.domain.AirplaneModeMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
 import com.android.systemui.qs.tiles.impl.airplane.qsAirplaneModeTileConfig
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
-class AirplaneModeMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+class AirplaneModeTileMapperTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
     private val airplaneModeConfig = kosmos.qsAirplaneModeTileConfig
 
-    private lateinit var mapper: AirplaneModeMapper
+    private lateinit var mapper: AirplaneModeTileMapper
 
     @Before
     fun setup() {
         mapper =
-            AirplaneModeMapper(
+            AirplaneModeTileMapper(
                 context.orCreateTestableResources
                     .apply {
                         addOverride(R.drawable.qs_airplane_icon_off, TestStubDrawable())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt
index afbc3e8..5fb0ea6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractorTest.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractorTest.kt
index be2da17..e7dd145 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractorTest.kt
@@ -22,9 +22,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click
 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapperTest.kt
similarity index 95%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapperTest.kt
index 24e4668..9b1d0a5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.alarm.domain
+package com.android.systemui.qs.tiles.impl.alarm.ui.mapper
 
 import android.app.AlarmManager
 import android.graphics.drawable.TestStubDrawable
@@ -23,12 +23,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
 import com.android.systemui.qs.tiles.impl.alarm.qsAlarmTileConfig
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import com.android.systemui.util.time.FakeSystemClock
 import java.time.Instant
 import java.time.LocalDateTime
@@ -41,7 +41,7 @@
 @RunWith(AndroidJUnit4::class)
 class AlarmTileMapperTest : SysuiTestCase() {
     private val oneMinute = 60000L
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val alarmTileConfig = kosmos.qsAlarmTileConfig
     private val fakeClock = FakeSystemClock()
     // Using lazy (versus =) to make sure we override the right context -- see b/311612168
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt
index 44c175a..8d3f8d4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileDataInteractorTest.kt
@@ -23,10 +23,10 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileDataInteractor
+import com.android.systemui.testKosmos
 import com.android.systemui.utils.leaks.FakeBatteryController
 import com.google.common.truth.Truth
 import kotlinx.coroutines.flow.flowOf
@@ -40,7 +40,7 @@
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class BatterySaverTileDataInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val batteryController = FakeBatteryController(LeakCheck())
     private val testUser = UserHandle.of(1)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileUserActionInteractorTest.kt
index 62c51e6..68a4d41 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/doman/interactor/BatterySaverTileUserActionInteractorTest.kt
@@ -22,9 +22,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel
 import com.android.systemui.utils.leaks.FakeBatteryController
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapperTest.kt
similarity index 96%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapperTest.kt
index 2ddaddd..8128c0c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.battery.ui
+package com.android.systemui.qs.tiles.impl.battery.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.widget.Switch
@@ -22,12 +22,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel
 import com.android.systemui.qs.tiles.impl.battery.qsBatterySaverTileConfig
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -35,7 +35,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class BatterySaverTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val batterySaverTileConfig = kosmos.qsBatterySaverTileConfig
     private lateinit var mapper: BatterySaverTileMapper
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt
index 4c156b7..4819539 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractorTest.kt
@@ -23,7 +23,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.FakeColorCorrectionRepository
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.flowOf
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt
index 0cf3734..90533f5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileUserActionInteractorTest.kt
@@ -24,9 +24,9 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.FakeColorCorrectionRepository
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapperTest.kt
similarity index 90%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapperTest.kt
index a3c159820..124e013 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.colorcorrection.domain
+package com.android.systemui.qs.tiles.impl.colorcorrection.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.widget.Switch
@@ -22,19 +22,19 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
 import com.android.systemui.qs.tiles.impl.colorcorrection.qsColorCorrectionTileConfig
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ColorCorrectionTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val colorCorrectionTileConfig = kosmos.qsColorCorrectionTileConfig
     private val subtitleArray by lazy {
         context.resources.getStringArray(R.array.tile_states_color_correction)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepositoryTest.kt
similarity index 95%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepositoryTest.kt
index 10530a2..80e865d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTileDefaultsRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepositoryTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom
+package com.android.systemui.qs.tiles.impl.custom.data.repository
 
 import android.content.ComponentName
 import android.content.Context
@@ -25,9 +25,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
-import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository
-import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepositoryImpl
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
@@ -199,6 +197,7 @@
             appInfoIcon = APP_INFO_ICON_1,
             isSystemApp = isSystemApp,
         )
+
     private fun PackageManager.setupApp2(isSystemApp: Boolean = false) =
         setupApp(
             componentName = COMPONENT_NAME_2,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepositoryTest.kt
similarity index 92%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepositoryTest.kt
index 835dba2..93dcf7d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/CustomTilePackageUpdatesRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepositoryTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom
+package com.android.systemui.qs.tiles.impl.custom.data.repository
 
 import android.annotation.SuppressLint
 import android.content.BroadcastReceiver
@@ -28,8 +28,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository
-import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepositoryImpl
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.capture
 import com.android.systemui.util.mockito.eq
@@ -111,7 +109,7 @@
                     any(),
                     any(),
                     nullable(),
-                    nullable()
+                    nullable(),
                 )
             listenerCaptor.value.onReceive(mockedContext, Intent(Intent.ACTION_MAIN))
             runCurrent()
@@ -144,9 +142,9 @@
                 type = IntentFilter.SCHEME_PACKAGE
                 putExtra(
                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST,
-                    arrayOf(componentName.packageName)
+                    arrayOf(componentName.packageName),
                 )
-            }
+            },
         )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
index 83e61d1..f8489c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepositoryTest.kt
@@ -24,16 +24,16 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.external.TileServiceKey
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat
-import com.android.systemui.qs.tiles.impl.custom.commons.copy
 import com.android.systemui.qs.tiles.impl.custom.customTileSpec
 import com.android.systemui.qs.tiles.impl.custom.customTileStatePersister
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
 import com.android.systemui.qs.tiles.impl.custom.packageManagerAdapterFacade
+import com.android.systemui.qs.tiles.impl.custom.shared.model.copy
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.test.runCurrent
@@ -45,7 +45,7 @@
 @RunWith(AndroidJUnit4::class)
 class CustomTileRepositoryTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos().apply { customTileSpec = TileSpec.create(TEST_COMPONENT) }
+    private val kosmos = testKosmos().apply { customTileSpec = TileSpec.create(TEST_COMPONENT) }
     private val underTest: CustomTileRepository =
         with(kosmos) {
             CustomTileRepositoryImpl(
@@ -213,7 +213,7 @@
                 underTest.updateWithTile(
                     TEST_USER_1,
                     Tile().apply { subtitle = "test_subtitle" },
-                    true
+                    true,
                 )
                 runCurrent()
 
@@ -247,7 +247,7 @@
                 underTest.updateWithTile(
                     TEST_USER_1,
                     Tile().apply { subtitle = "test_subtitle" },
-                    true
+                    true,
                 )
                 runCurrent()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt
index 2cc3678..8e10649 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractorTest.kt
@@ -31,7 +31,7 @@
 import com.android.systemui.qs.external.tileServiceManagerFacade
 import com.android.systemui.qs.external.tileServicesFacade
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat
 import com.android.systemui.qs.tiles.impl.custom.customTileDefaultsRepository
 import com.android.systemui.qs.tiles.impl.custom.customTileInteractor
@@ -39,7 +39,7 @@
 import com.android.systemui.qs.tiles.impl.custom.customTileRepository
 import com.android.systemui.qs.tiles.impl.custom.customTileServiceInteractor
 import com.android.systemui.qs.tiles.impl.custom.customTileSpec
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
 import com.android.systemui.qs.tiles.impl.custom.qsTileLogger
 import com.android.systemui.testKosmos
 import com.android.systemui.user.data.repository.fakeUserRepository
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
index a317dc5..6fef9f1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractorTest.kt
@@ -33,7 +33,7 @@
 import com.android.systemui.qs.tiles.impl.custom.customTileRepository
 import com.android.systemui.qs.tiles.impl.custom.customTileSpec
 import com.android.systemui.qs.tiles.impl.custom.customTileStatePersister
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.first
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt
index 72e5766..df4f097 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractorTest.kt
@@ -38,14 +38,14 @@
 import com.android.systemui.qs.external.componentName
 import com.android.systemui.qs.external.iQSTileService
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.intentInputs
-import com.android.systemui.qs.tiles.base.actions.pendingIntentInputs
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.longClick
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.intentInputs
+import com.android.systemui.qs.tiles.base.domain.actions.pendingIntentInputs
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.longClick
 import com.android.systemui.qs.tiles.impl.custom.customTileServiceInteractor
 import com.android.systemui.qs.tiles.impl.custom.customTileSpec
-import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
+import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel
 import com.android.systemui.qs.tiles.impl.custom.qsTileLogger
 import com.android.systemui.testKosmos
 import com.android.systemui.user.data.repository.fakeUserRepository
@@ -144,7 +144,7 @@
                     assertThat(
                             intent.getParcelableExtra(
                                 Intent.EXTRA_COMPONENT_NAME,
-                                ComponentName::class.java
+                                ComponentName::class.java,
                             )
                         )
                         .isEqualTo(componentName)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapperTest.kt
similarity index 95%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapperTest.kt
index 608adf1..41f6872 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom.domain.interactor
+package com.android.systemui.qs.tiles.impl.custom.ui.mapper
 
 import android.app.IUriGrantsManager
 import android.content.ComponentName
@@ -32,12 +32,11 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject.Companion.assertThat
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject.Companion.assertThat
 import com.android.systemui.qs.tiles.impl.custom.customTileQsTileConfig
 import com.android.systemui.qs.tiles.impl.custom.customTileSpec
-import com.android.systemui.qs.tiles.impl.custom.domain.CustomTileMapper
-import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt
index d42eb5e..5df7ae3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractorTest.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
 import com.android.systemui.utils.leaks.FakeFlashlightController
 import com.google.common.truth.Truth.assertThat
@@ -57,6 +57,7 @@
 
         assertThat(availability).isTrue()
     }
+
     @Test
     fun availabilityOffMatchesController() = runTest {
         controller.hasFlashlight = false
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractorTest.kt
index 1f19c98..d7536dc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractorTest.kt
@@ -20,7 +20,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
 import com.android.systemui.statusbar.policy.FlashlightController
 import com.android.systemui.util.mockito.mock
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapperTest.kt
similarity index 94%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapperTest.kt
index a115c12..aebc67b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.flashlight.domain
+package com.android.systemui.qs.tiles.impl.flashlight.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
 import com.android.systemui.qs.tiles.impl.flashlight.qsFlashlightTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import junit.framework.Assert.assertEquals
 import org.junit.Test
@@ -34,7 +34,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FlashlightMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val qsTileConfig = kosmos.qsFlashlightTileConfig
     private val mapper by lazy {
         FlashlightMapper(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt
index cd82504..585c1a7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractorTest.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.google.common.truth.Truth
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt
index 9bd4895..11b9f77 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingUserActionInteractorTest.kt
@@ -26,17 +26,17 @@
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.animation.LaunchableView
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.intentInputs
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.intentInputs
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel
 import com.android.systemui.statusbar.phone.FakeKeyguardStateController
 import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -67,7 +67,7 @@
 
     @Captor private lateinit var argumentCaptor: ArgumentCaptor<Runnable>
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val scope = kosmos.testScope
     private val qsTileIntentUserActionHandler = FakeQSTileIntentUserInputHandler()
     private val keyguardStateController = FakeKeyguardStateController()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapperTest.kt
similarity index 88%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapperTest.kt
index 8f8f710..1e794f9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.fontscaling.domain
+package com.android.systemui.qs.tiles.impl.fontscaling.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.widget.Switch
@@ -22,19 +22,19 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel
 import com.android.systemui.qs.tiles.impl.fontscaling.qsFontScalingTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class FontScalingTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val fontScalingTileConfig = kosmos.qsFontScalingTileConfig
 
     private val mapper by lazy {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt
index 4b9d11d..ae37684 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractorTest.kt
@@ -24,11 +24,11 @@
 import com.android.systemui.accessibility.hearingaid.HearingDevicesChecker
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
 import com.android.systemui.statusbar.policy.fakeBluetoothController
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
@@ -46,7 +46,7 @@
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class HearingDevicesTileDataInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val testUser = UserHandle.of(1)
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractorTest.kt
index 1b497a2..5ab728f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractorTest.kt
@@ -22,13 +22,13 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.hearingaid.HearingDevicesDialogManager
 import com.android.systemui.accessibility.hearingaid.HearingDevicesUiEventLogger.Companion.LAUNCH_SOURCE_QS_TILE
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -47,7 +47,7 @@
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class HearingDevicesTileUserActionInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val inputHandler = FakeQSTileIntentUserInputHandler()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapperTest.kt
similarity index 92%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapperTest.kt
index 3d3447d..b0129f0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.android.systemui.qs.tiles.impl.hearingdevices.domain
+package com.android.systemui.qs.tiles.impl.hearingdevices.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.widget.Switch
@@ -21,19 +21,19 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
 import com.android.systemui.qs.tiles.impl.hearingdevices.qsHearingDevicesTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class HearingDevicesTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val qsTileConfig = kosmos.qsHearingDevicesTileConfig
     private val mapper by lazy {
         HearingDevicesTileMapper(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
index 63607f1..a8747e8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractorTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,10 +29,9 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.table.logcatTableLogBuffer
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.connectivity.WifiIcons
@@ -54,6 +53,7 @@
 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry
 import com.android.systemui.statusbar.pipeline.wifi.ui.model.WifiIcon
 import com.android.systemui.statusbar.policy.data.repository.FakeUserSetupRepository
+import com.android.systemui.testKosmos
 import com.android.systemui.util.CarrierConfigTracker
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
@@ -67,7 +67,7 @@
 @RunWith(AndroidJUnit4::class)
 class InternetTileDataInteractorTest : SysuiTestCase() {
     private val testUser = UserHandle.of(1)
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
     private lateinit var underTest: InternetTileDataInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
index 261e3de..8b58e56 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractorTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -21,14 +21,14 @@
 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.kosmos.testScope
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.dialog.InternetDialogManager
 import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
 import com.android.systemui.statusbar.connectivity.AccessPointController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.nullable
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
@@ -44,7 +44,7 @@
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class InternetTileUserActionInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val inputHandler = FakeQSTileIntentUserInputHandler()
 
     private lateinit var underTest: InternetTileUserActionInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapperTest.kt
similarity index 95%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapperTest.kt
index 54a653d..da91f70 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.internet.domain
+package com.android.systemui.qs.tiles.impl.internet.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.os.fakeExecutorHandler
@@ -28,23 +28,23 @@
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.common.shared.model.Text.Companion.loadText
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
 import com.android.systemui.qs.tiles.impl.internet.qsInternetTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS
 import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
 import com.android.systemui.statusbar.pipeline.satellite.ui.model.SatelliteIconModel
 import com.android.systemui.statusbar.pipeline.shared.ui.model.InternetTileIconModel
+import com.android.systemui.testKosmos
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class InternetTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val internetTileConfig = kosmos.qsInternetTileConfig
     private val handler = kosmos.fakeExecutorHandler
     private val mapper by lazy {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt
index 228e993..70828d5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractorTest.kt
@@ -23,7 +23,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.FakeColorInversionRepository
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.flowOf
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt
index 3f77b86..e4a1ce2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractorTest.kt
@@ -24,9 +24,9 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.FakeColorInversionRepository
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapperTest.kt
similarity index 91%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapperTest.kt
index 780d58c..509a178 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.inversion.domain
+package com.android.systemui.qs.tiles.impl.inversion.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.widget.Switch
@@ -22,20 +22,20 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.tileimpl.SubtitleArrayMapping
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
 import com.android.systemui.qs.tiles.impl.inversion.qsColorInversionTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ColorInversionTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val colorInversionTileConfig = kosmos.qsColorInversionTileConfig
     private val subtitleArrayId =
         SubtitleArrayMapping.getSubtitleId(colorInversionTileConfig.tileSpec.spec)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractorTest.kt
similarity index 90%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractorTest.kt
index 7562ac0..1ee6ac6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractorTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package com.android.systemui.qs.tiles.impl.irecording.domain.interactor
 
 import android.os.Handler
 import android.os.UserHandle
@@ -22,13 +22,13 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.recordissue.IssueRecordingState
 import com.android.systemui.settings.fakeUserFileManager
 import com.android.systemui.settings.userTracker
+import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeGlobalSettings
 import com.google.common.truth.Truth
 import kotlinx.coroutines.flow.flowOf
@@ -42,7 +42,7 @@
 @RunWith(AndroidJUnit4::class)
 class IssueRecordingDataInteractorTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
     private val userTracker = kosmos.userTracker
     private val userFileManager = kosmos.fakeUserFileManager
     private val testUser = UserHandle.of(1)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractorTest.kt
similarity index 91%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractorTest.kt
index 9c2be89..2791b74 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractorTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package com.android.systemui.qs.tiles.impl.irecording.domain.interactor
 
 import android.os.Handler
 import android.os.UserHandle
@@ -22,15 +22,15 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.dialogTransitionAnimator
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.activityStarter
 import com.android.systemui.plugins.statusbar.statusBarStateController
 import com.android.systemui.qs.pipeline.domain.interactor.panelInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
+import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel
 import com.android.systemui.recordissue.IssueRecordingState
 import com.android.systemui.recordissue.RecordIssueDialogDelegate
 import com.android.systemui.screenrecord.RecordingController
@@ -39,6 +39,7 @@
 import com.android.systemui.settings.userTracker
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil
 import com.android.systemui.statusbar.policy.keyguardStateController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeGlobalSettings
 import com.google.common.truth.Truth
 import kotlinx.coroutines.test.runTest
@@ -56,7 +57,7 @@
     @Mock private lateinit var recordingController: RecordingController
 
     val user = UserHandle(1)
-    val kosmos = Kosmos().also { it.testCase = this }
+    val kosmos = testKosmos().also { it.testCase = this }
 
     private lateinit var userContextProvider: UserContextProvider
     private lateinit var underTest: IssueRecordingUserActionInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapperTest.kt
similarity index 81%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapperTest.kt
index fa6d8bf..e469330 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,22 +14,23 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package com.android.systemui.qs.tiles.impl.irecording.ui.mapper
 
 import android.content.res.mainResources
 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.kosmos.testCase
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.qsEventLogger
 import com.android.systemui.qs.shared.model.TileCategory
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel
 import com.android.systemui.recordissue.RecordIssueModule
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -37,7 +38,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class IssueRecordingMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
     private val uiConfig =
         QSTileUIConfig.Resource(R.drawable.qs_record_issue_icon_off, R.string.qs_record_issue_label)
     private val config =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractorTest.kt
similarity index 90%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractorTest.kt
index 52ce95b..9c52714 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractorTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.location.interactor
+package com.android.systemui.qs.tiles.impl.location.domain.interactor
 
 import android.os.UserHandle
 import android.platform.test.annotations.EnabledOnRavenwood
@@ -24,8 +24,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
 import com.android.systemui.utils.leaks.FakeLocationController
 import com.google.common.truth.Truth
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractorTest.kt
similarity index 85%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileUserActionInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractorTest.kt
index 8b21cb4..bd63253 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/interactor/LocationTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractorTest.kt
@@ -14,24 +14,23 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.location.interactor
+package com.android.systemui.qs.tiles.impl.location.domain.interactor
 
 import android.platform.test.annotations.EnabledOnRavenwood
 import android.provider.Settings
 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.kosmos.testScope
 import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.intentInputs
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.click
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx.longClick
-import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.intentInputs
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.click
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx.longClick
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
 import com.android.systemui.statusbar.phone.FakeKeyguardStateController
 import com.android.systemui.statusbar.policy.LocationController
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.coroutines.EmptyCoroutineContext
 import kotlinx.coroutines.test.runTest
@@ -58,7 +57,7 @@
     @Before
     fun setup() {
         MockitoAnnotations.initMocks(this)
-        val kosmos = Kosmos()
+        val kosmos = testKosmos()
         underTest =
             LocationTileUserActionInteractor(
                 EmptyCoroutineContext,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapperTest.kt
similarity index 92%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapperTest.kt
index 4ebe23dc..807e373 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.location.domain
+package com.android.systemui.qs.tiles.impl.location.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
 import com.android.systemui.qs.tiles.impl.location.qsLocationTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
 import junit.framework.Assert
 import org.junit.Test
@@ -34,7 +34,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LocationTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val qsTileConfig = kosmos.qsLocationTileConfig
 
     private val mapper by lazy {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractorTest.kt
index 23d7b86..58883204 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractorTest.kt
@@ -27,7 +27,7 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
 import com.android.systemui.testKosmos
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractorTest.kt
index 0a35b42..4ef61d9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractorTest.kt
@@ -26,9 +26,9 @@
 import com.android.systemui.kosmos.mainCoroutineContext
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel
 import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
@@ -79,7 +79,7 @@
             zenModeRepository.activateMode(MANUAL_DND)
             assertThat(dndMode?.isActive).isTrue()
 
-            underTest.handleInput(QSTileInputTestKtx.click(data = ModesDndTileModel(true)))
+            underTest.handleInput(QSTileInputTestKtx.click(data = ModesDndTileModel(true, null)))
 
             assertThat(dndMode?.isActive).isFalse()
         }
@@ -90,7 +90,7 @@
             val dndMode by collectLastValue(zenModeInteractor.dndMode)
             assertThat(dndMode?.isActive).isFalse()
 
-            underTest.handleInput(QSTileInputTestKtx.click(data = ModesDndTileModel(false)))
+            underTest.handleInput(QSTileInputTestKtx.click(data = ModesDndTileModel(false, null)))
 
             assertThat(dndMode?.isActive).isTrue()
         }
@@ -101,7 +101,7 @@
             zenModeRepository.activateMode(MANUAL_DND)
             runCurrent()
 
-            underTest.handleInput(QSTileInputTestKtx.longClick(ModesDndTileModel(true)))
+            underTest.handleInput(QSTileInputTestKtx.longClick(ModesDndTileModel(true, null)))
 
             QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
                 assertThat(it.intent.`package`).isEqualTo(SETTINGS_PACKAGE)
@@ -118,7 +118,7 @@
             zenModeRepository.deactivateMode(MANUAL_DND)
             runCurrent()
 
-            underTest.handleInput(QSTileInputTestKtx.longClick(ModesDndTileModel(false)))
+            underTest.handleInput(QSTileInputTestKtx.longClick(ModesDndTileModel(false, null)))
 
             QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
                 assertThat(it.intent.`package`).isEqualTo(SETTINGS_PACKAGE)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt
index 0b641ce..1df2e1b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractorTest.kt
@@ -34,7 +34,7 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
 import com.android.systemui.statusbar.policy.data.repository.fakeZenModeRepository
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt
index 24e4279..9d0b26f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorTest.kt
@@ -30,9 +30,9 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.mainCoroutineContext
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
 import com.android.systemui.statusbar.policy.data.repository.zenModeRepository
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapperTest.kt
index 29f642a..318ce0e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapperTest.kt
@@ -23,10 +23,10 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
 import com.android.systemui.res.R
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
@@ -58,23 +58,36 @@
 
     @Test
     fun map_inactiveState() {
-        val model = ModesDndTileModel(isActivated = false)
+        val model = ModesDndTileModel(isActivated = false, extraStatus = null)
 
         val state = underTest.map(config, model)
 
         assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.INACTIVE)
         assertThat((state.icon as Icon.Loaded).res).isEqualTo(R.drawable.qs_dnd_icon_off)
-        assertThat(state.secondaryLabel).isEqualTo("Off")
+        assertThat(state.secondaryLabel).isNull() // Will use default label for activationState
     }
 
     @Test
     fun map_activeState() {
-        val model = ModesDndTileModel(isActivated = true)
+        val model = ModesDndTileModel(isActivated = true, extraStatus = null)
 
         val state = underTest.map(config, model)
 
         assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE)
         assertThat((state.icon as Icon.Loaded).res).isEqualTo(R.drawable.qs_dnd_icon_on)
-        assertThat(state.secondaryLabel).isEqualTo("On")
+        assertThat(state.secondaryLabel).isNull() // Will use default label for activationState
+    }
+
+    @Test
+    fun map_activeStateWithExtraStatus() {
+        val model = ModesDndTileModel(isActivated = true, extraStatus = "Until 14:00")
+
+        val state = underTest.map(config, model)
+
+        assertThat(state.activationState).isEqualTo(QSTileState.ActivationState.ACTIVE)
+        assertThat((state.icon as Icon.Loaded).res).isEqualTo(R.drawable.qs_dnd_icon_on)
+        assertThat(state.secondaryLabel).isEqualTo("Until 14:00")
+        assertThat(state.contentDescription).isEqualTo("Do Not Disturb")
+        assertThat(state.stateDescription).isEqualTo("Until 14:00")
     }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapperTest.kt
similarity index 91%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapperTest.kt
index d73044f..e8a85f4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.modes.ui
+package com.android.systemui.qs.tiles.impl.modes.ui.mapper
 
 import android.app.Flags
 import android.graphics.drawable.TestStubDrawable
@@ -23,10 +23,10 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.asIcon
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
 import com.android.systemui.res.R
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractorTest.kt
index a0aa2d4..a5e2922 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractorTest.kt
@@ -26,7 +26,7 @@
 import com.android.systemui.accessibility.data.repository.NightDisplayRepository
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.dagger.NightDisplayListenerModule
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.testKosmos
 import com.android.systemui.user.utils.UserScopedService
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
@@ -47,7 +47,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NightDisplayTileDataInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testUser = UserHandle.of(1)!!
     private val testStartTime = LocalTime.MIDNIGHT
     private val testEndTime = LocalTime.NOON
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractorTest.kt
index adc8bcb..a0d0b23 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractorTest.kt
@@ -26,12 +26,12 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.NightDisplayRepository
 import com.android.systemui.dagger.NightDisplayListenerModule
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.intentInputs
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.intentInputs
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.custom.qsTileLogger
 import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel
+import com.android.systemui.testKosmos
 import com.android.systemui.user.utils.UserScopedService
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
@@ -51,7 +51,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NightDisplayTileUserActionInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val qsTileIntentUserActionHandler = FakeQSTileIntentUserInputHandler()
     private val testUser = UserHandle.of(1)
     private val colorDisplayManager =
@@ -89,7 +89,7 @@
         NightDisplayTileUserActionInteractor(
             nightDisplayRepository,
             qsTileIntentUserActionHandler,
-            kosmos.qsTileLogger
+            kosmos.qsTileLogger,
         )
 
     @Test
@@ -143,7 +143,7 @@
             underTest.handleInput(
                 QSTileInputTestKtx.longClick(
                     NightDisplayTileModel.AutoModeOff(enabledState, false),
-                    testUser
+                    testUser,
                 )
             )
 
@@ -163,7 +163,7 @@
             underTest.handleInput(
                 QSTileInputTestKtx.longClick(
                     NightDisplayTileModel.AutoModeOff(enabledState, false),
-                    testUser
+                    testUser,
                 )
             )
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapperTest.kt
similarity index 96%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapperTest.kt
index 7c85326..25c7016 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.night.ui
+package com.android.systemui.qs.tiles.impl.night.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.service.quicksettings.Tile
@@ -24,13 +24,13 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel
 import com.android.systemui.qs.tiles.impl.night.qsNightDisplayTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.mock
 import java.time.LocalTime
 import java.time.format.DateTimeFormatter
@@ -41,7 +41,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NightDisplayTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val config = kosmos.qsNightDisplayTileConfig
 
     private val testStartTime = LocalTime.MIDNIGHT
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt
index 4786fc4..51cad30 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractorTest.kt
@@ -24,9 +24,9 @@
 import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.toCollection
@@ -38,12 +38,11 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotesTileDataInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val testUser = UserHandle.of(1)
     private lateinit var underTest: NotesTileDataInteractor
 
-
     @EnableFlags(Flags.FLAG_NOTES_ROLE_QS_TILE)
     @Test
     fun availability_qsFlagEnabled_notesRoleEnabled_returnTrue() =
@@ -92,7 +91,7 @@
     fun tileData_notEmpty() = runTest {
         underTest = NotesTileDataInteractor(isNoteTaskEnabled = true)
         val flowValue by
-        collectLastValue(underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest)))
+            collectLastValue(underTest.tileData(testUser, flowOf(DataUpdateTrigger.InitialRequest)))
 
         runCurrent()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt
index 54911e6..c29a490 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractorTest.kt
@@ -20,27 +20,27 @@
 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.kosmos.testScope
 import com.android.systemui.notetask.NoteTaskController
 import com.android.systemui.notetask.NoteTaskEntryPoint
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.kotlin.mock
 import org.mockito.Mockito.verify
+import org.mockito.kotlin.mock
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotesTileUserActionInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val inputHandler = FakeQSTileIntentUserInputHandler()
     private val panelInteractor = mock<PanelInteractor>()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapperTest.kt
similarity index 88%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapperTest.kt
index b6caa22..0234584 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.notes.domain
+package com.android.systemui.qs.tiles.impl.notes.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.widget.Button
@@ -22,19 +22,19 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
 import com.android.systemui.qs.tiles.impl.notes.qsNotesTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import kotlin.test.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class NotesTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val qsTileConfig = kosmos.qsNotesTileConfig
 
     private val mapper by lazy {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt
index 59eb069..d0ea691 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileDataInteractorTest.kt
@@ -22,9 +22,9 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.oneHandedModeRepository
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileDataInteractor
+import com.android.systemui.testKosmos
 import com.android.wm.shell.onehanded.OneHanded
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.flowOf
@@ -37,7 +37,7 @@
 @RunWith(AndroidJUnit4::class)
 class OneHandedModeTileDataInteractorTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testUser = UserHandle.of(1)!!
     private val oneHandedModeRepository = kosmos.oneHandedModeRepository
     private val underTest: OneHandedModeTileDataInteractor =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileUserActionInteractorTest.kt
index 3f17d4c..a8f1808 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/domain/interactor/OneHandedModeTileUserActionInteractorTest.kt
@@ -23,9 +23,9 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.data.repository.FakeOneHandedModeRepository
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel
 import com.google.common.truth.Truth.assertThat
@@ -42,11 +42,7 @@
     private val repository = FakeOneHandedModeRepository()
     private val inputHandler = FakeQSTileIntentUserInputHandler()
 
-    private val underTest =
-        OneHandedModeTileUserActionInteractor(
-            repository,
-            inputHandler,
-        )
+    private val underTest = OneHandedModeTileUserActionInteractor(repository, inputHandler)
 
     @Test
     fun handleClickWhenEnabled() = runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapperTest.kt
similarity index 91%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapperTest.kt
index 5b39810..fe10457 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.onehanded.ui
+package com.android.systemui.qs.tiles.impl.onehanded.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.widget.Switch
@@ -22,13 +22,13 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.tileimpl.SubtitleArrayMapping
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel
 import com.android.systemui.qs.tiles.impl.onehanded.qsOneHandedModeTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -36,7 +36,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class OneHandedModeTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val config = kosmos.qsOneHandedModeTileConfig
     private val subtitleArrayId = SubtitleArrayMapping.getSubtitleId(config.tileSpec.spec)
     private val subtitleArray by lazy { context.resources.getStringArray(subtitleArrayId) }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractorTest.kt
index c41ce2f..82535db 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractorTest.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController.Callback
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractorTest.kt
index 312f180..8c0dae8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractorTest.kt
@@ -21,12 +21,12 @@
 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.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel
 import com.android.systemui.qs.tiles.impl.qr.qrCodeScannerTileUserActionInteractor
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.mock
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
@@ -36,7 +36,7 @@
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class QRCodeScannerTileUserActionInteractorTest : SysuiTestCase() {
-    val kosmos = Kosmos()
+    val kosmos = testKosmos()
     private val inputHandler = kosmos.qsTileIntentUserInputHandler
     private val underTest = kosmos.qrCodeScannerTileUserActionInteractor
     private val intent = mock<Intent>()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapperTest.kt
similarity index 81%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapperTest.kt
index c572ff6..8e453ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.qr.ui
+package com.android.systemui.qs.tiles.impl.qr.ui.mapper
 
 import android.content.Intent
 import android.graphics.drawable.TestStubDrawable
@@ -23,11 +23,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel
 import com.android.systemui.qs.tiles.impl.qr.qsQRCodeScannerTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.mock
 import org.junit.Before
 import org.junit.Test
@@ -36,7 +37,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class QRCodeScannerTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val config = kosmos.qsQRCodeScannerTileConfig
 
     private lateinit var mapper: QRCodeScannerTileMapper
@@ -46,12 +47,7 @@
         mapper =
             QRCodeScannerTileMapper(
                 context.orCreateTestableResources
-                    .apply {
-                        addOverride(
-                            com.android.systemui.res.R.drawable.ic_qr_code_scanner,
-                            TestStubDrawable(),
-                        )
-                    }
+                    .apply { addOverride(R.drawable.ic_qr_code_scanner, TestStubDrawable()) }
                     .resources,
                 context.theme,
             )
@@ -91,9 +87,9 @@
         val label = context.getString(com.android.systemui.res.R.string.qr_code_scanner_title)
         return QSTileState(
             Icon.Loaded(
-                context.getDrawable(com.android.systemui.res.R.drawable.ic_qr_code_scanner)!!,
+                context.getDrawable(R.drawable.ic_qr_code_scanner)!!,
                 null,
-                com.android.systemui.res.R.drawable.ic_qr_code_scanner,
+                R.drawable.ic_qr_code_scanner,
             ),
             label,
             activationState,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
index dc3248d..db46a4f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractorTest.kt
@@ -23,10 +23,10 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.reduceBrightColorsController
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
@@ -40,14 +40,14 @@
 class ReduceBrightColorsTileDataInteractorTest : SysuiTestCase() {
 
     private val isAvailable = true
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val reduceBrightColorsController = kosmos.reduceBrightColorsController
     private val underTest: ReduceBrightColorsTileDataInteractor =
         ReduceBrightColorsTileDataInteractor(
             testScope.testScheduler,
             isAvailable,
-            reduceBrightColorsController
+            reduceBrightColorsController,
         )
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt
index 75b090c..221a6f1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractorTest.kt
@@ -28,11 +28,11 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.accessibility.extradim.ExtraDimDialogManager
 import com.android.systemui.accessibility.reduceBrightColorsController
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -48,7 +48,7 @@
 @RunWith(AndroidJUnit4::class)
 class ReduceBrightColorsTileUserActionInteractorTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val inputHandler = FakeQSTileIntentUserInputHandler()
     private val controller = kosmos.reduceBrightColorsController
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapperTest.kt
similarity index 91%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapperTest.kt
index 00017f9..dabf0b0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.reducebrightness.ui
+package com.android.systemui.qs.tiles.impl.reducebrightness.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.service.quicksettings.Tile
@@ -23,12 +23,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
 import com.android.systemui.qs.tiles.impl.reducebrightness.qsReduceBrightColorsTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -36,7 +36,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ReduceBrightColorsTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val config = kosmos.qsReduceBrightColorsTileConfig
 
     private lateinit var mapper: ReduceBrightColorsTileMapper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt
index 283fa60..ef67910 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractorTest.kt
@@ -28,9 +28,9 @@
 import com.android.systemui.camera.data.repository.fakeCameraAutoRotateRepository
 import com.android.systemui.camera.data.repository.fakeCameraSensorPrivacyRepository
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.whenever
 import com.android.systemui.utils.leaks.FakeBatteryController
@@ -48,7 +48,7 @@
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class RotationLockTileDataInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val batteryController = FakeBatteryController(LeakCheck())
     private val rotationController = FakeRotationLockController(LeakCheck())
@@ -65,7 +65,7 @@
         whenever(
                 packageManager.checkPermission(
                     eq(Manifest.permission.CAMERA),
-                    eq(TEST_PACKAGE_NAME)
+                    eq(TEST_PACKAGE_NAME),
                 )
             )
             .thenReturn(PackageManager.PERMISSION_GRANTED)
@@ -81,7 +81,7 @@
                     .apply {
                         addOverride(com.android.internal.R.bool.config_allowRotationResolver, true)
                     }
-                    .resources
+                    .resources,
             )
     }
 
@@ -182,7 +182,7 @@
             whenever(
                     packageManager.checkPermission(
                         eq(Manifest.permission.CAMERA),
-                        eq(TEST_PACKAGE_NAME)
+                        eq(TEST_PACKAGE_NAME),
                     )
                 )
                 .thenReturn(PackageManager.PERMISSION_DENIED)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt
index 1653ce3..e60e210 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractorTest.kt
@@ -22,9 +22,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
 import com.android.systemui.utils.leaks.FakeRotationLockController
 import com.google.common.truth.Truth.assertThat
@@ -39,11 +39,7 @@
     private val controller = FakeRotationLockController(LeakCheck())
     private val inputHandler = FakeQSTileIntentUserInputHandler()
 
-    private val underTest =
-        RotationLockTileUserActionInteractor(
-            controller,
-            inputHandler,
-        )
+    private val underTest = RotationLockTileUserActionInteractor(controller, inputHandler)
 
     @Test
     fun handleClickWhenEnabled() = runTest {
@@ -69,14 +65,7 @@
     fun handleLongClickWhenDisabled() = runTest {
         val enabled = false
 
-        underTest.handleInput(
-            QSTileInputTestKtx.longClick(
-                RotationLockTileModel(
-                    enabled,
-                    false,
-                )
-            )
-        )
+        underTest.handleInput(QSTileInputTestKtx.longClick(RotationLockTileModel(enabled, false)))
 
         QSTileIntentUserInputHandlerSubject.assertThat(inputHandler).handledOneIntentInput {
             assertThat(it.intent.action).isEqualTo(Settings.ACTION_AUTO_ROTATE_SETTINGS)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt
index 7401014..92c7a1e 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapperTest.kt
@@ -25,14 +25,14 @@
 import com.android.systemui.defaultDeviceState
 import com.android.systemui.deviceStateManager
 import com.android.systemui.foldedDeviceStateList
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
 import com.android.systemui.qs.tiles.impl.rotation.qsRotationLockTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.DevicePostureController
 import com.android.systemui.statusbar.policy.devicePostureController
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
 import org.junit.Test
@@ -42,7 +42,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class RotationLockTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val rotationLockTileConfig = kosmos.qsRotationLockTileConfig
     private val devicePostureController = kosmos.devicePostureController
     private val deviceStateManager = kosmos.deviceStateManager
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt
index c286ea7..97bd1997 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractorTest.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
 import com.android.systemui.utils.leaks.FakeDataSaverController
 import com.google.common.truth.Truth
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractorTest.kt
index 87ac034a..ee57b25 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractorTest.kt
@@ -24,9 +24,9 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.animation.DialogTransitionAnimator
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.intentInputs
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.intentInputs
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.shade.domain.interactor.FakeShadeDialogContextInteractor
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapperTest.kt
similarity index 91%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapperTest.kt
index 1fb5048..638b76d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.saver.domain
+package com.android.systemui.qs.tiles.impl.saver.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.widget.Switch
@@ -22,19 +22,19 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
 import com.android.systemui.qs.tiles.impl.saver.qsDataSaverTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class DataSaverTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val dataSaverTileConfig = kosmos.qsDataSaverTileConfig
 
     // Using lazy (versus =) to make sure we override the right context -- see b/311612168
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt
index 41174e7..0c98271 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractorTest.kt
@@ -22,11 +22,11 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.screenRecordRepository
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.runCurrent
@@ -38,7 +38,7 @@
 @EnabledOnRavenwood
 @RunWith(AndroidJUnit4::class)
 class ScreenRecordTileDataInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val screenRecordRepo = kosmos.screenRecordRepository
     private val underTest: ScreenRecordTileDataInteractor =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
index 778c73f..9ffffa4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractorTest.kt
@@ -26,16 +26,16 @@
 import com.android.systemui.animation.Expandable
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
 import com.android.systemui.plugins.ActivityStarter.OnDismissAction
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.screenrecord.RecordingController
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.ScreenRecordRepositoryImpl
 import com.android.systemui.statusbar.phone.KeyguardDismissUtil
+import com.android.systemui.testKosmos
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -49,7 +49,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ScreenRecordTileUserActionInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val keyguardInteractor = kosmos.keyguardInteractor
     private val dialogTransitionAnimator = mock<DialogTransitionAnimator>()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/mapper/ScreenRecordTileMapperTest.kt
similarity index 93%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/mapper/ScreenRecordTileMapperTest.kt
index 3632556..6acfc444 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/ScreenRecordTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/screenrecord/ui/mapper/ScreenRecordTileMapperTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.screenrecord.ui
+package com.android.systemui.qs.tiles.impl.screenrecord.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.text.TextUtils
@@ -23,13 +23,13 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
-import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.ScreenRecordTileMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
+import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.mapper.ScreenRecordTileMapper
 import com.android.systemui.qs.tiles.impl.screenrecord.qsScreenRecordTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
+import com.android.systemui.testKosmos
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -37,7 +37,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ScreenRecordTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val config = kosmos.qsScreenRecordTileConfig
 
     private lateinit var mapper: ScreenRecordTileMapper
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt
index 6c7bb1b..7d1d7d8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractorTest.kt
@@ -23,11 +23,10 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.impl.sensorprivacy.SensorPrivacyToggleTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -44,7 +43,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class SensorPrivacyToggleTileDataInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val mockSensorPrivacyController =
         mock<IndividualSensorPrivacyController> {
@@ -55,7 +54,7 @@
         SensorPrivacyToggleTileDataInteractor(
             testScope.testScheduler,
             mockSensorPrivacyController,
-            CAMERA
+            CAMERA,
         )
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt
index 562e6eb..2630fdd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractorTest.kt
@@ -26,14 +26,13 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
 import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.plugins.activityStarter
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
-import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.SensorPrivacyToggleTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
 import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -48,7 +47,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class SensorPrivacyToggleTileUserActionInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val inputHandler = FakeQSTileIntentUserInputHandler()
     private val keyguardInteractor = kosmos.keyguardInteractor
     // The keyguard repository below is the same one kosmos used to create the interactor above
@@ -64,7 +63,7 @@
             mockActivityStarter,
             mockSensorPrivacyController,
             fakeSafetyCenterManager,
-            CAMERA
+            CAMERA,
         )
 
     @Test
@@ -79,7 +78,7 @@
             .setSensorBlocked(
                 eq(SensorPrivacyManager.Sources.QS_TILE),
                 eq(CAMERA),
-                eq(!originalIsBlocked)
+                eq(!originalIsBlocked),
             )
     }
 
@@ -95,7 +94,7 @@
             .setSensorBlocked(
                 eq(SensorPrivacyManager.Sources.QS_TILE),
                 eq(CAMERA),
-                eq(!originalIsBlocked)
+                eq(!originalIsBlocked),
             )
     }
 
@@ -114,7 +113,7 @@
             .setSensorBlocked(
                 eq(SensorPrivacyManager.Sources.QS_TILE),
                 eq(CAMERA),
-                eq(!originalIsBlocked)
+                eq(!originalIsBlocked),
             )
         verify(mockActivityStarter).postQSRunnableDismissingKeyguard(any())
     }
@@ -150,7 +149,7 @@
                 mockActivityStarter,
                 mockSensorPrivacyController,
                 fakeSafetyCenterManager,
-                MICROPHONE
+                MICROPHONE,
             )
 
         micUserActionInteractor.handleInput(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapperTest.kt
similarity index 89%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapperTest.kt
index e4cd0e0..d9a30b2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.sensorprivacy.ui
+package com.android.systemui.qs.tiles.impl.sensorprivacy.ui.mapper
 
 import android.graphics.drawable.TestStubDrawable
 import android.hardware.SensorPrivacyManager.Sensors.CAMERA
@@ -24,22 +24,23 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
 import com.android.systemui.qs.tiles.impl.sensorprivacy.qsCameraSensorPrivacyToggleTileConfig
 import com.android.systemui.qs.tiles.impl.sensorprivacy.qsMicrophoneSensorPrivacyToggleTileConfig
-import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources.CameraPrivacyTileResources
-import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources.MicrophonePrivacyTileResources
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources.CameraPrivacyTileResources
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources.MicrophonePrivacyTileResources
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class SensorPrivacyToggleTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val cameraConfig = kosmos.qsCameraSensorPrivacyToggleTileConfig
     private val micConfig = kosmos.qsMicrophoneSensorPrivacyToggleTileConfig
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractorTest.kt
similarity index 95%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractorTest.kt
index 96538b7..36a60c4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractorTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.uimodenight.domain
+package com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor
 
 import android.app.UiModeManager
 import android.content.res.Configuration
@@ -27,9 +27,8 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.coroutines.collectValues
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileDataInteractor
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel
 import com.android.systemui.statusbar.phone.ConfigurationControllerImpl
 import com.android.systemui.statusbar.policy.ConfigurationController
 import com.android.systemui.util.mockito.mock
@@ -77,7 +76,7 @@
                 uiModeManager,
                 batteryController,
                 locationController,
-                dateFormatUtil
+                dateFormatUtil,
             )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractorTest.kt
similarity index 89%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileUserActionInteractorTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractorTest.kt
index eea6d16..894a6cb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractorTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.uimodenight.domain
+package com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor
 
 import android.app.UiModeManager
 import android.platform.test.annotations.EnabledOnRavenwood
@@ -22,11 +22,10 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.intentInputs
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.intentInputs
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.uimodenight.UiModeNightTileModelHelper.createModel
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileUserActionInteractor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth
@@ -57,7 +56,7 @@
             UiModeNightTileUserActionInteractor(
                 EmptyCoroutineContext,
                 uiModeManager,
-                qsTileIntentUserActionHandler
+                qsTileIntentUserActionHandler,
             )
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapperTest.kt
similarity index 98%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapperTest.kt
index 8f5f2d3..e7653f2 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapperTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.uimodenight.domain
+package com.android.systemui.qs.tiles.impl.uimodenight.ui.mapper
 
 import android.app.UiModeManager
 import android.graphics.drawable.TestStubDrawable
@@ -25,12 +25,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.uimodenight.UiModeNightTileModelHelper.createModel
 import com.android.systemui.qs.tiles.impl.uimodenight.qsUiModeNightTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import kotlin.reflect.KClass
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -38,7 +38,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class UiModeNightTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val qsTileConfig = kosmos.qsUiModeNightTileConfig
 
     private val mapper by lazy {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractorTest.kt
index 8651300..4f59416 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractorTest.kt
@@ -23,7 +23,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
 import com.android.systemui.utils.leaks.FakeManagedProfileController
 import com.google.common.truth.Truth.assertThat
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractorTest.kt
index 8a63e2c..3d08a01 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractorTest.kt
@@ -22,9 +22,9 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerSubject
-import com.android.systemui.qs.tiles.base.interactor.QSTileInputTestKtx
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerSubject
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInputTestKtx
 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
 import com.android.systemui.utils.leaks.FakeManagedProfileController
 import com.google.common.truth.Truth.assertThat
@@ -40,11 +40,7 @@
     private val inputHandler = FakeQSTileIntentUserInputHandler()
     private val profileController = FakeManagedProfileController(LeakCheck())
 
-    private val underTest =
-        WorkModeTileUserActionInteractor(
-            profileController,
-            inputHandler,
-        )
+    private val underTest = WorkModeTileUserActionInteractor(profileController, inputHandler)
 
     @Test
     fun handleClickWhenEnabled() = runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapperTest.kt
similarity index 93%
rename from packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt
rename to packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapperTest.kt
index 2c81f39..b420d44 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapperTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.work.ui
+package com.android.systemui.qs.tiles.impl.work.ui.mapper
 
 import android.app.admin.DevicePolicyResources
 import android.app.admin.DevicePolicyResourcesManager
@@ -26,12 +26,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileStateSubject
 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
 import com.android.systemui.qs.tiles.impl.work.qsWorkModeTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
@@ -43,7 +43,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class WorkModeTileMapperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val qsTileConfig = kosmos.qsWorkModeTileConfig
     private val devicePolicyManager = kosmos.devicePolicyManager
     private val testLabel = context.getString(R.string.quick_settings_work_mode_label)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
index a8b005f..12ed3f0 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/qs/ui/adapter/QSSceneAdapterImplTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.display.data.repository.displayStateRepository
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
@@ -40,6 +39,7 @@
 import com.android.systemui.settings.brightness.MirrorController
 import com.android.systemui.shade.data.repository.fakeShadeRepository
 import com.android.systemui.shade.domain.interactor.shadeModeInteractor
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
@@ -65,7 +65,7 @@
 @RunWith(AndroidJUnit4::class)
 class QSSceneAdapterImplTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos().apply { testCase = this@QSSceneAdapterImplTest }
+    private val kosmos = testKosmos().apply { testCase = this@QSSceneAdapterImplTest }
     private val testDispatcher = kosmos.testDispatcher
     private val testScope = kosmos.testScope
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
index 7bcaeab..390a5d8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingServiceSessionTest.kt
@@ -28,12 +28,12 @@
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.animation.dialogTransitionAnimator
 import com.android.systemui.concurrency.fakeExecutor
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
 import com.android.systemui.settings.UserContextProvider
 import com.android.systemui.settings.userFileManager
 import com.android.systemui.settings.userTracker
+import com.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeGlobalSettings
 import com.android.traceur.TraceConfig
 import com.google.common.truth.Truth
@@ -52,7 +52,7 @@
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class IssueRecordingServiceSessionTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
     private val bgExecutor = kosmos.fakeExecutor
     private val userContextProvider: UserContextProvider = kosmos.userTracker
     private val dialogTransitionAnimator: DialogTransitionAnimator = kosmos.dialogTransitionAnimator
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt
index 83bdcd2..0510e6ca 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/IssueRecordingStateTest.kt
@@ -22,9 +22,9 @@
 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.android.systemui.testKosmos
 import com.android.systemui.util.settings.fakeGlobalSettings
 import com.google.common.truth.Truth
 import org.junit.Before
@@ -40,7 +40,7 @@
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class IssueRecordingStateTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private lateinit var underTest: IssueRecordingState
     @Mock private lateinit var resolver: ContentResolver
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt
index 737b101..6f0dd16 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/recordissue/ScreenRecordingStartTimeStoreTest.kt
@@ -20,10 +20,10 @@
 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.kosmos.testCase
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.settings.userTracker
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth
 import org.junit.Before
 import org.junit.Test
@@ -34,7 +34,7 @@
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper(setAsMainLooper = true)
 class ScreenRecordingStartTimeStoreTest : SysuiTestCase() {
-    private val userTracker: UserTracker = Kosmos().also { it.testCase = this }.userTracker
+    private val userTracker: UserTracker = testKosmos().also { it.testCase = this }.userTracker
 
     private lateinit var underTest: ScreenRecordingStartTimeStore
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
index a82a7de..7e9487b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/scene/domain/interactor/WindowRootViewVisibilityInteractorTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
 import com.android.systemui.keyguard.shared.model.StatusBarState
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
@@ -38,6 +37,7 @@
 import com.android.systemui.statusbar.notification.headsup.HeadsUpManager
 import com.android.systemui.statusbar.notification.init.NotificationsController
 import com.android.systemui.statusbar.notification.shared.NotificationsLiveDataStoreRefactor
+import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
@@ -57,7 +57,7 @@
 @RunWith(AndroidJUnit4::class)
 class WindowRootViewVisibilityInteractorTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val testDispatcher = StandardTestDispatcher()
     private val iStatusBarService = mock<IStatusBarService>()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
index 9724974..bd54166 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/screenrecord/data/repository/ScreenRecordRepositoryTest.kt
@@ -21,10 +21,10 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.screenrecord.RecordingController
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -39,7 +39,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ScreenRecordRepositoryTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val recordingController = mock<RecordingController>()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
index c6ce581..0c90d07 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerImplTest.kt
@@ -25,7 +25,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.assist.AssistManager
 import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.LogBuffer
 import com.android.systemui.plugins.statusbar.StatusBarStateController
@@ -43,6 +42,7 @@
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
+import com.android.systemui.testKosmos
 import com.android.systemui.util.concurrency.FakeExecutor
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -63,7 +63,7 @@
 @SmallTest
 class ShadeControllerImplTest : SysuiTestCase() {
     private val executor = FakeExecutor(FakeSystemClock())
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
     @Mock private lateinit var commandQueue: CommandQueue
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
index 054c1b8..32eec56 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shade/ShadeControllerSceneImplTest.kt
@@ -27,7 +27,6 @@
 import com.android.systemui.flags.fakeFeatureFlagsClassic
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository
 import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.scene.domain.interactor.sceneInteractor
@@ -35,6 +34,7 @@
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.statusbar.CommandQueue
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -52,7 +52,7 @@
 @RunWith(AndroidJUnit4::class)
 @EnableSceneContainer
 class ShadeControllerSceneImplTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
     private val sceneInteractor by lazy { kosmos.sceneInteractor }
     private val deviceEntryInteractor by lazy { kosmos.deviceEntryInteractor }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index ddad230..2f2fafa 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -25,8 +25,8 @@
 import com.android.systemui.plugins.PluginLifecycleManager
 import com.android.systemui.plugins.PluginListener
 import com.android.systemui.plugins.PluginManager
+import com.android.systemui.plugins.clocks.ClockAxisStyle
 import com.android.systemui.plugins.clocks.ClockController
-import com.android.systemui.plugins.clocks.ClockFontAxisSetting
 import com.android.systemui.plugins.clocks.ClockId
 import com.android.systemui.plugins.clocks.ClockMessageBuffers
 import com.android.systemui.plugins.clocks.ClockMetadata
@@ -543,7 +543,7 @@
 
     @Test
     fun jsonDeserialization_fontAxes() {
-        val expected = ClockSettings(axes = listOf(ClockFontAxisSetting("KEY", 10f)))
+        val expected = ClockSettings(axes = ClockAxisStyle("KEY", 10f))
         val json = JSONObject("""{"axes":[{"key":"KEY","value":10}]}""")
         val actual = ClockSettings.fromJson(json)
         assertEquals(expected, actual)
@@ -576,7 +576,7 @@
 
     @Test
     fun jsonSerialization_axisSettings() {
-        val settings = ClockSettings(axes = listOf(ClockFontAxisSetting("KEY", 10f)))
+        val settings = ClockSettings(axes = ClockAxisStyle("KEY", 10f))
         val actual = ClockSettings.toJson(settings)
         val expected = JSONObject("""{"metadata":{},"axes":[{"key":"KEY","value":10}]}""")
         assertEquals(expected.toString(), actual.toString())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
index 17509dc..8e2d1b5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionExtensionsTest.kt
@@ -3,64 +3,57 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.condition.testStart
+import com.android.systemui.condition.testStop
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.emptyFlow
 import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ConditionExtensionsTest : SysuiTestCase() {
-    private lateinit var testScope: TestScope
-    private val testCallback =
-        Condition.Callback {
-            // This is a no-op
-        }
-
-    @Before
-    fun setUp() {
-        testScope = TestScope(UnconfinedTestDispatcher())
-    }
+    private val kosmos = testKosmos()
 
     @Test
     fun flowInitiallyTrue() =
-        testScope.runTest {
+        kosmos.runTest {
             val flow = flowOf(true)
-            val condition = flow.toCondition(scope = this, Condition.START_EAGERLY)
+            val condition = flow.toCondition(scope = testScope, Condition.START_EAGERLY)
 
             assertThat(condition.isConditionSet).isFalse()
 
-            condition.testStart()
+            testStart(condition)
             assertThat(condition.isConditionSet).isTrue()
             assertThat(condition.isConditionMet).isTrue()
         }
 
     @Test
     fun flowInitiallyFalse() =
-        testScope.runTest {
+        kosmos.runTest {
             val flow = flowOf(false)
-            val condition = flow.toCondition(scope = this, Condition.START_EAGERLY)
+            val condition = flow.toCondition(scope = testScope, Condition.START_EAGERLY)
 
             assertThat(condition.isConditionSet).isFalse()
 
-            condition.testStart()
+            testStart(condition)
             assertThat(condition.isConditionSet).isTrue()
             assertThat(condition.isConditionMet).isFalse()
         }
 
     @Test
     fun emptyFlowWithNoInitialValue() =
-        testScope.runTest {
+        kosmos.runTest {
             val flow = emptyFlow<Boolean>()
-            val condition = flow.toCondition(scope = this, Condition.START_EAGERLY)
-            condition.testStop()
+            val condition = flow.toCondition(scope = testScope, Condition.START_EAGERLY)
+            testStop(condition)
 
             assertThat(condition.isConditionSet).isFalse()
             assertThat(condition.isConditionMet).isFalse()
@@ -68,15 +61,15 @@
 
     @Test
     fun emptyFlowWithInitialValueOfTrue() =
-        testScope.runTest {
+        kosmos.runTest {
             val flow = emptyFlow<Boolean>()
             val condition =
                 flow.toCondition(
-                    scope = this,
+                    scope = testScope,
                     strategy = Condition.START_EAGERLY,
                     initialValue = true,
                 )
-            condition.testStart()
+            testStart(condition)
 
             assertThat(condition.isConditionSet).isTrue()
             assertThat(condition.isConditionMet).isTrue()
@@ -84,15 +77,15 @@
 
     @Test
     fun emptyFlowWithInitialValueOfFalse() =
-        testScope.runTest {
+        kosmos.runTest {
             val flow = emptyFlow<Boolean>()
             val condition =
                 flow.toCondition(
-                    scope = this,
+                    scope = testScope,
                     strategy = Condition.START_EAGERLY,
                     initialValue = false,
                 )
-            condition.testStart()
+            testStart(condition)
 
             assertThat(condition.isConditionSet).isTrue()
             assertThat(condition.isConditionMet).isFalse()
@@ -100,42 +93,36 @@
 
     @Test
     fun conditionUpdatesWhenFlowEmitsNewValue() =
-        testScope.runTest {
+        kosmos.runTest {
             val flow = MutableStateFlow(false)
-            val condition = flow.toCondition(scope = this, strategy = Condition.START_EAGERLY)
-            condition.testStart()
+            val condition = flow.toCondition(scope = testScope, strategy = Condition.START_EAGERLY)
+            testStart(condition)
 
             assertThat(condition.isConditionSet).isTrue()
             assertThat(condition.isConditionMet).isFalse()
 
             flow.value = true
+            runCurrent()
             assertThat(condition.isConditionMet).isTrue()
 
             flow.value = false
+            runCurrent()
             assertThat(condition.isConditionMet).isFalse()
 
-            condition.testStop()
+            testStop(condition)
         }
 
     @Test
     fun stoppingConditionUnsubscribesFromFlow() =
-        testScope.runTest {
+        kosmos.runTest {
             val flow = MutableSharedFlow<Boolean>()
-            val condition = flow.toCondition(scope = this, strategy = Condition.START_EAGERLY)
+            val condition = flow.toCondition(scope = testScope, strategy = Condition.START_EAGERLY)
             assertThat(flow.subscriptionCount.value).isEqualTo(0)
 
-            condition.testStart()
+            testStart(condition)
             assertThat(flow.subscriptionCount.value).isEqualTo(1)
 
-            condition.testStop()
+            testStop(condition)
             assertThat(flow.subscriptionCount.value).isEqualTo(0)
         }
-
-    fun Condition.testStart() {
-        addCallback(testCallback)
-    }
-
-    fun Condition.testStop() {
-        removeCallback(testCallback)
-    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
deleted file mode 100644
index 267f22b..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.java
+++ /dev/null
@@ -1,621 +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.systemui.shared.condition;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.anyBoolean;
-import static org.mockito.Mockito.clearInvocations;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.log.TableLogBufferBase;
-import com.android.systemui.util.concurrency.FakeExecutor;
-import com.android.systemui.util.time.FakeSystemClock;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ConditionMonitorTest extends SysuiTestCase {
-    private FakeCondition mCondition1;
-    private FakeCondition mCondition2;
-    private FakeCondition mCondition3;
-    private HashSet<Condition> mConditions;
-    private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
-
-    @Mock
-    private CoroutineScope mScope;
-    @Mock
-    private TableLogBufferBase mLogBuffer;
-
-    private Monitor mConditionMonitor;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-
-        mCondition1 = spy(new FakeCondition(mScope));
-        mCondition2 = spy(new FakeCondition(mScope));
-        mCondition3 = spy(new FakeCondition(mScope));
-        mConditions = new HashSet<>(Arrays.asList(mCondition1, mCondition2, mCondition3));
-
-        mConditionMonitor = new Monitor(mExecutor);
-    }
-
-    public Monitor.Subscription.Builder getDefaultBuilder(
-            Monitor.Callback callback) {
-        return new Monitor.Subscription.Builder(callback)
-                .addConditions(mConditions);
-    }
-
-    private Condition createMockCondition() {
-        final Condition condition = Mockito.mock(
-                Condition.class);
-        when(condition.isConditionSet()).thenReturn(true);
-        return condition;
-    }
-
-    @Test
-    public void testOverridingCondition() {
-        final Condition overridingCondition = createMockCondition();
-        final Condition regularCondition = createMockCondition();
-        final Monitor.Callback callback = Mockito.mock(
-                Monitor.Callback.class);
-
-        final Monitor.Callback referenceCallback = Mockito.mock(
-                Monitor.Callback.class);
-
-        final Monitor
-                monitor = new Monitor(mExecutor);
-
-        monitor.addSubscription(getDefaultBuilder(callback)
-                .addCondition(overridingCondition)
-                .addCondition(regularCondition)
-                .build());
-
-        monitor.addSubscription(getDefaultBuilder(referenceCallback)
-                .addCondition(regularCondition)
-                .build());
-
-        mExecutor.runAllReady();
-
-        when(overridingCondition.isOverridingCondition()).thenReturn(true);
-        when(overridingCondition.isConditionMet()).thenReturn(true);
-        when(regularCondition.isConditionMet()).thenReturn(false);
-
-        final ArgumentCaptor<Condition.Callback> mCallbackCaptor =
-                ArgumentCaptor.forClass(Condition.Callback.class);
-
-        verify(overridingCondition).addCallback(mCallbackCaptor.capture());
-
-        mCallbackCaptor.getValue().onConditionChanged(overridingCondition);
-        mExecutor.runAllReady();
-
-        verify(callback).onConditionsChanged(eq(true));
-        verify(referenceCallback).onConditionsChanged(eq(false));
-        Mockito.clearInvocations(callback);
-        Mockito.clearInvocations(referenceCallback);
-
-        when(regularCondition.isConditionMet()).thenReturn(true);
-        when(overridingCondition.isConditionMet()).thenReturn(false);
-
-        mCallbackCaptor.getValue().onConditionChanged(overridingCondition);
-        mExecutor.runAllReady();
-
-        verify(callback).onConditionsChanged(eq(false));
-        verify(referenceCallback, never()).onConditionsChanged(anyBoolean());
-    }
-
-    /**
-     * Ensures that when multiple overriding conditions are present, it is the aggregate of those
-     * conditions that are considered.
-     */
-    @Test
-    public void testMultipleOverridingConditions() {
-        final Condition overridingCondition = createMockCondition();
-        final Condition overridingCondition2 = createMockCondition();
-        final Condition regularCondition = createMockCondition();
-        final Monitor.Callback callback = Mockito.mock(
-                Monitor.Callback.class);
-
-        final Monitor
-                monitor = new Monitor(mExecutor);
-
-        monitor.addSubscription(getDefaultBuilder(callback)
-                .addCondition(overridingCondition)
-                .addCondition(overridingCondition2)
-                .build());
-
-        mExecutor.runAllReady();
-
-        when(overridingCondition.isOverridingCondition()).thenReturn(true);
-        when(overridingCondition.isConditionMet()).thenReturn(true);
-        when(overridingCondition2.isOverridingCondition()).thenReturn(true);
-        when(overridingCondition.isConditionMet()).thenReturn(false);
-        when(regularCondition.isConditionMet()).thenReturn(true);
-
-        final ArgumentCaptor<Condition.Callback> mCallbackCaptor =
-                ArgumentCaptor.forClass(Condition.Callback.class);
-
-        verify(overridingCondition).addCallback(mCallbackCaptor.capture());
-
-        mCallbackCaptor.getValue().onConditionChanged(overridingCondition);
-        mExecutor.runAllReady();
-
-        verify(callback).onConditionsChanged(eq(false));
-        Mockito.clearInvocations(callback);
-    }
-
-    // Ensure that updating a callback that is removed doesn't result in an exception due to the
-    // absence of the condition.
-    @Test
-    public void testUpdateRemovedCallback() {
-        final Monitor.Callback callback1 =
-                mock(Monitor.Callback.class);
-        final Monitor.Subscription.Token subscription1 =
-                mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build());
-        ArgumentCaptor<Condition.Callback> monitorCallback =
-                ArgumentCaptor.forClass(Condition.Callback.class);
-        mExecutor.runAllReady();
-        verify(mCondition1).addCallback(monitorCallback.capture());
-        // This will execute first before the handler for onConditionChanged.
-        mConditionMonitor.removeSubscription(subscription1);
-        monitorCallback.getValue().onConditionChanged(mCondition1);
-        mExecutor.runAllReady();
-    }
-
-    @Test
-    public void addCallback_addFirstCallback_addCallbackToAllConditions() {
-        final Monitor.Callback callback1 =
-                mock(Monitor.Callback.class);
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build());
-        mExecutor.runAllReady();
-        mConditions.forEach(condition -> verify(condition).addCallback(any()));
-
-        final Monitor.Callback callback2 =
-                mock(Monitor.Callback.class);
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback2).build());
-        mExecutor.runAllReady();
-        mConditions.forEach(condition -> verify(condition, times(1)).addCallback(any()));
-    }
-
-    @Test
-    public void addCallback_addFirstCallback_reportWithDefaultValue() {
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(false);
-    }
-
-    @Test
-    public void addCallback_addSecondCallback_reportWithExistingValue() {
-        final Monitor.Callback callback1 =
-                mock(Monitor.Callback.class);
-        final Condition condition = mock(
-                Condition.class);
-        when(condition.isConditionMet()).thenReturn(true);
-        final Monitor
-                monitor = new Monitor(mExecutor);
-        monitor.addSubscription(new Monitor.Subscription.Builder(callback1)
-                .addCondition(condition)
-                .build());
-
-        final Monitor.Callback callback2 =
-                mock(Monitor.Callback.class);
-        monitor.addSubscription(new Monitor.Subscription.Builder(callback2)
-                .addCondition(condition)
-                .build());
-        mExecutor.runAllReady();
-        verify(callback2).onConditionsChanged(eq(true));
-    }
-
-    @Test
-    public void addCallback_noConditions_reportAllConditionsMet() {
-        final Monitor
-                monitor = new Monitor(mExecutor);
-        final Monitor.Callback callback = mock(
-                Monitor.Callback.class);
-
-        monitor.addSubscription(new Monitor.Subscription.Builder(callback).build());
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-    }
-
-    @Test
-    public void addCallback_preCondition_noConditions_reportAllConditionsMet() {
-        final Monitor
-                monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(mCondition1)));
-        final Monitor.Callback callback = mock(
-                Monitor.Callback.class);
-
-        monitor.addSubscription(new Monitor.Subscription.Builder(callback).build());
-        mExecutor.runAllReady();
-        verify(callback, never()).onConditionsChanged(true);
-        mCondition1.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-    }
-
-    @Test
-    public void removeCallback_noFailureOnDoubleRemove() {
-        final Condition condition = mock(
-                Condition.class);
-        final Monitor
-                monitor = new Monitor(mExecutor);
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-        final Monitor.Subscription.Token token = monitor.addSubscription(
-                new Monitor.Subscription.Builder(callback).addCondition(condition).build()
-        );
-        monitor.removeSubscription(token);
-        mExecutor.runAllReady();
-        // Ensure second removal doesn't cause an exception.
-        monitor.removeSubscription(token);
-        mExecutor.runAllReady();
-    }
-
-    @Test
-    public void removeCallback_shouldNoLongerReceiveUpdate() {
-        final Condition condition = mock(
-                Condition.class);
-        final Monitor
-                monitor = new Monitor(mExecutor);
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-        final Monitor.Subscription.Token token = monitor.addSubscription(
-                new Monitor.Subscription.Builder(callback).addCondition(condition).build()
-        );
-        monitor.removeSubscription(token);
-        mExecutor.runAllReady();
-        clearInvocations(callback);
-
-        final ArgumentCaptor<Condition.Callback> conditionCallbackCaptor =
-                ArgumentCaptor.forClass(Condition.Callback.class);
-        verify(condition).addCallback(conditionCallbackCaptor.capture());
-
-        final Condition.Callback conditionCallback = conditionCallbackCaptor.getValue();
-        verify(condition).removeCallback(conditionCallback);
-    }
-
-    @Test
-    public void removeCallback_removeLastCallback_removeCallbackFromAllConditions() {
-        final Monitor.Callback callback1 =
-                mock(Monitor.Callback.class);
-        final Monitor.Callback callback2 =
-                mock(Monitor.Callback.class);
-        final Monitor.Subscription.Token subscription1 =
-                mConditionMonitor.addSubscription(getDefaultBuilder(callback1).build());
-        final Monitor.Subscription.Token subscription2 =
-                mConditionMonitor.addSubscription(getDefaultBuilder(callback2).build());
-
-        mConditionMonitor.removeSubscription(subscription1);
-        mExecutor.runAllReady();
-        mConditions.forEach(condition -> verify(condition, never()).removeCallback(any()));
-
-        mConditionMonitor.removeSubscription(subscription2);
-        mExecutor.runAllReady();
-        mConditions.forEach(condition -> verify(condition).removeCallback(any()));
-    }
-
-    @Test
-    public void updateCallbacks_allConditionsMet_reportTrue() {
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
-        clearInvocations(callback);
-
-        mCondition1.fakeUpdateCondition(true);
-        mCondition2.fakeUpdateCondition(true);
-        mCondition3.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-
-        verify(callback).onConditionsChanged(true);
-    }
-
-    @Test
-    public void updateCallbacks_oneConditionStoppedMeeting_reportFalse() {
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
-
-        mCondition1.fakeUpdateCondition(true);
-        mCondition2.fakeUpdateCondition(true);
-        mCondition3.fakeUpdateCondition(true);
-        clearInvocations(callback);
-
-        mCondition1.fakeUpdateCondition(false);
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(false);
-    }
-
-    @Test
-    public void updateCallbacks_shouldOnlyUpdateWhenValueChanges() {
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(false);
-        clearInvocations(callback);
-
-        mCondition1.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-        verify(callback, never()).onConditionsChanged(anyBoolean());
-
-        mCondition2.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-        verify(callback, never()).onConditionsChanged(anyBoolean());
-
-        mCondition3.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-    }
-
-    @Test
-    public void clearCondition_shouldUpdateValue() {
-        mCondition1.fakeUpdateCondition(false);
-        mCondition2.fakeUpdateCondition(true);
-        mCondition3.fakeUpdateCondition(true);
-
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback).build());
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(false);
-
-        mCondition1.clearCondition();
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-    }
-
-    @Test
-    public void unsetCondition_shouldNotAffectValue() {
-        final FakeCondition settableCondition = new FakeCondition(mScope, null, false);
-        mCondition1.fakeUpdateCondition(true);
-        mCondition2.fakeUpdateCondition(true);
-        mCondition3.fakeUpdateCondition(true);
-
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback)
-                .addCondition(settableCondition)
-                .build());
-
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-    }
-
-    @Test
-    public void setUnsetCondition_shouldAffectValue() {
-        final FakeCondition settableCondition = new FakeCondition(mScope, null, false);
-        mCondition1.fakeUpdateCondition(true);
-        mCondition2.fakeUpdateCondition(true);
-        mCondition3.fakeUpdateCondition(true);
-
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback)
-                .addCondition(settableCondition)
-                .build());
-
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-        clearInvocations(callback);
-
-        settableCondition.fakeUpdateCondition(false);
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(false);
-        clearInvocations(callback);
-
-
-        settableCondition.clearCondition();
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-    }
-
-    @Test
-    public void clearingOverridingCondition_shouldBeExcluded() {
-        final FakeCondition overridingCondition = new FakeCondition(mScope, true, true);
-        mCondition1.fakeUpdateCondition(false);
-        mCondition2.fakeUpdateCondition(false);
-        mCondition3.fakeUpdateCondition(false);
-
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback)
-                .addCondition(overridingCondition)
-                .build());
-
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-        clearInvocations(callback);
-
-        overridingCondition.clearCondition();
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(false);
-    }
-
-    @Test
-    public void settingUnsetOverridingCondition_shouldBeIncluded() {
-        final FakeCondition overridingCondition = new FakeCondition(mScope, null, true);
-        mCondition1.fakeUpdateCondition(false);
-        mCondition2.fakeUpdateCondition(false);
-        mCondition3.fakeUpdateCondition(false);
-
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-
-        mConditionMonitor.addSubscription(getDefaultBuilder(callback)
-                .addCondition(overridingCondition)
-                .build());
-
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(false);
-        clearInvocations(callback);
-
-        overridingCondition.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-        verify(callback).onConditionsChanged(true);
-    }
-
-    /**
-     * Ensures that the result of a condition being true leads to its nested condition being
-     * activated.
-     */
-    @Test
-    public void testNestedCondition() {
-        mCondition1.fakeUpdateCondition(false);
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-
-        mCondition2.fakeUpdateCondition(false);
-
-        // Create a nested condition
-        mConditionMonitor.addSubscription(new Monitor.Subscription.Builder(
-                new Monitor.Subscription.Builder(callback)
-                        .addCondition(mCondition2)
-                        .build())
-                .addCondition(mCondition1)
-                .build());
-
-        mExecutor.runAllReady();
-
-        // Ensure the nested condition callback is not called at all.
-        verify(callback, never()).onActiveChanged(anyBoolean());
-        verify(callback, never()).onConditionsChanged(anyBoolean());
-
-        // Update the inner condition to true and ensure that the nested condition is not triggered.
-        mCondition2.fakeUpdateCondition(true);
-        verify(callback, never()).onConditionsChanged(anyBoolean());
-        mCondition2.fakeUpdateCondition(false);
-
-        // Set outer condition and make sure the inner condition becomes active and reports that
-        // conditions aren't met
-        mCondition1.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-
-        verify(callback).onActiveChanged(eq(true));
-        verify(callback).onConditionsChanged(eq(false));
-
-        Mockito.clearInvocations(callback);
-
-        // Update the inner condition and make sure the callback is updated.
-        mCondition2.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-
-        verify(callback).onConditionsChanged(true);
-
-        Mockito.clearInvocations(callback);
-        // Invalidate outer condition and make sure callback is informed, but the last state is
-        // not affected.
-        mCondition1.fakeUpdateCondition(false);
-        mExecutor.runAllReady();
-
-        verify(callback).onActiveChanged(eq(false));
-        verify(callback, never()).onConditionsChanged(anyBoolean());
-    }
-
-    /**
-     * Ensure preconditions are applied to every subscription added to a monitor.
-     */
-    @Test
-    public void testPreconditionMonitor() {
-        final Monitor.Callback callback =
-                mock(Monitor.Callback.class);
-
-        mCondition2.fakeUpdateCondition(true);
-        final Monitor monitor = new Monitor(mExecutor, new HashSet<>(Arrays.asList(mCondition1)));
-
-        monitor.addSubscription(new Monitor.Subscription.Builder(callback)
-                .addCondition(mCondition2)
-                .build());
-
-        mExecutor.runAllReady();
-
-        verify(callback, never()).onActiveChanged(anyBoolean());
-        verify(callback, never()).onConditionsChanged(anyBoolean());
-
-        mCondition1.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-
-        verify(callback).onActiveChanged(eq(true));
-        verify(callback).onConditionsChanged(eq(true));
-    }
-
-    @Test
-    public void testLoggingCallback() {
-        final Monitor monitor = new Monitor(mExecutor, Collections.emptySet(), mLogBuffer);
-
-        final FakeCondition condition = new FakeCondition(mScope);
-        final FakeCondition overridingCondition = new FakeCondition(
-                mScope,
-                /* initialValue= */ false,
-                /* overriding= */ true);
-
-        final Monitor.Callback callback = mock(Monitor.Callback.class);
-        monitor.addSubscription(getDefaultBuilder(callback)
-                .addCondition(condition)
-                .addCondition(overridingCondition)
-                .build());
-        mExecutor.runAllReady();
-
-        // condition set to true
-        condition.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-        verify(mLogBuffer).logChange("", "FakeCondition", "True");
-
-        // condition set to false
-        condition.fakeUpdateCondition(false);
-        mExecutor.runAllReady();
-        verify(mLogBuffer).logChange("", "FakeCondition", "False");
-
-        // condition unset
-        condition.fakeClearCondition();
-        mExecutor.runAllReady();
-        verify(mLogBuffer).logChange("", "FakeCondition", "Invalid");
-
-        // overriding condition set to true
-        overridingCondition.fakeUpdateCondition(true);
-        mExecutor.runAllReady();
-        verify(mLogBuffer).logChange("", "FakeCondition[OVRD]", "True");
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.kt
new file mode 100644
index 0000000..dc45c53
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionMonitorTest.kt
@@ -0,0 +1,605 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.shared.condition
+
+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.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.plugins.log.TableLogBufferBase
+import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.time.FakeSystemClock
+import java.util.Arrays
+import java.util.function.Consumer
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyBoolean
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.verify
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ConditionMonitorTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+
+    private lateinit var condition1: FakeCondition
+    private lateinit var condition2: FakeCondition
+    private lateinit var condition3: FakeCondition
+    private lateinit var conditions: HashSet<Condition>
+    private val executor = FakeExecutor(FakeSystemClock())
+
+    @Mock private lateinit var logBuffer: TableLogBufferBase
+
+    private lateinit var conditionMonitor: Monitor
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+
+        condition1 = Mockito.spy(FakeCondition(kosmos.testScope))
+        condition2 = Mockito.spy(FakeCondition(kosmos.testScope))
+        condition3 = Mockito.spy(FakeCondition(kosmos.testScope))
+        conditions = HashSet(listOf(condition1, condition2, condition3))
+
+        conditionMonitor = Monitor(executor)
+    }
+
+    fun getDefaultBuilder(callback: Monitor.Callback): Monitor.Subscription.Builder {
+        return Monitor.Subscription.Builder(callback).addConditions(conditions)
+    }
+
+    private fun createMockCondition(): Condition {
+        val condition: Condition = mock()
+        whenever(condition.isConditionSet).thenReturn(true)
+        return condition
+    }
+
+    @Test
+    fun testOverridingCondition() =
+        kosmos.runTest {
+            val overridingCondition = createMockCondition()
+            val regularCondition = createMockCondition()
+            val callback: Monitor.Callback = mock()
+            val referenceCallback: Monitor.Callback = mock()
+
+            val monitor = Monitor(executor)
+
+            monitor.addSubscription(
+                getDefaultBuilder(callback)
+                    .addCondition(overridingCondition)
+                    .addCondition(regularCondition)
+                    .build()
+            )
+
+            monitor.addSubscription(
+                getDefaultBuilder(referenceCallback).addCondition(regularCondition).build()
+            )
+
+            executor.runAllReady()
+
+            whenever(overridingCondition.isOverridingCondition).thenReturn(true)
+            whenever(overridingCondition.isConditionMet).thenReturn(true)
+            whenever(regularCondition.isConditionMet).thenReturn(false)
+
+            val callbackCaptor = argumentCaptor<Condition.Callback>()
+
+            Mockito.verify(overridingCondition).addCallback(callbackCaptor.capture())
+
+            callbackCaptor.lastValue.onConditionChanged(overridingCondition)
+            executor.runAllReady()
+
+            Mockito.verify(callback).onConditionsChanged(eq(true))
+            Mockito.verify(referenceCallback).onConditionsChanged(eq(false))
+            Mockito.clearInvocations(callback)
+            Mockito.clearInvocations(referenceCallback)
+
+            whenever(regularCondition.isConditionMet).thenReturn(true)
+            whenever(overridingCondition.isConditionMet).thenReturn(false)
+
+            callbackCaptor.lastValue.onConditionChanged(overridingCondition)
+            executor.runAllReady()
+
+            Mockito.verify(callback).onConditionsChanged(eq(false))
+            Mockito.verify(referenceCallback, Mockito.never()).onConditionsChanged(anyBoolean())
+        }
+
+    /**
+     * Ensures that when multiple overriding conditions are present, it is the aggregate of those
+     * conditions that are considered.
+     */
+    @Test
+    fun testMultipleOverridingConditions() =
+        kosmos.runTest {
+            val overridingCondition = createMockCondition()
+            val overridingCondition2 = createMockCondition()
+            val regularCondition = createMockCondition()
+            val callback: Monitor.Callback = mock()
+
+            val monitor = Monitor(executor)
+
+            monitor.addSubscription(
+                getDefaultBuilder(callback)
+                    .addCondition(overridingCondition)
+                    .addCondition(overridingCondition2)
+                    .build()
+            )
+
+            executor.runAllReady()
+
+            whenever(overridingCondition.isOverridingCondition).thenReturn(true)
+            whenever(overridingCondition.isConditionMet).thenReturn(true)
+            whenever(overridingCondition2.isOverridingCondition).thenReturn(true)
+            whenever(overridingCondition.isConditionMet).thenReturn(false)
+            whenever(regularCondition.isConditionMet).thenReturn(true)
+
+            val mCallbackCaptor = argumentCaptor<Condition.Callback>()
+
+            Mockito.verify(overridingCondition).addCallback(mCallbackCaptor.capture())
+
+            mCallbackCaptor.lastValue.onConditionChanged(overridingCondition)
+            executor.runAllReady()
+
+            Mockito.verify(callback).onConditionsChanged(eq(false))
+            Mockito.clearInvocations(callback)
+        }
+
+    // Ensure that updating a callback that is removed doesn't result in an exception due to the
+    // absence of the condition.
+    @Test
+    fun testUpdateRemovedCallback() =
+        kosmos.runTest {
+            val callback1: Monitor.Callback = mock()
+            val subscription1 =
+                conditionMonitor.addSubscription(getDefaultBuilder(callback1).build())
+            val monitorCallback = argumentCaptor<Condition.Callback>()
+            executor.runAllReady()
+            Mockito.verify(condition1).addCallback(monitorCallback.capture())
+            // This will execute first before the handler for onConditionChanged.
+            conditionMonitor.removeSubscription(subscription1)
+            monitorCallback.lastValue.onConditionChanged(condition1)
+            executor.runAllReady()
+        }
+
+    @Test
+    fun addCallback_addFirstCallback_addCallbackToAllConditions() {
+        val callback1: Monitor.Callback = mock()
+        conditionMonitor.addSubscription(getDefaultBuilder(callback1).build())
+        executor.runAllReady()
+        conditions.forEach(
+            Consumer { condition: Condition -> Mockito.verify(condition).addCallback(any()) }
+        )
+
+        val callback2: Monitor.Callback = mock()
+        conditionMonitor.addSubscription(getDefaultBuilder(callback2).build())
+        executor.runAllReady()
+        conditions.forEach(
+            Consumer { condition: Condition ->
+                Mockito.verify(condition, Mockito.times(1)).addCallback(any())
+            }
+        )
+    }
+
+    @Test
+    fun addCallback_addFirstCallback_reportWithDefaultValue() =
+        kosmos.runTest {
+            val callback: Monitor.Callback = mock()
+            conditionMonitor.addSubscription(getDefaultBuilder(callback).build())
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(false)
+        }
+
+    @Test
+    fun addCallback_addSecondCallback_reportWithExistingValue() =
+        kosmos.runTest {
+            val callback1: Monitor.Callback = mock()
+            val condition: Condition = mock()
+
+            whenever(condition.isConditionMet).thenReturn(true)
+            val monitor = Monitor(executor)
+            monitor.addSubscription(
+                Monitor.Subscription.Builder(callback1).addCondition(condition).build()
+            )
+
+            val callback2: Monitor.Callback = mock()
+            monitor.addSubscription(
+                Monitor.Subscription.Builder(callback2).addCondition(condition).build()
+            )
+            executor.runAllReady()
+            Mockito.verify(callback2).onConditionsChanged(eq(true))
+        }
+
+    @Test
+    fun addCallback_noConditions_reportAllConditionsMet() =
+        kosmos.runTest {
+            val monitor = Monitor(executor)
+            val callback: Monitor.Callback = mock()
+
+            monitor.addSubscription(Monitor.Subscription.Builder(callback).build())
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+
+    @Test
+    fun addCallback_preCondition_noConditions_reportAllConditionsMet() =
+        kosmos.runTest {
+            val monitor = Monitor(executor, HashSet<Condition?>(Arrays.asList(condition1)))
+            val callback: Monitor.Callback = mock()
+
+            monitor.addSubscription(Monitor.Subscription.Builder(callback).build())
+            executor.runAllReady()
+            Mockito.verify(callback, Mockito.never()).onConditionsChanged(true)
+            condition1.fakeUpdateCondition(true)
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+
+    @Test
+    fun removeCallback_noFailureOnDoubleRemove() =
+        kosmos.runTest {
+            val condition: Condition = mock()
+            val monitor = Monitor(executor)
+            val callback: Monitor.Callback = mock()
+            val token =
+                monitor.addSubscription(
+                    Monitor.Subscription.Builder(callback).addCondition(condition).build()
+                )
+            monitor.removeSubscription(token)
+            executor.runAllReady()
+            // Ensure second removal doesn't cause an exception.
+            monitor.removeSubscription(token)
+            executor.runAllReady()
+        }
+
+    @Test
+    fun removeCallback_shouldNoLongerReceiveUpdate() =
+        kosmos.runTest {
+            val condition: Condition = mock()
+            val monitor = Monitor(executor)
+            val callback: Monitor.Callback = mock()
+            val token =
+                monitor.addSubscription(
+                    Monitor.Subscription.Builder(callback).addCondition(condition).build()
+                )
+            monitor.removeSubscription(token)
+            executor.runAllReady()
+            Mockito.clearInvocations(callback)
+
+            val conditionCallbackCaptor = argumentCaptor<Condition.Callback>()
+            Mockito.verify(condition).addCallback(conditionCallbackCaptor.capture())
+
+            val conditionCallback = conditionCallbackCaptor.lastValue
+            Mockito.verify(condition).removeCallback(conditionCallback)
+        }
+
+    @Test
+    fun removeCallback_removeLastCallback_removeCallbackFromAllConditions() =
+        kosmos.runTest {
+            val callback1: Monitor.Callback = mock()
+            val callback2: Monitor.Callback = mock()
+            val subscription1 =
+                conditionMonitor.addSubscription(getDefaultBuilder(callback1).build())
+            val subscription2 =
+                conditionMonitor.addSubscription(getDefaultBuilder(callback2).build())
+
+            conditionMonitor.removeSubscription(subscription1)
+            executor.runAllReady()
+            conditions.forEach(
+                Consumer { condition: Condition ->
+                    verify(condition, Mockito.never()).removeCallback(any())
+                }
+            )
+
+            conditionMonitor.removeSubscription(subscription2)
+            executor.runAllReady()
+            conditions.forEach(
+                Consumer { condition: Condition -> Mockito.verify(condition).removeCallback(any()) }
+            )
+        }
+
+    @Test
+    fun updateCallbacks_allConditionsMet_reportTrue() =
+        kosmos.runTest {
+            val callback: Monitor.Callback = mock()
+            conditionMonitor.addSubscription(getDefaultBuilder(callback).build())
+            Mockito.clearInvocations(callback)
+
+            condition1.fakeUpdateCondition(true)
+            condition2.fakeUpdateCondition(true)
+            condition3.fakeUpdateCondition(true)
+            executor.runAllReady()
+
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+
+    @Test
+    fun updateCallbacks_oneConditionStoppedMeeting_reportFalse() =
+        kosmos.runTest {
+            val callback: Monitor.Callback = mock()
+            conditionMonitor.addSubscription(getDefaultBuilder(callback).build())
+
+            condition1.fakeUpdateCondition(true)
+            condition2.fakeUpdateCondition(true)
+            condition3.fakeUpdateCondition(true)
+            Mockito.clearInvocations(callback)
+
+            condition1.fakeUpdateCondition(false)
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(false)
+        }
+
+    @Test
+    fun updateCallbacks_shouldOnlyUpdateWhenValueChanges() =
+        kosmos.runTest {
+            val callback: Monitor.Callback = mock()
+            conditionMonitor.addSubscription(getDefaultBuilder(callback).build())
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(false)
+            Mockito.clearInvocations(callback)
+
+            condition1.fakeUpdateCondition(true)
+            executor.runAllReady()
+            Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean())
+
+            condition2.fakeUpdateCondition(true)
+            executor.runAllReady()
+            Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean())
+
+            condition3.fakeUpdateCondition(true)
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+
+    @Test
+    fun clearCondition_shouldUpdateValue() =
+        kosmos.runTest {
+            condition1.fakeUpdateCondition(false)
+            condition2.fakeUpdateCondition(true)
+            condition3.fakeUpdateCondition(true)
+
+            val callback: Monitor.Callback = mock()
+            conditionMonitor.addSubscription(getDefaultBuilder(callback).build())
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(false)
+
+            condition1.clearCondition()
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+
+    @Test
+    fun unsetCondition_shouldNotAffectValue() =
+        kosmos.runTest {
+            val settableCondition = FakeCondition(testScope, null, false)
+            condition1.fakeUpdateCondition(true)
+            condition2.fakeUpdateCondition(true)
+            condition3.fakeUpdateCondition(true)
+
+            val callback: Monitor.Callback = mock()
+
+            conditionMonitor.addSubscription(
+                getDefaultBuilder(callback).addCondition(settableCondition).build()
+            )
+
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+
+    @Test
+    fun setUnsetCondition_shouldAffectValue() =
+        kosmos.runTest {
+            val settableCondition = FakeCondition(testScope, null, false)
+            condition1.fakeUpdateCondition(true)
+            condition2.fakeUpdateCondition(true)
+            condition3.fakeUpdateCondition(true)
+
+            val callback: Monitor.Callback = mock()
+
+            conditionMonitor.addSubscription(
+                getDefaultBuilder(callback).addCondition(settableCondition).build()
+            )
+
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+            Mockito.clearInvocations(callback)
+
+            settableCondition.fakeUpdateCondition(false)
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(false)
+            Mockito.clearInvocations(callback)
+
+            settableCondition.clearCondition()
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+
+    @Test
+    fun clearingOverridingCondition_shouldBeExcluded() =
+        kosmos.runTest {
+            val overridingCondition = FakeCondition(testScope, true, true)
+            condition1.fakeUpdateCondition(false)
+            condition2.fakeUpdateCondition(false)
+            condition3.fakeUpdateCondition(false)
+
+            val callback: Monitor.Callback = mock()
+
+            conditionMonitor.addSubscription(
+                getDefaultBuilder(callback).addCondition(overridingCondition).build()
+            )
+
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+            Mockito.clearInvocations(callback)
+
+            overridingCondition.clearCondition()
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(false)
+        }
+
+    @Test
+    fun settingUnsetOverridingCondition_shouldBeIncluded() =
+        kosmos.runTest {
+            val overridingCondition = FakeCondition(testScope, null, true)
+            condition1.fakeUpdateCondition(false)
+            condition2.fakeUpdateCondition(false)
+            condition3.fakeUpdateCondition(false)
+
+            val callback: Monitor.Callback = mock()
+
+            conditionMonitor.addSubscription(
+                getDefaultBuilder(callback).addCondition(overridingCondition).build()
+            )
+
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(false)
+            Mockito.clearInvocations(callback)
+
+            overridingCondition.fakeUpdateCondition(true)
+            executor.runAllReady()
+            Mockito.verify(callback).onConditionsChanged(true)
+        }
+
+    /**
+     * Ensures that the result of a condition being true leads to its nested condition being
+     * activated.
+     */
+    @Test
+    fun testNestedCondition() =
+        kosmos.runTest {
+            condition1.fakeUpdateCondition(false)
+            val callback: Monitor.Callback = mock()
+
+            condition2.fakeUpdateCondition(false)
+
+            // Create a nested condition
+            conditionMonitor.addSubscription(
+                Monitor.Subscription.Builder(
+                        Monitor.Subscription.Builder(callback).addCondition(condition2).build()
+                    )
+                    .addCondition(condition1)
+                    .build()
+            )
+
+            executor.runAllReady()
+
+            // Ensure the nested condition callback is not called at all.
+            Mockito.verify(callback, Mockito.never()).onActiveChanged(anyBoolean())
+            Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean())
+
+            // Update the inner condition to true and ensure that the nested condition is not
+            // triggered.
+            condition2.fakeUpdateCondition(true)
+            Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean())
+            condition2.fakeUpdateCondition(false)
+
+            // Set outer condition and make sure the inner condition becomes active and reports that
+            // conditions aren't met
+            condition1.fakeUpdateCondition(true)
+            executor.runAllReady()
+
+            Mockito.verify(callback).onActiveChanged(eq(true))
+            Mockito.verify(callback).onConditionsChanged(eq(false))
+
+            Mockito.clearInvocations(callback)
+
+            // Update the inner condition and make sure the callback is updated.
+            condition2.fakeUpdateCondition(true)
+            executor.runAllReady()
+
+            Mockito.verify(callback).onConditionsChanged(true)
+
+            Mockito.clearInvocations(callback)
+            // Invalidate outer condition and make sure callback is informed, but the last state is
+            // not affected.
+            condition1.fakeUpdateCondition(false)
+            executor.runAllReady()
+
+            Mockito.verify(callback).onActiveChanged(eq(false))
+            Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean())
+        }
+
+    /** Ensure preconditions are applied to every subscription added to a monitor. */
+    @Test
+    fun testPreconditionMonitor() {
+        val callback: Monitor.Callback = mock()
+
+        condition2.fakeUpdateCondition(true)
+        val monitor = Monitor(executor, HashSet<Condition?>(listOf(condition1)))
+
+        monitor.addSubscription(
+            Monitor.Subscription.Builder(callback).addCondition(condition2).build()
+        )
+
+        executor.runAllReady()
+
+        Mockito.verify(callback, Mockito.never()).onActiveChanged(anyBoolean())
+        Mockito.verify(callback, Mockito.never()).onConditionsChanged(anyBoolean())
+
+        condition1.fakeUpdateCondition(true)
+        executor.runAllReady()
+
+        Mockito.verify(callback).onActiveChanged(eq(true))
+        Mockito.verify(callback).onConditionsChanged(eq(true))
+    }
+
+    @Test
+    fun testLoggingCallback() =
+        kosmos.runTest {
+            val monitor = Monitor(executor, emptySet(), logBuffer)
+
+            val condition = FakeCondition(testScope)
+            val overridingCondition =
+                FakeCondition(testScope, /* initialValue= */ false, /* overriding= */ true)
+
+            val callback: Monitor.Callback = mock()
+            monitor.addSubscription(
+                getDefaultBuilder(callback)
+                    .addCondition(condition)
+                    .addCondition(overridingCondition)
+                    .build()
+            )
+            executor.runAllReady()
+
+            // condition set to true
+            condition.fakeUpdateCondition(true)
+            executor.runAllReady()
+            Mockito.verify(logBuffer).logChange("", "FakeCondition", "True")
+
+            // condition set to false
+            condition.fakeUpdateCondition(false)
+            executor.runAllReady()
+            Mockito.verify(logBuffer).logChange("", "FakeCondition", "False")
+
+            // condition unset
+            condition.fakeClearCondition()
+            executor.runAllReady()
+            Mockito.verify(logBuffer).logChange("", "FakeCondition", "Invalid")
+
+            // overriding condition set to true
+            overridingCondition.fakeUpdateCondition(true)
+            executor.runAllReady()
+            Mockito.verify(logBuffer).logChange("", "FakeCondition[OVRD]", "True")
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java
deleted file mode 100644
index a224843..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.java
+++ /dev/null
@@ -1,163 +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.systemui.shared.condition;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public class ConditionTest extends SysuiTestCase {
-    @Mock
-    CoroutineScope mScope;
-
-    private FakeCondition mCondition;
-
-    @Before
-    public void setup() {
-        MockitoAnnotations.initMocks(this);
-        mCondition = spy(new FakeCondition(mScope));
-    }
-
-    @Test
-    public void addCallback_addFirstCallback_triggerStart() {
-        final Condition.Callback callback = mock(
-                Condition.Callback.class);
-        mCondition.addCallback(callback);
-        verify(mCondition).start();
-    }
-
-    @Test
-    public void addCallback_addMultipleCallbacks_triggerStartOnlyOnce() {
-        final Condition.Callback callback1 = mock(
-                Condition.Callback.class);
-        final Condition.Callback callback2 = mock(
-                Condition.Callback.class);
-        final Condition.Callback callback3 = mock(
-                Condition.Callback.class);
-
-        mCondition.addCallback(callback1);
-        mCondition.addCallback(callback2);
-        mCondition.addCallback(callback3);
-
-        verify(mCondition, times(1)).start();
-    }
-
-    @Test
-    public void addCallback_alreadyStarted_triggerUpdate() {
-        final Condition.Callback callback1 = mock(
-                Condition.Callback.class);
-        mCondition.addCallback(callback1);
-
-        mCondition.fakeUpdateCondition(true);
-
-        final Condition.Callback callback2 = mock(
-                Condition.Callback.class);
-        mCondition.addCallback(callback2);
-        verify(callback2).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void removeCallback_removeLastCallback_triggerStop() {
-        final Condition.Callback callback = mock(
-                Condition.Callback.class);
-        mCondition.addCallback(callback);
-        verify(mCondition, never()).stop();
-
-        mCondition.removeCallback(callback);
-        verify(mCondition).stop();
-    }
-
-    @Test
-    public void updateCondition_falseToTrue_reportTrue() {
-        mCondition.fakeUpdateCondition(false);
-
-        final Condition.Callback callback = mock(
-                Condition.Callback.class);
-        mCondition.addCallback(callback);
-
-        mCondition.fakeUpdateCondition(true);
-        verify(callback).onConditionChanged(eq(mCondition));
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void updateCondition_trueToFalse_reportFalse() {
-        mCondition.fakeUpdateCondition(true);
-
-        final Condition.Callback callback = mock(
-                Condition.Callback.class);
-        mCondition.addCallback(callback);
-
-        mCondition.fakeUpdateCondition(false);
-        verify(callback).onConditionChanged(eq(mCondition));
-        assertThat(mCondition.isConditionMet()).isFalse();
-    }
-
-    @Test
-    public void updateCondition_trueToTrue_reportNothing() {
-        mCondition.fakeUpdateCondition(true);
-
-        final Condition.Callback callback = mock(
-                Condition.Callback.class);
-        mCondition.addCallback(callback);
-
-        mCondition.fakeUpdateCondition(true);
-        verify(callback, never()).onConditionChanged(eq(mCondition));
-    }
-
-    @Test
-    public void updateCondition_falseToFalse_reportNothing() {
-        mCondition.fakeUpdateCondition(false);
-
-        final Condition.Callback callback = mock(
-                Condition.Callback.class);
-        mCondition.addCallback(callback);
-
-        mCondition.fakeUpdateCondition(false);
-        verify(callback, never()).onConditionChanged(eq(mCondition));
-    }
-
-    @Test
-    public void clearCondition_reportsNotSet() {
-        mCondition.fakeUpdateCondition(false);
-        assertThat(mCondition.isConditionSet()).isTrue();
-        mCondition.clearCondition();
-        assertThat(mCondition.isConditionSet()).isFalse();
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.kt
new file mode 100644
index 0000000..f72185b
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/ConditionTest.kt
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.shared.condition
+
+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.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito
+import org.mockito.Mockito.mock
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.mock
+
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class ConditionTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+    private lateinit var underTest: FakeCondition
+
+    @Before
+    fun setup() {
+        MockitoAnnotations.initMocks(this)
+        underTest = Mockito.spy(FakeCondition(kosmos.testScope))
+    }
+
+    @Test
+    fun addCallback_addFirstCallback_triggerStart() =
+        kosmos.runTest {
+            val callback = mock<Condition.Callback>()
+            underTest.addCallback(callback)
+            runCurrent()
+            Mockito.verify(underTest).start()
+        }
+
+    @Test
+    fun addCallback_addMultipleCallbacks_triggerStartOnlyOnce() =
+        kosmos.runTest {
+            val callback1 = mock<Condition.Callback>()
+            val callback2 = mock<Condition.Callback>()
+            val callback3 = mock<Condition.Callback>()
+
+            underTest.addCallback(callback1)
+            underTest.addCallback(callback2)
+            underTest.addCallback(callback3)
+
+            runCurrent()
+            Mockito.verify(underTest).start()
+        }
+
+    @Test
+    fun addCallback_alreadyStarted_triggerUpdate() =
+        kosmos.runTest {
+            val callback1 = mock<Condition.Callback>()
+            underTest.addCallback(callback1)
+
+            underTest.fakeUpdateCondition(true)
+
+            val callback2 = mock<Condition.Callback>()
+            underTest.addCallback(callback2)
+            Mockito.verify(callback2).onConditionChanged(underTest)
+            Truth.assertThat(underTest.isConditionMet).isTrue()
+        }
+
+    @Test
+    fun removeCallback_removeLastCallback_triggerStop() =
+        kosmos.runTest {
+            val callback = mock<Condition.Callback>()
+            underTest.addCallback(callback)
+            Mockito.verify(underTest, Mockito.never()).stop()
+
+            underTest.removeCallback(callback)
+            Mockito.verify(underTest).stop()
+        }
+
+    @Test
+    fun updateCondition_falseToTrue_reportTrue() =
+        kosmos.runTest {
+            underTest.fakeUpdateCondition(false)
+
+            val callback = mock<Condition.Callback>()
+            underTest.addCallback(callback)
+
+            underTest.fakeUpdateCondition(true)
+            Mockito.verify(callback).onConditionChanged(eq(underTest))
+            Truth.assertThat(underTest.isConditionMet).isTrue()
+        }
+
+    @Test
+    fun updateCondition_trueToFalse_reportFalse() =
+        kosmos.runTest {
+            underTest.fakeUpdateCondition(true)
+
+            val callback = mock<Condition.Callback>()
+            underTest.addCallback(callback)
+
+            underTest.fakeUpdateCondition(false)
+            Mockito.verify(callback).onConditionChanged(eq(underTest))
+            Truth.assertThat(underTest.isConditionMet).isFalse()
+        }
+
+    @Test
+    fun updateCondition_trueToTrue_reportNothing() =
+        kosmos.runTest {
+            underTest.fakeUpdateCondition(true)
+
+            val callback = mock<Condition.Callback>()
+            underTest.addCallback(callback)
+
+            underTest.fakeUpdateCondition(true)
+            Mockito.verify(callback, Mockito.never()).onConditionChanged(eq(underTest))
+        }
+
+    @Test
+    fun updateCondition_falseToFalse_reportNothing() =
+        kosmos.runTest {
+            underTest.fakeUpdateCondition(false)
+
+            val callback = mock<Condition.Callback>()
+            underTest.addCallback(callback)
+
+            underTest.fakeUpdateCondition(false)
+            Mockito.verify(callback, Mockito.never()).onConditionChanged(eq(underTest))
+        }
+
+    @Test
+    fun clearCondition_reportsNotSet() =
+        kosmos.runTest {
+            underTest.fakeUpdateCondition(false)
+            Truth.assertThat(underTest.isConditionSet).isTrue()
+            underTest.clearCondition()
+            Truth.assertThat(underTest.isConditionSet).isFalse()
+        }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java
deleted file mode 100644
index da660e2..0000000
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.java
+++ /dev/null
@@ -1,54 +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.systemui.shared.condition;
-
-import kotlinx.coroutines.CoroutineScope;
-
-/**
- * Fake implementation of {@link Condition}, and provides a way for tests to update
- * condition fulfillment.
- */
-public class FakeCondition extends Condition {
-    FakeCondition(CoroutineScope scope) {
-        super(scope);
-    }
-
-    FakeCondition(CoroutineScope scope, Boolean initialValue, boolean overriding) {
-        super(scope, initialValue, overriding);
-    }
-
-    @Override
-    public void start() {
-    }
-
-    @Override
-    public void stop() {
-    }
-
-    @Override
-    public int getStartStrategy() {
-        return START_EAGERLY;
-    }
-
-    public void fakeUpdateCondition(boolean isConditionMet) {
-        updateCondition(isConditionMet);
-    }
-
-    public void fakeClearCondition() {
-        clearCondition();
-    }
-}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.kt
new file mode 100644
index 0000000..340249c
--- /dev/null
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/shared/condition/FakeCondition.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.shared.condition
+
+import kotlinx.coroutines.CoroutineScope
+
+/**
+ * Fake implementation of [Condition], and provides a way for tests to update condition fulfillment.
+ */
+class FakeCondition : Condition {
+    constructor(scope: CoroutineScope) : super(scope)
+
+    constructor(
+        scope: CoroutineScope,
+        initialValue: Boolean?,
+        overriding: Boolean,
+    ) : super(scope, initialValue, overriding)
+
+    public override suspend fun start() {}
+
+    public override fun stop() {}
+
+    override val startStrategy: Int
+        get() = START_EAGERLY
+
+    fun fakeUpdateCondition(isConditionMet: Boolean) {
+        updateCondition(isConditionMet)
+    }
+
+    fun fakeClearCondition() {
+        clearCondition()
+    }
+}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index 01046cd..3c19179 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -227,7 +227,7 @@
         if (NotificationBundleUi.isEnabled()) {
             return row.getEntryAdapter().getSbn().getNotification();
         } else {
-            return row.getEntry().getSbn().getNotification();
+            return row.getEntryLegacy().getSbn().getNotification();
         }
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
index 03dee3a..72d21f1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/OperatorNameViewControllerTest.kt
@@ -24,13 +24,13 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.keyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.plugins.DarkIconDispatcher
 import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
 import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.util.FakeSubscriptionManagerProxy
 import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
+import com.android.systemui.testKosmos
 import com.android.systemui.tuner.TunerService
 import com.android.systemui.util.CarrierConfigTracker
 import com.android.systemui.util.kotlin.JavaAdapter
@@ -54,7 +54,7 @@
     private lateinit var underTest: OperatorNameViewController
     private lateinit var airplaneModeInteractor: AirplaneModeInteractor
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = TestScope()
 
     private val view = OperatorNameView(mContext)
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
index 485b9fe..8120c2d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModelTest.kt
@@ -17,12 +17,17 @@
 package com.android.systemui.statusbar.chips.call.ui.viewmodel
 
 import android.app.PendingIntent
+import android.content.ComponentName
+import android.content.Intent
 import android.platform.test.annotations.DisableFlags
 import android.platform.test.annotations.EnableFlags
 import android.platform.test.flag.junit.FlagsParameterization
 import android.view.View
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.activity.data.repository.activityManagerRepository
+import com.android.systemui.activity.data.repository.fake
+import com.android.systemui.animation.ActivityTransitionAnimator
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.common.shared.model.Icon
@@ -51,6 +56,7 @@
 import kotlin.test.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.any
+import org.mockito.kotlin.anyOrNull
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.verify
 import org.mockito.kotlin.whenever
@@ -481,6 +487,303 @@
             verify(kosmos.activityStarter).postStartActivityDismissingKeyguard(pendingIntent, null)
         }
 
+    @Test
+    @EnableFlags(StatusBarChipsReturnAnimations.FLAG_NAME)
+    @EnableChipsModernization
+    fun chipWithReturnAnimation_updatesCorrectly_withStateAndTransitionState() =
+        kosmos.runTest {
+            val pendingIntent = mock<PendingIntent>()
+            val intent = mock<Intent>()
+            whenever(pendingIntent.intent).thenReturn(intent)
+            val component = mock<ComponentName>()
+            whenever(intent.component).thenReturn(component)
+
+            val expandable = mock<Expandable>()
+            val activityController = mock<ActivityTransitionAnimator.Controller>()
+            whenever(
+                    expandable.activityTransitionController(
+                        anyOrNull(),
+                        anyOrNull(),
+                        any(),
+                        anyOrNull(),
+                        any(),
+                    )
+                )
+                .thenReturn(activityController)
+
+            val latest by collectLastValue(underTest.chip)
+
+            // Start off with no call.
+            removeOngoingCallState(key = NOTIFICATION_KEY)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java)
+            assertThat(latest!!.transitionManager!!.controllerFactory).isNull()
+
+            // Call starts [NoCall -> InCall(isAppVisible=true), NoTransition].
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = 345,
+                contentIntent = pendingIntent,
+                uid = NOTIFICATION_UID,
+                isAppVisible = true,
+            )
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isTrue()
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
+            val factory = latest!!.transitionManager!!.controllerFactory
+            assertThat(factory!!.component).isEqualTo(component)
+
+            // Request a return transition [InCall(isAppVisible=true), NoTransition ->
+            // ReturnRequested].
+            factory.onCompose(expandable)
+            var controller = factory.createController(forLaunch = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isTrue()
+
+            // Start the return transition [InCall(isAppVisible=true), ReturnRequested ->
+            // Returning].
+            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
+
+            // End the return transition [InCall(isAppVisible=true), Returning -> NoTransition].
+            controller.onTransitionAnimationEnd(isExpandingFullyAbove = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
+
+            // Settle the return transition [InCall(isAppVisible=true) ->
+            // InCall(isAppVisible=false), NoTransition].
+            kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
+
+            // Trigger a launch transition [InCall(isAppVisible=false) -> InCall(isAppVisible=true),
+            // NoTransition].
+            kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, true)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
+
+            // Request the return transition [InCall(isAppVisible=true), NoTransition ->
+            // LaunchRequested].
+            controller = factory.createController(forLaunch = true)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
+
+            // Start the return transition [InCall(isAppVisible=true), LaunchRequested ->
+            // Launching].
+            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
+
+            // End the return transition [InCall(isAppVisible=true), Launching -> NoTransition].
+            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+            assertThat(latest!!.transitionManager!!.controllerFactory).isEqualTo(factory)
+            assertThat(latest!!.transitionManager!!.hideChipForTransition).isFalse()
+
+            // End the call with the app visible [InCall(isAppVisible=true) -> NoCall,
+            // NoTransition].
+            removeOngoingCallState(key = NOTIFICATION_KEY)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java)
+            assertThat(latest!!.transitionManager!!.controllerFactory).isNull()
+
+            // End the call with the app hidden [InCall(isAppVisible=false) -> NoCall,
+            // NoTransition].
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = 345,
+                contentIntent = pendingIntent,
+                isAppVisible = false,
+            )
+            removeOngoingCallState(key = NOTIFICATION_KEY)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java)
+            assertThat(latest!!.transitionManager!!.controllerFactory).isNull()
+        }
+
+    @Test
+    @DisableFlags(StatusBarChipsReturnAnimations.FLAG_NAME)
+    fun chipLegacy_hasNoTransitionAnimationInformation() =
+        kosmos.runTest {
+            val latest by collectLastValue(underTest.chip)
+
+            // NoCall
+            removeOngoingCallState(key = NOTIFICATION_KEY)
+            assertThat(latest!!.transitionManager).isNull()
+
+            // InCall with visible app
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = 345,
+                uid = NOTIFICATION_UID,
+                isAppVisible = true,
+            )
+            assertThat(latest!!.transitionManager).isNull()
+
+            // InCall with hidden app
+            kosmos.activityManagerRepository.fake.setIsAppVisible(NOTIFICATION_UID, false)
+            assertThat(latest!!.transitionManager).isNull()
+        }
+
+    @Test
+    @EnableFlags(StatusBarChipsReturnAnimations.FLAG_NAME)
+    @EnableChipsModernization
+    fun chipWithReturnAnimation_chipDataChangesMidTransition() =
+        kosmos.runTest {
+            val pendingIntent = mock<PendingIntent>()
+            val intent = mock<Intent>()
+            whenever(pendingIntent.intent).thenReturn(intent)
+            val component = mock<ComponentName>()
+            whenever(intent.component).thenReturn(component)
+
+            val expandable = mock<Expandable>()
+            val activityController = mock<ActivityTransitionAnimator.Controller>()
+            whenever(
+                    expandable.activityTransitionController(
+                        anyOrNull(),
+                        anyOrNull(),
+                        any(),
+                        anyOrNull(),
+                        any(),
+                    )
+                )
+                .thenReturn(activityController)
+
+            val latest by collectLastValue(underTest.chip)
+
+            // Start with the app visible and trigger a return animation.
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = 345,
+                contentIntent = pendingIntent,
+                uid = NOTIFICATION_UID,
+                isAppVisible = true,
+            )
+            var factory = latest!!.transitionManager!!.controllerFactory!!
+            factory.onCompose(expandable)
+            var controller = factory.createController(forLaunch = false)
+            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+
+            // The chip changes state.
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = 0,
+                contentIntent = pendingIntent,
+                uid = NOTIFICATION_UID,
+                isAppVisible = true,
+            )
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+
+            // Reset the state and trigger a launch animation.
+            controller.onTransitionAnimationEnd(isExpandingFullyAbove = false)
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = 345,
+                contentIntent = pendingIntent,
+                uid = NOTIFICATION_UID,
+                isAppVisible = true,
+            )
+            factory = latest!!.transitionManager!!.controllerFactory!!
+            factory.onCompose(expandable)
+            controller = factory.createController(forLaunch = true)
+            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+
+            // The chip changes state.
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = -2,
+                contentIntent = pendingIntent,
+                uid = NOTIFICATION_UID,
+                isAppVisible = true,
+            )
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.IconOnly::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+        }
+
+    @Test
+    @EnableFlags(StatusBarChipsReturnAnimations.FLAG_NAME)
+    @EnableChipsModernization
+    fun chipWithReturnAnimation_chipDisappearsMidTransition() =
+        kosmos.runTest {
+            val pendingIntent = mock<PendingIntent>()
+            val intent = mock<Intent>()
+            whenever(pendingIntent.intent).thenReturn(intent)
+            val component = mock<ComponentName>()
+            whenever(intent.component).thenReturn(component)
+
+            val expandable = mock<Expandable>()
+            val activityController = mock<ActivityTransitionAnimator.Controller>()
+            whenever(
+                    expandable.activityTransitionController(
+                        anyOrNull(),
+                        anyOrNull(),
+                        any(),
+                        anyOrNull(),
+                        any(),
+                    )
+                )
+                .thenReturn(activityController)
+
+            val latest by collectLastValue(underTest.chip)
+
+            // Start with the app visible and trigger a return animation.
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = 345,
+                contentIntent = pendingIntent,
+                uid = NOTIFICATION_UID,
+                isAppVisible = true,
+            )
+            var factory = latest!!.transitionManager!!.controllerFactory!!
+            factory.onCompose(expandable)
+            var controller = factory.createController(forLaunch = false)
+            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+
+            // The chip disappears.
+            removeOngoingCallState(key = NOTIFICATION_KEY)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java)
+
+            // Reset the state and trigger a launch animation.
+            controller.onTransitionAnimationEnd(isExpandingFullyAbove = false)
+            addOngoingCallState(
+                key = NOTIFICATION_KEY,
+                startTimeMs = 345,
+                contentIntent = pendingIntent,
+                uid = NOTIFICATION_UID,
+                isAppVisible = true,
+            )
+            factory = latest!!.transitionManager!!.controllerFactory!!
+            factory.onCompose(expandable)
+            controller = factory.createController(forLaunch = true)
+            controller.onTransitionAnimationStart(isExpandingFullyAbove = false)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Active.Timer::class.java)
+            assertThat((latest as OngoingActivityChipModel.Active).isHidden).isFalse()
+
+            // The chip disappears.
+            removeOngoingCallState(key = NOTIFICATION_KEY)
+            assertThat(latest).isInstanceOf(OngoingActivityChipModel.Inactive::class.java)
+        }
+
     companion object {
         fun createStatusBarIconViewOrNull(): StatusBarIconView? =
             if (StatusBarConnectedDisplays.isEnabled) {
@@ -500,6 +803,8 @@
                 }
                 .build()
 
+        private const val NOTIFICATION_KEY = "testKey"
+        private const val NOTIFICATION_UID = 12345
         private const val PROMOTED_BACKGROUND_COLOR = 65
         private const val PROMOTED_PRIMARY_TEXT_COLOR = 98
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
index b2174c1..21a4560 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/domian/interactor/MediaRouterChipInteractorTest.kt
@@ -20,12 +20,12 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
 import com.android.systemui.statusbar.chips.casttootherdevice.domain.interactor.mediaRouterChipInteractor
 import com.android.systemui.statusbar.chips.casttootherdevice.domain.model.MediaRouterCastModel
 import com.android.systemui.statusbar.policy.CastDevice
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlinx.coroutines.test.runCurrent
@@ -35,7 +35,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MediaRouterChipInteractorTest : SysuiTestCase() {
-    val kosmos = Kosmos()
+    val kosmos = testKosmos()
     val testScope = kosmos.testScope
     val mediaRouterRepository = kosmos.fakeMediaRouterRepository
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
index 274efbb..5681297 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndCastScreenToOtherDeviceDialogDelegateTest.kt
@@ -30,7 +30,6 @@
 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.kosmos.testCase
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
@@ -41,6 +40,7 @@
 import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
 import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlinx.coroutines.test.runCurrent
@@ -57,7 +57,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class EndCastScreenToOtherDeviceDialogDelegateTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
     private val sysuiDialog = mock<SystemUIDialog>()
     private lateinit var underTest: EndCastScreenToOtherDeviceDialogDelegate
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
index 88207d1..30a415c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/view/EndGenericCastToOtherDeviceDialogDelegateTest.kt
@@ -26,7 +26,6 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.mediarouter.data.repository.fakeMediaRouterRepository
@@ -35,6 +34,7 @@
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.policy.CastDevice
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlinx.coroutines.test.runCurrent
@@ -51,7 +51,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class EndGenericCastToOtherDeviceDialogDelegateTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
     private val sysuiDialog = mock<SystemUIDialog>()
     private lateinit var underTest: EndGenericCastToOtherDeviceDialogDelegate
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
index ccc844a..d921ab3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/casttootherdevice/ui/viewmodel/CastToOtherDeviceChipViewModelTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
@@ -52,6 +51,7 @@
 import com.android.systemui.statusbar.phone.ongoingcall.DisableChipsModernization
 import com.android.systemui.statusbar.phone.ongoingcall.EnableChipsModernization
 import com.android.systemui.statusbar.policy.CastDevice
+import com.android.systemui.testKosmos
 import com.android.systemui.util.time.fakeSystemClock
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
@@ -69,7 +69,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class CastToOtherDeviceChipViewModelTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
     private val testScope = kosmos.testScope
     private val mediaProjectionRepo = kosmos.fakeMediaProjectionRepository
     private val mediaRouterRepo = kosmos.fakeMediaRouterRepository
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
index 795988f..fac50b3 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/mediaprojection/ui/view/EndMediaProjectionDialogHelperTest.kt
@@ -24,12 +24,12 @@
 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.kosmos.testCase
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.phone.mockSystemUIDialogFactory
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import org.junit.runner.RunWith
@@ -42,7 +42,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class EndMediaProjectionDialogHelperTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
 
     private val underTest = kosmos.endMediaProjectionDialogHelper
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
index f560ee7..981c952 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/screenrecord/ui/view/EndScreenRecordingDialogDelegateTest.kt
@@ -30,7 +30,6 @@
 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.kosmos.testCase
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.mediaprojection.taskswitcher.FakeActivityTaskManager.Companion.createTask
@@ -39,6 +38,7 @@
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
 import com.android.systemui.statusbar.chips.screenrecord.domain.interactor.screenRecordChipInteractor
 import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlinx.coroutines.test.runCurrent
@@ -55,7 +55,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class EndScreenRecordingDialogDelegateTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
 
     private val sysuiDialog = mock<SystemUIDialog>()
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt
index 95aa6cd..b2e90ec 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/sharetoapp/ui/view/EndShareScreenToAppDialogDelegateTest.kt
@@ -30,7 +30,6 @@
 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.kosmos.testCase
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
@@ -41,6 +40,7 @@
 import com.android.systemui.statusbar.chips.mediaprojection.domain.model.ProjectionChipModel
 import com.android.systemui.statusbar.chips.mediaprojection.ui.view.endMediaProjectionDialogHelper
 import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlinx.coroutines.test.runCurrent
@@ -57,7 +57,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class EndShareScreenToAppDialogDelegateTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
     private val sysuiDialog = mock<SystemUIDialog>()
     private lateinit var underTest: EndShareScreenToAppDialogDelegate
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
index e3a84fd..6d91fb5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/chips/ui/viewmodel/ChipTransitionHelperTest.kt
@@ -22,12 +22,12 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlin.test.Test
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -39,7 +39,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class ChipTransitionHelperTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = kosmos.testScope
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
index 2f6bedb..ea61b71 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/data/repository/StatusBarModeRepositoryImplTest.kt
@@ -29,7 +29,6 @@
 import com.android.internal.view.AppearanceRegion
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.statusbar.CommandQueue
 import com.android.systemui.statusbar.data.model.StatusBarMode
 import com.android.systemui.statusbar.layout.BoundsPair
@@ -42,6 +41,7 @@
 import com.android.systemui.statusbar.phone.ongoingcall.data.repository.ongoingCallRepository
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.argumentCaptor
 import com.android.systemui.util.mockito.capture
@@ -59,7 +59,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class StatusBarModeRepositoryImplTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope = TestScope()
     private val commandQueue = mock<CommandQueue>()
     private val letterboxAppearanceCalculator = mock<LetterboxAppearanceCalculator>()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt
index a13b864..1018748 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapterTest.kt
@@ -24,6 +24,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
 import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
 import com.google.common.truth.Truth.assertThat
 import org.junit.Before
@@ -126,7 +127,7 @@
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun isBubble() {
-        assertThat(underTest.isBubbleCapable).isFalse()
+        assertThat(underTest.isBubble).isFalse()
     }
 
     @Test
@@ -152,4 +153,10 @@
     fun canShowFullScreen() {
         assertThat(underTest.isFullScreenCapable()).isFalse()
     }
+
+    @Test
+    @EnableFlags(NotificationBundleUi.FLAG_NAME)
+    fun getPeopleNotificationType() {
+        assertThat(underTest.getPeopleNotificationType()).isEqualTo(TYPE_NON_PERSON)
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt
index faafa07..7449064 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapterTest.kt
@@ -30,6 +30,7 @@
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.RankingBuilder
 import com.android.systemui.statusbar.notification.mockNotificationActivityStarter
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import com.android.systemui.statusbar.notification.row.entryAdapterFactory
 import com.android.systemui.statusbar.notification.row.mockNotificationActionClickManager
@@ -41,6 +42,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mockito
+import org.mockito.Mockito.mock
 import org.mockito.Mockito.verify
 
 @SmallTest
@@ -108,7 +110,7 @@
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun getRow_adapter() {
-        val row = Mockito.mock(ExpandableNotificationRow::class.java)
+        val row = mock(ExpandableNotificationRow::class.java)
         val notification: Notification =
             Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
 
@@ -126,7 +128,7 @@
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun isGroupRoot_adapter_groupSummary() {
-        val row = Mockito.mock(ExpandableNotificationRow::class.java)
+        val row = mock(ExpandableNotificationRow::class.java)
         val notification: Notification =
             Notification.Builder(mContext, "")
                 .setSmallIcon(R.drawable.ic_person)
@@ -173,7 +175,7 @@
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun isClearable_adapter() {
-        val row = Mockito.mock(ExpandableNotificationRow::class.java)
+        val row = mock(ExpandableNotificationRow::class.java)
         val notification: Notification =
             Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
 
@@ -191,7 +193,7 @@
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun getSummarization_adapter() {
-        val row = Mockito.mock(ExpandableNotificationRow::class.java)
+        val row = mock(ExpandableNotificationRow::class.java)
         val notification: Notification =
             Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
 
@@ -211,7 +213,7 @@
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun getIcons_adapter() {
-        val row = Mockito.mock(ExpandableNotificationRow::class.java)
+        val row = mock(ExpandableNotificationRow::class.java)
         val notification: Notification =
             Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
 
@@ -256,7 +258,7 @@
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun canDragAndDrop() {
-        val pi = Mockito.mock(PendingIntent::class.java)
+        val pi = mock(PendingIntent::class.java)
         Mockito.`when`(pi.isActivity).thenReturn(true)
         val notification: Notification =
             Notification.Builder(mContext, "")
@@ -282,7 +284,7 @@
         val entry = NotificationEntryBuilder().setNotification(notification).build()
 
         underTest = factory.create(entry) as NotificationEntryAdapter
-        assertThat(underTest.isBubbleCapable).isEqualTo(entry.isBubble)
+        assertThat(underTest.isBubble).isEqualTo(entry.isBubble)
     }
 
     @Test
@@ -334,11 +336,21 @@
 
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
+    fun getPeopleNotificationType() {
+        val entry = kosmos.msgStyleBubbleableFullPerson
+
+        underTest = factory.create(entry) as NotificationEntryAdapter
+
+        assertThat(underTest.peopleNotificationType).isEqualTo(TYPE_FULL_PERSON)
+    }
+
+    @Test
+    @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun canShowFullScreen() {
         val notification: Notification =
             Notification.Builder(mContext, "")
                 .setSmallIcon(R.drawable.ic_person)
-                .setFullScreenIntent(Mockito.mock(PendingIntent::class.java), true)
+                .setFullScreenIntent(mock(PendingIntent::class.java), true)
                 .build()
 
         val entry =
@@ -353,6 +365,22 @@
 
     @Test
     @EnableFlags(NotificationBundleUi.FLAG_NAME)
+    fun onDragSuccess() {
+        val notification: Notification =
+            Notification.Builder(mContext, "")
+                .setSmallIcon(R.drawable.ic_person)
+                .addAction(mock(Notification.Action::class.java))
+                .build()
+        val entry = NotificationEntryBuilder().setNotification(notification).build()
+
+        underTest = factory.create(entry) as NotificationEntryAdapter
+
+        underTest.onDragSuccess()
+        verify(kosmos.mockNotificationActivityStarter).onDragSuccess(entry)
+    }
+
+    @Test
+    @EnableFlags(NotificationBundleUi.FLAG_NAME)
     fun onNotificationBubbleIconClicked() {
         val notification: Notification =
             Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
@@ -371,7 +399,7 @@
         val notification: Notification =
             Notification.Builder(mContext, "")
                 .setSmallIcon(R.drawable.ic_person)
-                .addAction(Mockito.mock(Notification.Action::class.java))
+                .addAction(mock(Notification.Action::class.java))
                 .build()
 
         val entry = NotificationEntryBuilder().setNotification(notification).build()
@@ -380,4 +408,36 @@
         underTest.onNotificationActionClicked()
         verify(kosmos.mockNotificationActionClickManager).onNotificationActionClicked(entry)
     }
+
+    @Test
+    @EnableFlags(NotificationBundleUi.FLAG_NAME)
+    fun getDismissState() {
+        val notification: Notification =
+            Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+
+        val entry = NotificationEntryBuilder().setNotification(notification).build()
+        entry.dismissState = NotificationEntry.DismissState.PARENT_DISMISSED
+
+        underTest = factory.create(entry) as NotificationEntryAdapter
+
+        assertThat(underTest.dismissState).isEqualTo(entry.dismissState)
+    }
+
+    @Test
+    @EnableFlags(NotificationBundleUi.FLAG_NAME)
+    fun onEntryClicked() {
+        val notification: Notification =
+            Notification.Builder(mContext, "")
+                .setSmallIcon(R.drawable.ic_person)
+                .addAction(mock(Notification.Action::class.java))
+                .build()
+        val entry = NotificationEntryBuilder().setNotification(notification).build()
+        val row = mock(ExpandableNotificationRow::class.java)
+
+        underTest = factory.create(entry) as NotificationEntryAdapter
+
+
+        underTest.onEntryClicked(row)
+        verify(kosmos.mockNotificationActivityStarter).onNotificationClicked(entry, row)
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
index 790b2c3..bfd700d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/NotificationEntryTest.java
@@ -58,6 +58,7 @@
 import com.android.systemui.statusbar.RankingBuilder;
 import com.android.systemui.statusbar.SbnBuilder;
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
+import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime;
 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
 import com.android.systemui.util.time.FakeSystemClock;
 
@@ -151,7 +152,8 @@
                 .build();
 
         NotificationEntry entry =
-                new NotificationEntry(sbn, ranking, mClock.uptimeMillis());
+                new NotificationEntry(sbn, ranking,
+                        UseElapsedRealtimeForCreationTime.getCurrentTime(mClock));
 
         assertFalse(entry.isBlockable());
     }
@@ -251,7 +253,8 @@
                 .build();
 
         NotificationEntry entry =
-                new NotificationEntry(sbn, ranking, mClock.uptimeMillis());
+                new NotificationEntry(sbn, ranking,
+                        UseElapsedRealtimeForCreationTime.getCurrentTime(mClock));
 
         assertEquals(systemGeneratedSmartActions, entry.getSmartActions());
         assertEquals(NOTIFICATION_CHANNEL, entry.getChannel());
@@ -365,7 +368,8 @@
                 .setKey(sbn.getKey())
                 .build();
         NotificationEntry entry =
-                new NotificationEntry(sbn, ranking, mClock.uptimeMillis());
+                new NotificationEntry(sbn, ranking,
+                        UseElapsedRealtimeForCreationTime.getCurrentTime(mClock));
 
         assertFalse(entry.isChannelVisibilityPrivate());
     }
@@ -378,7 +382,8 @@
                 .setKey(sbn.getKey())
                 .build();
         NotificationEntry entry =
-                new NotificationEntry(sbn, ranking, mClock.uptimeMillis());
+                new NotificationEntry(sbn, ranking,
+                        UseElapsedRealtimeForCreationTime.getCurrentTime(mClock));
 
         assertFalse(entry.isChannelVisibilityPrivate());
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
index 7fa157f..ba2d40b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/ColorizedFgsCoordinatorTest.kt
@@ -27,7 +27,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.collectLastValue
 import com.android.systemui.kosmos.runTest
@@ -35,10 +34,10 @@
 import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.core.StatusBarRootModernization
-import com.android.systemui.statusbar.notification.buildNotificationEntry
-import com.android.systemui.statusbar.notification.buildOngoingCallEntry
-import com.android.systemui.statusbar.notification.buildPromotedOngoingEntry
 import com.android.systemui.statusbar.notification.collection.buildEntry
+import com.android.systemui.statusbar.notification.collection.buildNotificationEntry
+import com.android.systemui.statusbar.notification.collection.buildOngoingCallEntry
+import com.android.systemui.statusbar.notification.collection.buildPromotedOngoingEntry
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifPromoter
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
 import com.android.systemui.statusbar.notification.collection.notifPipeline
@@ -49,7 +48,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.withArgCaptor
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.runTest
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.kt
index ef0a416..d532010 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/collection/coordinator/VisualStabilityCoordinatorTest.kt
@@ -50,6 +50,7 @@
 import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
+import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.Pluggable.PluggableListener
 import com.android.systemui.statusbar.notification.collection.notifPipeline
@@ -323,7 +324,10 @@
             setPulsing(true)
 
             // WHEN we temporarily allow section changes for this notification entry
-            underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.currentTimeMillis())
+            underTest.temporarilyAllowSectionChanges(
+                entry,
+                UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock),
+            )
 
             // THEN group changes aren't allowed
             assertThat(notifStabilityManager.isGroupChangeAllowed(entry)).isFalse()
@@ -349,7 +353,10 @@
             setPulsing(false)
 
             // WHEN we temporarily allow section changes for this notification entry
-            underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.uptimeMillis())
+            underTest.temporarilyAllowSectionChanges(
+                entry,
+                UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock),
+            )
 
             // THEN the notification list is invalidated
             verifyStabilityManagerWasInvalidated(times(1))
@@ -365,7 +372,10 @@
             setPulsing(false)
 
             // WHEN we temporarily allow section changes for this notification entry
-            underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.currentTimeMillis())
+            underTest.temporarilyAllowSectionChanges(
+                entry,
+                UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock),
+            )
 
             // THEN invalidate is not called because this entry was never suppressed from reordering
             verifyStabilityManagerWasInvalidated(never())
@@ -382,7 +392,10 @@
             assertThat(notifStabilityManager.isSectionChangeAllowed(entry)).isTrue()
 
             // WHEN we temporarily allow section changes for this notification entry
-            underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.currentTimeMillis())
+            underTest.temporarilyAllowSectionChanges(
+                entry,
+                UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock),
+            )
 
             // THEN invalidate is not called because this entry was never suppressed from
             // reordering;
@@ -415,7 +428,10 @@
             setPulsing(true)
 
             // WHEN we temporarily allow section changes for this notification entry
-            underTest.temporarilyAllowSectionChanges(entry, fakeSystemClock.currentTimeMillis())
+            underTest.temporarilyAllowSectionChanges(
+                entry,
+                UseElapsedRealtimeForCreationTime.getCurrentTime(fakeSystemClock),
+            )
             // can now reorder, so invalidates
             verifyStabilityManagerWasInvalidated(times(1))
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
index 893c179..0ac944a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractorImplTest.kt
@@ -190,11 +190,22 @@
 
     @Test
     @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractTime_basicTimeZero() {
+        assertExtractedTime(
+            hasTime = true,
+            hasChronometer = false,
+            provided = ProvidedTime.Value(0L),
+            expected = ExpectedTime.Time,
+        )
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
     fun extractTime_basicTimeNow() {
         assertExtractedTime(
             hasTime = true,
             hasChronometer = false,
-            whenOffset = Duration.ZERO,
+            provided = ProvidedTime.Offset(Duration.ZERO),
             expected = ExpectedTime.Time,
         )
     }
@@ -205,7 +216,7 @@
         assertExtractedTime(
             hasTime = true,
             hasChronometer = false,
-            whenOffset = (-5).minutes,
+            provided = ProvidedTime.Offset((-5).minutes),
             expected = ExpectedTime.Time,
         )
     }
@@ -216,19 +227,31 @@
         assertExtractedTime(
             hasTime = true,
             hasChronometer = false,
-            whenOffset = 5.minutes,
+            provided = ProvidedTime.Offset(5.minutes),
             expected = ExpectedTime.Time,
         )
     }
 
     @Test
     @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractTime_countUpZero() {
+        assertExtractedTime(
+            hasTime = false,
+            hasChronometer = true,
+            isCountDown = false,
+            provided = ProvidedTime.Value(0L),
+            expected = ExpectedTime.CountUp,
+        )
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
     fun extractTime_countUpNow() {
         assertExtractedTime(
             hasTime = false,
             hasChronometer = true,
             isCountDown = false,
-            whenOffset = Duration.ZERO,
+            provided = ProvidedTime.Offset(Duration.ZERO),
             expected = ExpectedTime.CountUp,
         )
     }
@@ -240,7 +263,7 @@
             hasTime = false,
             hasChronometer = true,
             isCountDown = false,
-            whenOffset = (-5).minutes,
+            provided = ProvidedTime.Offset((-5).minutes),
             expected = ExpectedTime.CountUp,
         )
     }
@@ -252,19 +275,31 @@
             hasTime = false,
             hasChronometer = true,
             isCountDown = false,
-            whenOffset = 5.minutes,
+            provided = ProvidedTime.Offset(5.minutes),
             expected = ExpectedTime.CountUp,
         )
     }
 
     @Test
     @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
+    fun extractTime_countDownZero() {
+        assertExtractedTime(
+            hasTime = false,
+            hasChronometer = true,
+            isCountDown = true,
+            provided = ProvidedTime.Value(0L),
+            expected = ExpectedTime.CountDown,
+        )
+    }
+
+    @Test
+    @EnableFlags(PromotedNotificationUi.FLAG_NAME, StatusBarNotifChips.FLAG_NAME)
     fun extractTime_countDownNow() {
         assertExtractedTime(
             hasTime = false,
             hasChronometer = true,
             isCountDown = true,
-            whenOffset = Duration.ZERO,
+            provided = ProvidedTime.Offset(Duration.ZERO),
             expected = ExpectedTime.CountDown,
         )
     }
@@ -276,7 +311,7 @@
             hasTime = false,
             hasChronometer = true,
             isCountDown = true,
-            whenOffset = (-5).minutes,
+            provided = ProvidedTime.Offset((-5).minutes),
             expected = ExpectedTime.CountDown,
         )
     }
@@ -288,7 +323,7 @@
             hasTime = false,
             hasChronometer = true,
             isCountDown = true,
-            whenOffset = 5.minutes,
+            provided = ProvidedTime.Offset(5.minutes),
             expected = ExpectedTime.CountDown,
         )
     }
@@ -299,6 +334,12 @@
         assertExtractedTime(hasTime = true, hasChronometer = true, expected = ExpectedTime.CountUp)
     }
 
+    private sealed class ProvidedTime {
+        data class Value(val value: Long) : ProvidedTime()
+
+        data class Offset(val offset: Duration = Duration.ZERO) : ProvidedTime()
+    }
+
     private enum class ExpectedTime {
         Null,
         Time,
@@ -310,7 +351,7 @@
         hasTime: Boolean = false,
         hasChronometer: Boolean = false,
         isCountDown: Boolean = false,
-        whenOffset: Duration = Duration.ZERO,
+        provided: ProvidedTime = ProvidedTime.Offset(),
         expected: ExpectedTime,
     ) {
         // Set the two timebases to different (arbitrary) numbers, so we can verify whether the
@@ -318,14 +359,24 @@
         systemClock.setCurrentTimeMillis(1_739_570_992_579L)
         systemClock.setElapsedRealtime(1_380_967_080L)
 
-        val whenCurrentTime = systemClock.currentTimeMillis() + whenOffset.inWholeMilliseconds
-        val whenElapsedRealtime = systemClock.elapsedRealtime() + whenOffset.inWholeMilliseconds
+        val providedCurrentTime =
+            when (provided) {
+                is ProvidedTime.Value -> provided.value
+                is ProvidedTime.Offset ->
+                    systemClock.currentTimeMillis() + provided.offset.inWholeMilliseconds
+            }
+
+        val expectedCurrentTime =
+            when (providedCurrentTime) {
+                0L -> systemClock.currentTimeMillis()
+                else -> providedCurrentTime
+            }
 
         val entry = createEntry {
             setShowWhen(hasTime)
             setUsesChronometer(hasChronometer)
             setChronometerCountDown(isCountDown)
-            setWhen(whenCurrentTime)
+            setWhen(providedCurrentTime)
         }
 
         val content = extractContent(entry)
@@ -338,14 +389,18 @@
             ExpectedTime.Time -> {
                 val actual = content?.time as? When.Time
                 assertThat(actual).isNotNull()
-                assertThat(actual?.currentTimeMillis).isEqualTo(whenCurrentTime)
+                assertThat(actual?.currentTimeMillis).isEqualTo(expectedCurrentTime)
             }
 
             ExpectedTime.CountDown,
             ExpectedTime.CountUp -> {
+                val expectedElapsedRealtime =
+                    expectedCurrentTime + systemClock.elapsedRealtime() -
+                        systemClock.currentTimeMillis()
+
                 val actual = content?.time as? When.Chronometer
                 assertThat(actual).isNotNull()
-                assertThat(actual?.elapsedRealtimeMillis).isEqualTo(whenElapsedRealtime)
+                assertThat(actual?.elapsedRealtimeMillis).isEqualTo(expectedElapsedRealtime)
                 assertThat(actual?.isCountDown).isEqualTo(expected == ExpectedTime.CountDown)
             }
         }
@@ -455,6 +510,7 @@
 
         assertThat(content).isNotNull()
         assertThat(content?.style).isEqualTo(Style.Call)
+        assertThat(content?.title).isEqualTo(TEST_PERSON_NAME)
     }
 
     @Test
@@ -544,6 +600,11 @@
         if (promoted) {
             notif.flags = FLAG_PROMOTED_ONGOING
         }
+        // Notification uses System.currentTimeMillis() to initialize creationTime; overwrite that
+        // with the value from our mock clock.
+        if (notif.creationTime != 0L) {
+            notif.creationTime = systemClock.currentTimeMillis()
+        }
         return NotificationEntryBuilder().setNotification(notif).build()
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
index 6926677..6192399 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/promoted/domain/interactor/PromotedNotificationsInteractorTest.kt
@@ -28,9 +28,9 @@
 import com.android.systemui.statusbar.chips.notification.domain.interactor.statusBarNotificationChipsInteractor
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.core.StatusBarRootModernization
-import com.android.systemui.statusbar.notification.buildNotificationEntry
-import com.android.systemui.statusbar.notification.buildOngoingCallEntry
-import com.android.systemui.statusbar.notification.buildPromotedOngoingEntry
+import com.android.systemui.statusbar.notification.collection.buildNotificationEntry
+import com.android.systemui.statusbar.notification.collection.buildOngoingCallEntry
+import com.android.systemui.statusbar.notification.collection.buildPromotedOngoingEntry
 import com.android.systemui.statusbar.notification.domain.interactor.renderNotificationListInteractor
 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
 import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
index bb12eff..0d45335 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowControllerTest.kt
@@ -51,6 +51,7 @@
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRowController.BUBBLES_SETTING_URI
 import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer
@@ -58,11 +59,13 @@
 import com.android.systemui.statusbar.phone.KeyguardBypassController
 import com.android.systemui.statusbar.policy.SmartReplyConstants
 import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.eq
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.withArgCaptor
 import com.android.systemui.util.time.SystemClock
+import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor
 import com.google.android.msdl.domain.MSDLPlayer
 import junit.framework.Assert
 import org.junit.After
@@ -84,6 +87,8 @@
     private val appName = "MyApp"
     private val notifKey = "MyNotifKey"
 
+    private val kosmos = testKosmos()
+
     private val view: ExpandableNotificationRow = mock()
     private val activableNotificationViewController: ActivatableNotificationViewController = mock()
     private val rivSubComponentFactory: RemoteInputViewSubcomponent.Factory = mock()
@@ -160,6 +165,7 @@
                 msdlPlayer,
                 rebindingTracker,
                 entryAdapterFactory,
+                kosmos.windowRootViewBlurInteractor,
             )
         whenever(view.childrenContainer).thenReturn(childrenContainer)
 
@@ -313,7 +319,7 @@
         val notification = Notification.Builder(mContext).build()
         val sbn =
             SbnBuilder().setNotification(notification).setUser(UserHandle.of(USER_ALL)).build()
-        whenever(view.entry)
+        whenever(view.entryLegacy)
             .thenReturn(
                 NotificationEntryBuilder().setSbn(sbn).setUser(UserHandle.of(USER_ALL)).build()
             )
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
index 4a954b3..387c62d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.kt
@@ -512,6 +512,7 @@
             .setImportance(NotificationManager.IMPORTANCE_HIGH)
             .build()
 
+        whenever(row.canViewBeDismissed()).thenReturn(true)
         whenever(highPriorityProvider.isHighPriority(entry)).thenReturn(true)
         val statusBarNotification = entry.sbn
         gutsManager.initializeNotificationInfo(row, notificationInfoView)
@@ -534,6 +535,7 @@
                 any<UiEventLogger>(),
                 /* isDeviceProvisioned = */ eq(false),
                 /* isNonblockable = */ eq(false),
+                /* isDismissable = */ eq(true),
                 /* wasShownHighPriority = */ eq(true),
                 eq(assistantFeedbackController),
                 eq(metricsLogger),
@@ -549,6 +551,7 @@
         NotificationEntryHelper.modifyRanking(row.entry)
             .setUserSentiment(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE)
             .build()
+        whenever(row.canViewBeDismissed()).thenReturn(true)
         val statusBarNotification = row.entry.sbn
         val entry = row.entry
 
@@ -574,6 +577,7 @@
                 any<UiEventLogger>(),
                 /* isDeviceProvisioned = */ eq(true),
                 /* isNonblockable = */ eq(false),
+                /* isDismissable = */ eq(true),
                 /* wasShownHighPriority = */ eq(false),
                 eq(assistantFeedbackController),
                 eq(metricsLogger),
@@ -589,6 +593,7 @@
         NotificationEntryHelper.modifyRanking(row.entry)
             .setUserSentiment(NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE)
             .build()
+        whenever(row.canViewBeDismissed()).thenReturn(true)
         val statusBarNotification = row.entry.sbn
         val entry = row.entry
 
@@ -612,6 +617,7 @@
                 any<UiEventLogger>(),
                 /* isDeviceProvisioned = */ eq(false),
                 /* isNonblockable = */ eq(false),
+                /* isDismissable = */ eq(true),
                 /* wasShownHighPriority = */ eq(false),
                 eq(assistantFeedbackController),
                 eq(metricsLogger),
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
index 5f817de..0ac5fe9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationInfoTest.kt
@@ -49,6 +49,7 @@
 import android.view.View.VISIBLE
 import android.widget.ImageView
 import android.widget.TextView
+import androidx.core.view.isVisible
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.logging.MetricsLogger
@@ -57,7 +58,6 @@
 import com.android.internal.logging.uiEventLoggerFake
 import com.android.systemui.Dependency
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.RankingBuilder
@@ -69,6 +69,7 @@
 import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider
 import com.android.systemui.statusbar.notification.row.icon.appIconProvider
 import com.android.systemui.statusbar.notification.row.icon.notificationIconStyleProvider
+import com.android.systemui.testKosmos
 import com.android.telecom.telecomManager
 import com.google.common.truth.Truth.assertThat
 import java.util.concurrent.CountDownLatch
@@ -90,7 +91,7 @@
 @RunWith(AndroidJUnit4::class)
 @RunWithLooper
 class NotificationInfoTest : SysuiTestCase() {
-    private val kosmos = Kosmos().also { it.testCase = this }
+    private val kosmos = testKosmos().also { it.testCase = this }
 
     private lateinit var underTest: NotificationInfo
     private lateinit var notificationChannel: NotificationChannel
@@ -865,6 +866,31 @@
         assertThat(underTest.findViewById<View>(R.id.feedback).visibility).isEqualTo(GONE)
     }
 
+    @Test
+    @Throws(RemoteException::class)
+    fun testDismissListenerBound() {
+        val latch = CountDownLatch(1)
+        bindNotification(onCloseClick = { _: View? -> latch.countDown() })
+
+        val dismissView = underTest.findViewById<View>(R.id.inline_dismiss)
+        assertThat(dismissView.isVisible).isTrue()
+        dismissView.performClick()
+
+        // Verify that listener was triggered.
+        assertThat(latch.count).isEqualTo(0)
+    }
+
+    @Test
+    @Throws(RemoteException::class)
+    fun testDismissHiddenWhenUndismissable() {
+
+        entry.sbn.notification.flags =
+            entry.sbn.notification.flags or android.app.Notification.FLAG_NO_DISMISS
+        bindNotification(isDismissable = false)
+        val dismissView = underTest.findViewById<View>(R.id.inline_dismiss)
+        assertThat(dismissView.isVisible).isFalse()
+    }
+
     private fun bindNotification(
         pm: PackageManager = this.mockPackageManager,
         iNotificationManager: INotificationManager = this.mockINotificationManager,
@@ -883,6 +909,7 @@
         uiEventLogger: UiEventLogger = this.uiEventLogger,
         isDeviceProvisioned: Boolean = true,
         isNonblockable: Boolean = false,
+        isDismissable: Boolean = true,
         wasShownHighPriority: Boolean = true,
         assistantFeedbackController: AssistantFeedbackController = this.assistantFeedbackController,
         metricsLogger: MetricsLogger = kosmos.metricsLogger,
@@ -905,6 +932,7 @@
             uiEventLogger,
             isDeviceProvisioned,
             isNonblockable,
+            isDismissable,
             wasShownHighPriority,
             assistantFeedbackController,
             metricsLogger,
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
index af52c31..9536656 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationMenuRowTest.java
@@ -40,7 +40,9 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.systemui.Flags;
+import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
@@ -56,6 +58,7 @@
 @SmallTest
 public class NotificationMenuRowTest extends LeakCheckedTest {
 
+    private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
     private ExpandableNotificationRow mRow;
     private View mView;
     private PeopleNotificationIdentifier mPeopleNotificationIdentifier;
@@ -68,6 +71,8 @@
         mPeopleNotificationIdentifier = mock(PeopleNotificationIdentifier.class);
         NotificationEntry entry = new NotificationEntryBuilder().build();
         when(mRow.getEntry()).thenReturn(entry);
+        EntryAdapter entryAdapter = mKosmos.getEntryAdapterFactory().create(entry);
+        when(mRow.getEntryAdapter()).thenReturn(entryAdapter);
     }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
index af67a04..2d4063b 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/NotificationSnoozeTest.java
@@ -27,7 +27,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 
-import android.platform.test.annotations.EnableFlags;
 import android.provider.Settings;
 import android.testing.TestableResources;
 import android.view.View;
@@ -39,7 +38,6 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 import androidx.test.filters.SmallTest;
 
-import com.android.systemui.Flags;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.animation.AnimatorTestRule;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
@@ -93,7 +91,6 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_NOTIFICATION_UNDO_GUTS_ON_CONFIG_CHANGED)
     public void closeControls_withoutSave_performsUndo() {
         ArrayList<SnoozeOption> options = mUnderTest.getDefaultSnoozeOptions();
         mUnderTest.mSelectedOption = options.getFirst();
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
index 3887297..209dfb2d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfoTest.java
@@ -152,6 +152,7 @@
                 true,
                 false,
                 true,
+                true,
                 mAssistantFeedbackController,
                 mMetricsLogger,
                 null);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
index 3d1fdee..961616c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelTest.kt
@@ -22,8 +22,6 @@
 import com.android.systemui.accessibility.data.repository.FakeAccessibilityRepository
 import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.testKosmos
-import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -34,16 +32,12 @@
 @SmallTest
 class ActivatableNotificationViewModelTest : SysuiTestCase() {
 
-    private val kosmos = testKosmos()
-
     // fakes
     private val a11yRepo = FakeAccessibilityRepository()
 
     // real impls
     private val a11yInteractor = AccessibilityInteractor(a11yRepo)
-    private val windowRootViewBlurInteractor = kosmos.windowRootViewBlurInteractor
-    private val underTest = ActivatableNotificationViewModel(a11yInteractor,
-        windowRootViewBlurInteractor)
+    private val underTest = ActivatableNotificationViewModel(a11yInteractor)
 
     @Test
     fun isTouchable_whenA11yTouchExplorationDisabled() = runTest {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
index 048028c..db0c59f 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/domain/interactor/NotificationShelfInteractorTest.kt
@@ -23,12 +23,12 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testCase
 import com.android.systemui.plugins.statusbar.statusBarStateController
 import com.android.systemui.power.data.repository.fakePowerRepository
 import com.android.systemui.statusbar.lockscreenShadeTransitionController
 import com.android.systemui.statusbar.phone.screenOffAnimationController
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
@@ -44,7 +44,7 @@
 class NotificationShelfInteractorTest : SysuiTestCase() {
 
     private val kosmos =
-        Kosmos().apply {
+        testKosmos().apply {
             testCase = this@NotificationShelfInteractorTest
             lockscreenShadeTransitionController = mock()
             screenOffAnimationController = mock()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
index 6381b4e..7265262 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelTest.kt
@@ -24,7 +24,6 @@
 import com.android.systemui.flags.EnableSceneContainer
 import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFaceAuthRepository
 import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.collectLastValue
 import com.android.systemui.kosmos.runTest
 import com.android.systemui.kosmos.testCase
@@ -35,6 +34,7 @@
 import com.android.systemui.shade.domain.interactor.enableSplitShade
 import com.android.systemui.statusbar.lockscreenShadeTransitionController
 import com.android.systemui.statusbar.phone.screenOffAnimationController
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Test
@@ -50,7 +50,7 @@
 class NotificationShelfViewModelTest : SysuiTestCase() {
 
     private val kosmos =
-        Kosmos().apply {
+        testKosmos().apply {
             testCase = this@NotificationShelfViewModelTest
             lockscreenShadeTransitionController = mock()
             screenOffAnimationController = mock()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
index 13da04e..378ffb5 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/AmbientStateTest.kt
@@ -16,16 +16,22 @@
 
 package com.android.systemui.statusbar.notification.stack
 
+import android.app.Notification
+import android.platform.test.annotations.DisableFlags
+import android.platform.test.annotations.EnableFlags
 import android.platform.test.flag.junit.FlagsParameterization
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.flags.DisableSceneContainer
 import com.android.systemui.flags.andSceneContainer
+import com.android.systemui.res.R
 import com.android.systemui.shade.transition.LargeScreenShadeInterpolator
 import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
 import com.android.systemui.statusbar.notification.data.repository.HeadsUpRepository
 import com.android.systemui.statusbar.notification.headsup.AvalancheController
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -33,6 +39,7 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyString
 import platform.test.runner.parameterized.ParameterizedAndroidJunit4
 import platform.test.runner.parameterized.Parameters
 
@@ -389,6 +396,36 @@
         assertThat(sut.isClosing).isFalse()
     }
     // endregion
+
+    // region isPulsing
+    @Test
+    @EnableFlags(NotificationBundleUi.FLAG_NAME)
+    fun isPulsing_key() {
+        whenever(headsupRepository.isHeadsUpEntry(anyString())).thenReturn(true);
+        sut.isPulsing = true
+        assertThat(sut.isPulsing("key")).isTrue()
+
+        whenever(headsupRepository.isHeadsUpEntry(anyString())).thenReturn(false);
+        sut.isPulsing = true
+        assertThat(sut.isPulsing("key")).isFalse()
+    }
+
+    @Test
+    @DisableFlags(NotificationBundleUi.FLAG_NAME)
+    fun isPulsing_entry() {
+        val notification: Notification =
+            Notification.Builder(mContext, "").setSmallIcon(R.drawable.ic_person).build()
+        val entry = NotificationEntryBuilder().setNotification(notification).build()
+
+        sut.isPulsing = true
+        entry.setIsHeadsUpEntry(true)
+        assertThat(sut.isPulsing(entry)).isTrue()
+
+        sut.isPulsing = true
+        entry.setIsHeadsUpEntry(false)
+        assertThat(sut.isPulsing(entry)).isFalse()
+    }
+    // endregion
 }
 
 // region Arrange helper methods.
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
index 6c6ba93..936b971 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt
@@ -248,6 +248,19 @@
         }
 
     @Test
+    fun onMagneticInteractionEnd_whileTargetsSet_goesToIdle() =
+        kosmos.testScope.runTest {
+            // GIVEN that targets are set
+            setTargets()
+
+            // WHEN the interaction ends on the row
+            underTest.onMagneticInteractionEnd(swipedRow, velocity = null)
+
+            // THEN the state resets
+            assertThat(underTest.currentState).isEqualTo(State.IDLE)
+        }
+
+    @Test
     fun onMagneticInteractionEnd_whileDetached_goesToIdle() =
         kosmos.testScope.runTest {
             // GIVEN the swiped row is detached
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 41cca19..6ec1f91 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -129,7 +129,7 @@
         whenever(notificationShelf.viewState).thenReturn(ExpandableViewState())
         whenever(notificationRow.key).thenReturn("key")
         whenever(notificationRow.viewState).thenReturn(ExpandableViewState())
-        whenever(notificationRow.entry).thenReturn(notificationEntry)
+        whenever(notificationRow.entryLegacy).thenReturn(notificationEntry)
         whenever(notificationRow.entryAdapter).thenReturn(notificationEntryAdapter)
         whenever(notificationRow.roundableState)
             .thenReturn(RoundableState(notificationRow, notificationRow, 0f))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
index 46430af..1f37291 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewControllerTest.kt
@@ -790,6 +790,7 @@
     }
 
     @Test
+    @DisableFlags(Flags.FLAG_GLANCEABLE_HUB_V2)
     fun animateToGlanceableHub_affectsAlpha() =
         testScope.runTest {
             try {
@@ -809,6 +810,7 @@
         }
 
     @Test
+    @DisableFlags(Flags.FLAG_GLANCEABLE_HUB_V2)
     fun animateToGlanceableHub_alphaResetOnCommunalNotShowing() =
         testScope.runTest {
             try {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
index c5abd02..19e9838 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/NotificationGroupTestHelper.java
@@ -106,6 +106,7 @@
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
         entry.setRow(row);
         when(row.getEntry()).thenReturn(entry);
+        when(row.getEntryLegacy()).thenReturn(entry);
         return entry;
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
index c23e0e7..1cc2911 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallbackTest.java
@@ -221,6 +221,7 @@
 
         when(enr.getPrivateLayout()).thenReturn(privateLayout);
         when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.getEntryLegacy()).thenReturn(enrEntry);
         when(enr.getEntryAdapter()).thenReturn(enrEntryAdapter);
         when(enr.isChildInGroup()).thenReturn(true);
         when(enr.areChildrenExpanded()).thenReturn(false);
@@ -251,6 +252,7 @@
 
         when(enr.getPrivateLayout()).thenReturn(privateLayout);
         when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.getEntryLegacy()).thenReturn(enrEntry);
         when(enr.isChildInGroup()).thenReturn(true);
         when(enr.areChildrenExpanded()).thenReturn(true);
 
@@ -277,6 +279,7 @@
 
         when(enr.getPrivateLayout()).thenReturn(privateLayout);
         when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.getEntryLegacy()).thenReturn(enrEntry);
         when(enr.isChildInGroup()).thenReturn(false);
         when(enr.isPinned()).thenReturn(false);
         when(enr.isExpanded()).thenReturn(false);
@@ -305,6 +308,7 @@
 
         when(enr.getPrivateLayout()).thenReturn(privateLayout);
         when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.getEntryLegacy()).thenReturn(enrEntry);
         when(enr.isChildInGroup()).thenReturn(false);
         when(enr.isPinned()).thenReturn(false);
         when(enr.isExpanded()).thenReturn(true);
@@ -333,6 +337,7 @@
 
         when(enr.getPrivateLayout()).thenReturn(privateLayout);
         when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.getEntryLegacy()).thenReturn(enrEntry);
         when(enr.isChildInGroup()).thenReturn(false);
         when(enr.isPinned()).thenReturn(true);
         when(enr.isPinnedAndExpanded()).thenReturn(false);
@@ -361,6 +366,7 @@
 
         when(enr.getPrivateLayout()).thenReturn(privateLayout);
         when(enr.getEntry()).thenReturn(enrEntry);
+        when(enr.getEntryLegacy()).thenReturn(enrEntry);
         when(enr.isChildInGroup()).thenReturn(false);
         when(enr.isPinned()).thenReturn(true);
         when(enr.isPinnedAndExpanded()).thenReturn(true);
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
index eb95ddb..c58b4bc 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
@@ -30,7 +30,6 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.concurrency.fakeExecutor
 import com.android.systemui.dump.DumpManager
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.logcatLogBuffer
 import com.android.systemui.res.R
@@ -48,6 +47,7 @@
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import com.android.systemui.statusbar.window.StatusBarWindowController
 import com.android.systemui.statusbar.window.StatusBarWindowControllerStore
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runCurrent
 import kotlinx.coroutines.test.runTest
@@ -70,7 +70,7 @@
 @TestableLooper.RunWithLooper
 @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
 class OngoingCallControllerTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
 
     private val mainExecutor = kosmos.fakeExecutor
     private val testScope = kosmos.testScope
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
index a446313..7de56dd 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/data/repository/OngoingCallRepositoryTest.kt
@@ -19,12 +19,11 @@
 import android.platform.test.annotations.DisableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
-import com.android.systemui.Flags.FLAG_STATUS_BAR_CHIPS_MODERNIZATION
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.statusbar.phone.ongoingcall.StatusBarChipsModernization
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallModel
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.inCallModel
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -33,7 +32,7 @@
 @RunWith(AndroidJUnit4::class)
 @DisableFlags(StatusBarChipsModernization.FLAG_NAME)
 class OngoingCallRepositoryTest : SysuiTestCase() {
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val underTest = kosmos.ongoingCallRepository
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
index f4204af7..84f1d5c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/phone/ongoingcall/domain/interactor/OngoingCallInteractorTest.kt
@@ -23,7 +23,6 @@
 import com.android.systemui.activity.data.repository.activityManagerRepository
 import com.android.systemui.activity.data.repository.fake
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.collectLastValue
 import com.android.systemui.kosmos.runTest
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
@@ -36,6 +35,7 @@
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.addOngoingCallState
 import com.android.systemui.statusbar.phone.ongoingcall.shared.model.OngoingCallTestHelper.removeOngoingCallState
 import com.android.systemui.statusbar.window.fakeStatusBarWindowControllerStore
+import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.test.runTest
 import org.junit.Before
@@ -51,7 +51,7 @@
 @RunWith(AndroidJUnit4::class)
 @EnableChipsModernization
 class OngoingCallInteractorTest : SysuiTestCase() {
-    private val kosmos = Kosmos().useUnconfinedTestDispatcher()
+    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val underTest = kosmos.ongoingCallInteractor
 
     @Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt
index 57e63a5..9042ac4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileIconViewModelKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,110 +19,69 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.log.table.logcatTableLogBuffer
 import com.android.systemui.statusbar.connectivity.MobileIconCarrierIdOverridesFake
-import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.airplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorImpl
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorImpl
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairosImpl
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.mobileIconsInteractorKairos
 import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
-import com.android.systemui.statusbar.policy.data.repository.FakeUserSetupRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.fake
 import com.android.systemui.testKosmos
-import com.android.systemui.util.CarrierConfigTracker
-import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.mock
 
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class LocationBasedMobileIconViewModelKairosTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
 
-    private lateinit var commonImpl: MobileIconViewModelCommonKairos
-    private lateinit var homeIcon: HomeMobileIconViewModelKairos
-    private lateinit var qsIcon: QsMobileIconViewModelKairos
-    private lateinit var keyguardIcon: KeyguardMobileIconViewModelKairos
-    private lateinit var iconsInteractor: MobileIconsInteractor
-    private lateinit var interactor: MobileIconInteractor
-    private val connectionsRepository = kosmos.fakeMobileConnectionsRepository
-    private lateinit var repository: FakeMobileConnectionRepository
-    private lateinit var airplaneModeInteractor: AirplaneModeInteractor
+    private val Kosmos.commonImpl: MobileIconViewModelKairosCommon by ActivatedKairosFixture {
+        MobileIconViewModelKairos(
+            SUB_1_ID,
+            interactor,
+            airplaneModeInteractor,
+            constants,
+            featureFlagsClassic,
+        )
+    }
 
-    private val connectivityRepository = FakeConnectivityRepository()
-    private val flags =
-        FakeFeatureFlagsClassic().also {
-            it.set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true)
-        }
+    private val Kosmos.homeIcon: HomeMobileIconViewModelKairos by
+        Kosmos.Fixture { HomeMobileIconViewModelKairos(commonImpl, mock()) }
 
-    @Mock private lateinit var constants: ConnectivityConstants
-    private val tableLogBuffer =
-        logcatTableLogBuffer(kosmos, "LocationBasedMobileIconViewModelTest")
-    @Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
+    private val Kosmos.qsIcon: QsMobileIconViewModelKairos by
+        Kosmos.Fixture { QsMobileIconViewModelKairos(commonImpl) }
 
-    private val testDispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
+    private val Kosmos.keyguardIcon: KeyguardMobileIconViewModelKairos by
+        Kosmos.Fixture { KeyguardMobileIconViewModelKairos(commonImpl) }
 
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        airplaneModeInteractor =
-            AirplaneModeInteractor(
-                FakeAirplaneModeRepository(),
-                FakeConnectivityRepository(),
-                connectionsRepository,
-            )
-        repository =
-            FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer).apply {
-                isInService.value = true
-                cdmaLevel.value = 1
-                primaryLevel.value = 1
-                isEmergencyOnly.value = false
-                numberOfLevels.value = 4
-                resolvedNetworkType.value = ResolvedNetworkType.DefaultNetworkType(lookupKey = "3G")
-                dataConnectionState.value = DataConnectionState.Connected
-            }
+    private val Kosmos.iconsInteractor: MobileIconsInteractorKairos
+        get() = mobileIconsInteractorKairos
 
-        connectionsRepository.activeMobileDataRepository.value = repository
-
-        connectivityRepository.apply { setMobileConnected() }
-
-        iconsInteractor =
-            MobileIconsInteractorImpl(
-                connectionsRepository,
-                carrierConfigTracker,
-                tableLogBuffer,
-                connectivityRepository,
-                FakeUserSetupRepository(),
-                testScope.backgroundScope,
-                context,
-                flags,
-            )
-
-        interactor =
-            MobileIconInteractorImpl(
-                testScope.backgroundScope,
+    private val Kosmos.interactor: MobileIconInteractorKairos by
+        Kosmos.Fixture {
+            MobileIconInteractorKairosImpl(
                 iconsInteractor.activeDataConnectionHasDataEnabled,
                 iconsInteractor.alwaysShowDataRatIcon,
                 iconsInteractor.alwaysUseCdmaLevel,
@@ -136,50 +95,74 @@
                 context,
                 MobileIconCarrierIdOverridesFake(),
             )
+        }
 
-        commonImpl =
-            MobileIconViewModelKairos(
-                SUB_1_ID,
-                interactor,
-                airplaneModeInteractor,
-                constants,
-                testScope.backgroundScope,
-            )
+    private val Kosmos.repository: FakeMobileConnectionRepositoryKairos by
+        Kosmos.Fixture {
+            FakeMobileConnectionRepositoryKairos(SUB_1_ID, kairos, tableLogBuffer).apply {
+                isInService.setValue(true)
+                cdmaLevel.setValue(1)
+                primaryLevel.setValue(1)
+                isEmergencyOnly.setValue(false)
+                numberOfLevels.setValue(4)
+                resolvedNetworkType.setValue(
+                    ResolvedNetworkType.DefaultNetworkType(lookupKey = "3G")
+                )
+                dataConnectionState.setValue(DataConnectionState.Connected)
+            }
+        }
 
-        homeIcon = HomeMobileIconViewModelKairos(commonImpl, mock())
-        qsIcon = QsMobileIconViewModelKairos(commonImpl)
-        keyguardIcon = KeyguardMobileIconViewModelKairos(commonImpl)
-    }
+    private val Kosmos.constants: ConnectivityConstants by Kosmos.Fixture { mock() }
+    private val Kosmos.tableLogBuffer by
+        Kosmos.Fixture { logcatTableLogBuffer(this, "LocationBasedMobileIconViewModelTest") }
+
+    private val kosmos =
+        testKosmos().apply {
+            useUnconfinedTestDispatcher()
+            mobileConnectionsRepositoryKairos =
+                fakeMobileConnectionsRepositoryKairos.apply {
+                    setActiveMobileDataSubscriptionId(SUB_1_ID)
+                    subscriptions.setValue(
+                        listOf(
+                            SubscriptionModel(
+                                SUB_1_ID,
+                                carrierName = "carrierName",
+                                profileClass = 0,
+                            )
+                        )
+                    )
+                }
+            connectivityRepository.fake.apply { setMobileConnected() }
+            featureFlagsClassic.fake.apply {
+                set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true)
+            }
+        }
+
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
 
     @Test
-    fun locationBasedViewModelsReceiveSameIconIdWhenCommonImplUpdates() =
-        testScope.runTest {
-            var latestHome: SignalIconModel? = null
-            val homeJob = homeIcon.icon.onEach { latestHome = it }.launchIn(this)
+    fun locationBasedViewModelsReceiveSameIconIdWhenCommonImplUpdates() = runTest {
+        repository.dataEnabled.setValue(true)
+        repository.isInService.setValue(true)
 
-            var latestQs: SignalIconModel? = null
-            val qsJob = qsIcon.icon.onEach { latestQs = it }.launchIn(this)
+        val latestHome by homeIcon.icon.collectLastValue()
+        val latestQs by qsIcon.icon.collectLastValue()
+        val latestKeyguard by keyguardIcon.icon.collectLastValue()
 
-            var latestKeyguard: SignalIconModel? = null
-            val keyguardJob = keyguardIcon.icon.onEach { latestKeyguard = it }.launchIn(this)
+        var expected = defaultSignal(level = 1)
 
-            var expected = defaultSignal(level = 1)
+        assertThat(latestHome).isEqualTo(expected)
+        assertThat(latestQs).isEqualTo(expected)
+        assertThat(latestKeyguard).isEqualTo(expected)
 
-            assertThat(latestHome).isEqualTo(expected)
-            assertThat(latestQs).isEqualTo(expected)
-            assertThat(latestKeyguard).isEqualTo(expected)
+        repository.setAllLevels(2)
+        expected = defaultSignal(level = 2)
 
-            repository.setAllLevels(2)
-            expected = defaultSignal(level = 2)
-
-            assertThat(latestHome).isEqualTo(expected)
-            assertThat(latestQs).isEqualTo(expected)
-            assertThat(latestKeyguard).isEqualTo(expected)
-
-            homeJob.cancel()
-            qsJob.cancel()
-            keyguardJob.cancel()
-        }
+        assertThat(latestHome).isEqualTo(expected)
+        assertThat(latestQs).isEqualTo(expected)
+        assertThat(latestKeyguard).isEqualTo(expected)
+    }
 
     companion object {
         private const val SUB_1_ID = 1
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt
index 6b114a8..68499d1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -28,1039 +28,893 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.flags.FakeFeatureFlagsClassic
 import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.kairos
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
 import com.android.systemui.log.table.logcatTableLogBuffer
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.connectivity.MobileIconCarrierIdOverridesFake
 import com.android.systemui.statusbar.core.NewStatusBarIcons
 import com.android.systemui.statusbar.core.StatusBarRootModernization
-import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.airplaneModeRepository
+import com.android.systemui.statusbar.pipeline.airplane.data.repository.fake
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.airplaneModeInteractor
 import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
 import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepository.Companion.DEFAULT_NETWORK_NAME
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorImpl
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorImpl
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairosImpl
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.mobileIconsInteractorKairos
 import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
 import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
 import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlot
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
-import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
-import com.android.systemui.statusbar.policy.data.repository.FakeUserSetupRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.connectivityRepository
+import com.android.systemui.statusbar.pipeline.shared.data.repository.fake
 import com.android.systemui.testKosmos
-import com.android.systemui.util.CarrierConfigTracker
-import com.android.systemui.util.mockito.whenever
 import com.google.common.truth.Truth.assertThat
 import com.google.common.truth.Truth.assertWithMessage
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.filterIsInstance
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
 import kotlinx.coroutines.yield
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.doReturn
+import org.mockito.kotlin.mock
+import org.mockito.kotlin.stub
 
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileIconViewModelKairosTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
 
-    private var connectivityRepository = FakeConnectivityRepository()
-
-    private lateinit var underTest: MobileIconViewModelKairos
-    private lateinit var interactor: MobileIconInteractorImpl
-    private lateinit var iconsInteractor: MobileIconsInteractorImpl
-    private lateinit var repository: FakeMobileConnectionRepository
-    private lateinit var connectionsRepository: FakeMobileConnectionsRepository
-    private lateinit var airplaneModeRepository: FakeAirplaneModeRepository
-    private lateinit var airplaneModeInteractor: AirplaneModeInteractor
-    @Mock private lateinit var constants: ConnectivityConstants
-    private val tableLogBuffer = logcatTableLogBuffer(kosmos, "MobileIconViewModelTest")
-    @Mock private lateinit var carrierConfigTracker: CarrierConfigTracker
-
-    private val flags =
-        FakeFeatureFlagsClassic().also {
-            it.set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true)
+    private val Kosmos.underTest: MobileIconViewModelKairos by ActivatedKairosFixture {
+        MobileIconViewModelKairos(
+            SUB_1_ID,
+            interactor,
+            airplaneModeInteractor,
+            constants,
+            featureFlagsClassic,
+        )
+    }
+    private val Kosmos.interactor: MobileIconInteractorKairos by ActivatedKairosFixture {
+        MobileIconInteractorKairosImpl(
+            mobileIconsInteractorKairos.activeDataConnectionHasDataEnabled,
+            mobileIconsInteractorKairos.alwaysShowDataRatIcon,
+            mobileIconsInteractorKairos.alwaysUseCdmaLevel,
+            mobileIconsInteractorKairos.isSingleCarrier,
+            mobileIconsInteractorKairos.mobileIsDefault,
+            mobileIconsInteractorKairos.defaultMobileIconMapping,
+            mobileIconsInteractorKairos.defaultMobileIconGroup,
+            mobileIconsInteractorKairos.isDefaultConnectionFailed,
+            mobileIconsInteractorKairos.isForceHidden,
+            repository,
+            context,
+            MobileIconCarrierIdOverridesFake(),
+        )
+    }
+    private val Kosmos.repository: FakeMobileConnectionRepositoryKairos by
+        Kosmos.Fixture {
+            FakeMobileConnectionRepositoryKairos(SUB_1_ID, kairos, tableLogBuffer)
+                .also {
+                    mobileConnectionsRepositoryKairos.fake.setActiveMobileDataSubscriptionId(
+                        SUB_1_ID
+                    )
+                    mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(
+                        listOf(
+                            SubscriptionModel(
+                                SUB_1_ID,
+                                carrierName = "carrierName",
+                                profileClass = 0,
+                            )
+                        )
+                    )
+                }
+                .apply {
+                    isInService.setValue(true)
+                    dataConnectionState.setValue(DataConnectionState.Connected)
+                    dataEnabled.setValue(true)
+                    setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+                }
         }
-    private val testDispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
+    private val Kosmos.constants: ConnectivityConstants by
+        Kosmos.Fixture { mock { on { hasDataCapabilities } doReturn true } }
+    private val Kosmos.tableLogBuffer by
+        Kosmos.Fixture { logcatTableLogBuffer(this, "MobileIconViewModelKairosTest") }
 
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-        whenever(constants.hasDataCapabilities).thenReturn(true)
-
-        connectionsRepository =
-            FakeMobileConnectionsRepository(FakeMobileMappingsProxy(), tableLogBuffer)
-
-        repository =
-            FakeMobileConnectionRepository(SUB_1_ID, tableLogBuffer).apply {
-                setNetworkTypeKey(connectionsRepository.GSM_KEY)
-                isInService.value = true
-                dataConnectionState.value = DataConnectionState.Connected
-                dataEnabled.value = true
+    private val kosmos =
+        testKosmos().apply {
+            useUnconfinedTestDispatcher()
+            mobileConnectionsRepositoryKairos =
+                fakeMobileConnectionsRepositoryKairos.apply { mobileIsDefault.setValue(true) }
+            featureFlagsClassic.fake.apply {
+                set(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS, true)
             }
-        connectionsRepository.activeMobileDataRepository.value = repository
-        connectionsRepository.mobileIsDefault.value = true
+        }
 
-        airplaneModeRepository = FakeAirplaneModeRepository()
-        airplaneModeInteractor =
-            AirplaneModeInteractor(
-                airplaneModeRepository,
-                connectivityRepository,
-                kosmos.fakeMobileConnectionsRepository,
-            )
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
 
-        iconsInteractor =
-            MobileIconsInteractorImpl(
-                connectionsRepository,
-                carrierConfigTracker,
-                tableLogBuffer,
-                connectivityRepository,
-                FakeUserSetupRepository(),
-                testScope.backgroundScope,
-                context,
-                flags,
-            )
+    @Test
+    fun isVisible_notDataCapable_alwaysFalse() = runTest {
+        // Create a new view model here so the constants are properly read
+        constants.stub { on { hasDataCapabilities } doReturn false }
 
-        interactor =
-            MobileIconInteractorImpl(
-                testScope.backgroundScope,
-                iconsInteractor.activeDataConnectionHasDataEnabled,
-                iconsInteractor.alwaysShowDataRatIcon,
-                iconsInteractor.alwaysUseCdmaLevel,
-                iconsInteractor.isSingleCarrier,
-                iconsInteractor.mobileIsDefault,
-                iconsInteractor.defaultMobileIconMapping,
-                iconsInteractor.defaultMobileIconGroup,
-                iconsInteractor.isDefaultConnectionFailed,
-                iconsInteractor.isForceHidden,
-                repository,
-                context,
-                MobileIconCarrierIdOverridesFake(),
-            )
-        createAndSetViewModel()
+        val latest by underTest.isVisible.collectLastValue()
+
+        assertThat(latest).isFalse()
     }
 
     @Test
-    fun isVisible_notDataCapable_alwaysFalse() =
-        testScope.runTest {
-            // Create a new view model here so the constants are properly read
-            whenever(constants.hasDataCapabilities).thenReturn(false)
-            createAndSetViewModel()
+    fun isVisible_notAirplane_notForceHidden_true() = runTest {
+        val latest by underTest.isVisible.collectLastValue()
 
-            var latest: Boolean? = null
-            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+        airplaneModeRepository.fake.setIsAirplaneMode(false)
 
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
+        assertThat(latest).isTrue()
+    }
 
     @Test
-    fun isVisible_notAirplane_notForceHidden_true() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+    fun isVisible_airplaneAndNotAllowed_false() = runTest {
+        val latest by underTest.isVisible.collectLastValue()
 
-            airplaneModeRepository.setIsAirplaneMode(false)
+        airplaneModeRepository.fake.setIsAirplaneMode(true)
+        repository.isAllowedDuringAirplaneMode.setValue(false)
+        connectivityRepository.fake.setForceHiddenIcons(setOf())
 
-            assertThat(latest).isTrue()
-
-            job.cancel()
-        }
-
-    @Test
-    fun isVisible_airplaneAndNotAllowed_false() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
-
-            airplaneModeRepository.setIsAirplaneMode(true)
-            repository.isAllowedDuringAirplaneMode.value = false
-            connectivityRepository.setForceHiddenIcons(setOf())
-
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(false)
+    }
 
     /** Regression test for b/291993542. */
     @Test
-    fun isVisible_airplaneButAllowed_true() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+    fun isVisible_airplaneButAllowed_true() = runTest {
+        val latest by underTest.isVisible.collectLastValue()
 
-            airplaneModeRepository.setIsAirplaneMode(true)
-            repository.isAllowedDuringAirplaneMode.value = true
-            connectivityRepository.setForceHiddenIcons(setOf())
+        airplaneModeRepository.fake.setIsAirplaneMode(true)
+        repository.isAllowedDuringAirplaneMode.setValue(true)
+        connectivityRepository.fake.setForceHiddenIcons(setOf())
 
-            assertThat(latest).isTrue()
-
-            job.cancel()
-        }
+        assertThat(latest).isTrue()
+    }
 
     @Test
-    fun isVisible_forceHidden_false() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+    fun isVisible_forceHidden_false() = runTest {
+        val latest by underTest.isVisible.collectLastValue()
 
-            airplaneModeRepository.setIsAirplaneMode(false)
-            connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
+        airplaneModeRepository.fake.setIsAirplaneMode(false)
+        connectivityRepository.fake.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
 
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun isVisible_respondsToUpdates() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job = underTest.isVisible.onEach { latest = it }.launchIn(this)
+    fun isVisible_respondsToUpdates() = runTest {
+        val latest by underTest.isVisible.collectLastValue()
 
-            airplaneModeRepository.setIsAirplaneMode(false)
-            connectivityRepository.setForceHiddenIcons(setOf())
+        airplaneModeRepository.fake.setIsAirplaneMode(false)
+        connectivityRepository.fake.setForceHiddenIcons(setOf())
 
-            assertThat(latest).isTrue()
+        assertThat(latest).isEqualTo(true)
 
-            airplaneModeRepository.setIsAirplaneMode(true)
-            assertThat(latest).isFalse()
+        airplaneModeRepository.fake.setIsAirplaneMode(true)
+        assertThat(latest).isEqualTo(false)
 
-            repository.isAllowedDuringAirplaneMode.value = true
-            assertThat(latest).isTrue()
+        repository.isAllowedDuringAirplaneMode.setValue(true)
+        assertThat(latest).isEqualTo(true)
 
-            connectivityRepository.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
+        connectivityRepository.fake.setForceHiddenIcons(setOf(ConnectivitySlot.MOBILE))
+        assertThat(latest).isEqualTo(false)
+    }
 
     @Test
-    fun isVisible_satellite_respectsAirplaneMode() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.isVisible)
+    fun isVisible_satellite_respectsAirplaneMode() = runTest {
+        val latest by underTest.isVisible.collectLastValue()
 
-            repository.isNonTerrestrial.value = true
-            airplaneModeInteractor.setIsAirplaneMode(false)
+        repository.isNonTerrestrial.setValue(true)
+        airplaneModeInteractor.setIsAirplaneMode(false)
 
-            assertThat(latest).isTrue()
+        assertThat(latest).isTrue()
 
-            airplaneModeInteractor.setIsAirplaneMode(true)
+        airplaneModeInteractor.setIsAirplaneMode(true)
 
-            assertThat(latest).isFalse()
-        }
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun contentDescription_notInService_usesNoPhone() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
+    fun contentDescription_notInService_usesNoPhone() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
 
-            repository.isInService.value = false
+        repository.isInService.setValue(false)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
-        }
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+    }
 
     @Test
-    fun contentDescription_includesNetworkName() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
+    fun contentDescription_includesNetworkName() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
 
-            repository.isInService.value = true
-            repository.networkName.value = NetworkNameModel.SubscriptionDerived("Test Network Name")
-            repository.numberOfLevels.value = 5
-            repository.setAllLevels(3)
+        repository.isInService.setValue(true)
+        repository.networkName.setValue(NetworkNameModel.SubscriptionDerived("Test Network Name"))
+        repository.numberOfLevels.setValue(5)
+        repository.setAllLevels(3)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular("Test Network Name", THREE_BARS))
-        }
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular("Test Network Name", THREE_BARS))
+    }
 
     @Test
-    fun contentDescription_inService_usesLevel() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
+    fun contentDescription_inService_usesLevel() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
 
-            repository.setAllLevels(2)
+        repository.setAllLevels(2)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
 
-            repository.setAllLevels(0)
+        repository.setAllLevels(0)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
-        }
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+    }
 
     @Test
-    fun contentDescription_nonInflated_invalidLevelUsesNoSignalText() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
+    fun contentDescription_nonInflated_invalidLevelUsesNoSignalText() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
 
-            repository.inflateSignalStrength.value = false
-            repository.setAllLevels(-1)
+        repository.inflateSignalStrength.setValue(false)
+        repository.setAllLevels(-1)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
 
-            repository.setAllLevels(100)
+        repository.setAllLevels(100)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
-        }
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+    }
 
     @Test
-    fun contentDescription_nonInflated_levelStrings() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
+    fun contentDescription_nonInflated_levelStrings() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
 
-            repository.inflateSignalStrength.value = false
-            repository.setAllLevels(0)
+        repository.inflateSignalStrength.setValue(false)
+        repository.setAllLevels(0)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
 
-            repository.setAllLevels(1)
+        repository.setAllLevels(1)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
 
-            repository.setAllLevels(2)
+        repository.setAllLevels(2)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
 
-            repository.setAllLevels(3)
+        repository.setAllLevels(3)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
 
-            repository.setAllLevels(4)
+        repository.setAllLevels(4)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
-        }
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
+    }
 
     @Test
-    fun contentDescription_inflated_invalidLevelUsesNoSignalText() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
+    fun contentDescription_inflated_invalidLevelUsesNoSignalText() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
 
-            repository.inflateSignalStrength.value = true
-            repository.numberOfLevels.value = 6
+        repository.inflateSignalStrength.setValue(true)
+        repository.numberOfLevels.setValue(6)
+        repository.setAllLevels(-2)
 
-            repository.setAllLevels(-2)
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+        repository.setAllLevels(100)
 
-            repository.setAllLevels(100)
-
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
-        }
+        assertThat(latest as MobileContentDescription.Cellular)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, NO_SIGNAL))
+    }
 
     @Test
-    fun contentDescription_inflated_levelStrings() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
+    fun contentDescription_inflated_levelStrings() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
 
-            repository.inflateSignalStrength.value = true
-            repository.numberOfLevels.value = 6
+        repository.inflateSignalStrength.setValue(true)
+        repository.numberOfLevels.setValue(6)
 
-            // Note that the _repo_ level is 1 lower than the reported level through the interactor
+        // Note that the _repo_ level is 1 lower than the reported level through the interactor
 
-            repository.setAllLevels(0)
+        repository.setAllLevels(0)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, ONE_BAR))
 
-            repository.setAllLevels(1)
+        repository.setAllLevels(1)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, TWO_BARS))
 
-            repository.setAllLevels(2)
+        repository.setAllLevels(2)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, THREE_BARS))
 
-            repository.setAllLevels(3)
+        repository.setAllLevels(3)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FOUR_BARS))
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FOUR_BARS))
 
-            repository.setAllLevels(4)
+        repository.setAllLevels(4)
 
-            assertThat(latest as MobileContentDescription.Cellular)
-                .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
-        }
+        assertThat(latest)
+            .isEqualTo(MobileContentDescription.Cellular(DEFAULT_NETWORK_NAME, FULL_BARS))
+    }
 
     @Test
-    fun contentDescription_nonInflated_testABunchOfLevelsForNull() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
+    fun contentDescription_nonInflated_testABunchOfLevelsForNull() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
 
-            repository.inflateSignalStrength.value = false
-            repository.numberOfLevels.value = 5
+        repository.inflateSignalStrength.setValue(false)
+        repository.numberOfLevels.setValue(5)
 
-            // -1 and 5 are out of the bounds for non-inflated content descriptions
-            for (i in -1..5) {
-                repository.setAllLevels(i)
-                when (i) {
-                    -1,
-                    5 ->
-                        assertWithMessage("Level $i is expected to be 'no signal'")
-                            .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
-                            .isEqualTo(NO_SIGNAL)
-                    else ->
-                        assertWithMessage("Level $i is expected not to be null")
-                            .that(latest)
-                            .isNotNull()
-                }
+        // -1 and 5 are out of the bounds for non-inflated content descriptions
+        for (i in -1..5) {
+            repository.setAllLevels(i)
+            when (i) {
+                -1,
+                5 ->
+                    assertWithMessage("Level $i is expected to be null")
+                        .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
+                        .isEqualTo(NO_SIGNAL)
+                else ->
+                    assertWithMessage("Level $i is expected not to be null")
+                        .that(latest)
+                        .isNotNull()
             }
         }
+    }
 
     @Test
-    fun contentDescription_inflated_testABunchOfLevelsForNull() =
-        testScope.runTest {
-            val latest by collectLastValue(underTest.contentDescription)
-            repository.inflateSignalStrength.value = true
-            repository.numberOfLevels.value = 6
-            // -1 and 6 are out of the bounds for inflated content descriptions
-            // Note that the interactor adds 1 to the reported level, hence the -2 to 5 range
-            for (i in -2..5) {
-                repository.setAllLevels(i)
-                when (i) {
-                    -2,
-                    5 ->
-                        assertWithMessage("Level $i is expected to be 'no signal'")
-                            .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
-                            .isEqualTo(NO_SIGNAL)
-                    else ->
-                        assertWithMessage("Level $i is not expected to be null")
-                            .that(latest)
-                            .isNotNull()
-                }
+    fun contentDescription_inflated_testABunchOfLevelsForNull() = runTest {
+        val latest by underTest.contentDescription.collectLastValue()
+        repository.inflateSignalStrength.setValue(true)
+        repository.numberOfLevels.setValue(6)
+        // -1 and 6 are out of the bounds for inflated content descriptions
+        // Note that the interactor adds 1 to the reported level, hence the -2 to 5 range
+        for (i in -2..5) {
+            repository.setAllLevels(i)
+            when (i) {
+                -2,
+                5 ->
+                    assertWithMessage("Level $i is expected to be null")
+                        .that((latest as MobileContentDescription.Cellular).levelDescriptionRes)
+                        .isEqualTo(NO_SIGNAL)
+                else ->
+                    assertWithMessage("Level $i is not expected to be null")
+                        .that(latest)
+                        .isNotNull()
             }
         }
+    }
 
     @Test
-    fun networkType_dataEnabled_groupIsRepresented() =
-        testScope.runTest {
-            val expected =
-                Icon.Resource(
-                    THREE_G.dataType,
-                    ContentDescription.Resource(THREE_G.dataContentDescription),
-                )
-            connectionsRepository.mobileIsDefault.value = true
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
+    fun networkType_dataEnabled_groupIsRepresented() = runTest {
+        val expected =
+            Icon.Resource(
+                THREE_G.dataType,
+                ContentDescription.Resource(THREE_G.dataContentDescription),
+            )
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
 
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(expected)
+    }
 
     @Test
-    fun networkType_null_whenDisabled() =
-        testScope.runTest {
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-            repository.setDataEnabled(false)
-            connectionsRepository.mobileIsDefault.value = true
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun networkType_null_whenDisabled() = runTest {
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        repository.dataEnabled.setValue(false)
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            assertThat(latest).isNull()
-
-            job.cancel()
-        }
+        assertThat(latest).isNull()
+    }
 
     @Test
-    fun networkType_null_whenCarrierNetworkChangeActive() =
-        testScope.runTest {
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-            repository.carrierNetworkChangeActive.value = true
-            connectionsRepository.mobileIsDefault.value = true
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun networkType_null_whenCarrierNetworkChangeActive() = runTest {
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        repository.carrierNetworkChangeActive.setValue(true)
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            assertThat(latest).isNull()
-
-            job.cancel()
-        }
+        assertThat(latest).isNull()
+    }
 
     @Test
-    fun networkTypeIcon_notNull_whenEnabled() =
-        testScope.runTest {
-            val expected =
-                Icon.Resource(
-                    THREE_G.dataType,
-                    ContentDescription.Resource(THREE_G.dataContentDescription),
-                )
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-            repository.setDataEnabled(true)
-            repository.dataConnectionState.value = DataConnectionState.Connected
-            connectionsRepository.mobileIsDefault.value = true
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun networkTypeIcon_notNull_whenEnabled() = runTest {
+        val expected =
+            Icon.Resource(
+                THREE_G.dataType,
+                ContentDescription.Resource(THREE_G.dataContentDescription),
+            )
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        repository.dataEnabled.setValue(true)
+        repository.dataConnectionState.setValue(DataConnectionState.Connected)
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(expected)
+    }
 
     @Test
-    fun networkType_nullWhenDataDisconnects() =
-        testScope.runTest {
-            val initial =
-                Icon.Resource(
-                    THREE_G.dataType,
-                    ContentDescription.Resource(THREE_G.dataContentDescription),
-                )
+    fun networkType_nullWhenDataDisconnects() = runTest {
+        val initial =
+            Icon.Resource(
+                THREE_G.dataType,
+                ContentDescription.Resource(THREE_G.dataContentDescription),
+            )
 
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            assertThat(latest).isEqualTo(initial)
+        assertThat(latest).isEqualTo(initial)
 
-            repository.dataConnectionState.value = DataConnectionState.Disconnected
+        repository.dataConnectionState.setValue(DataConnectionState.Disconnected)
 
-            assertThat(latest).isNull()
-
-            job.cancel()
-        }
+        assertThat(latest).isNull()
+    }
 
     @Test
-    fun networkType_null_changeToDisabled() =
-        testScope.runTest {
-            val expected =
-                Icon.Resource(
-                    THREE_G.dataType,
-                    ContentDescription.Resource(THREE_G.dataContentDescription),
-                )
-            repository.dataEnabled.value = true
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun networkType_null_changeToDisabled() = runTest {
+        val expected =
+            Icon.Resource(
+                THREE_G.dataType,
+                ContentDescription.Resource(THREE_G.dataContentDescription),
+            )
+        repository.dataEnabled.setValue(true)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            assertThat(latest).isEqualTo(expected)
+        assertThat(latest).isEqualTo(expected)
 
-            repository.dataEnabled.value = false
+        repository.dataEnabled.setValue(false)
 
-            assertThat(latest).isNull()
-
-            job.cancel()
-        }
+        assertThat(latest).isNull()
+    }
 
     @Test
-    fun networkType_alwaysShow_shownEvenWhenDisabled() =
-        testScope.runTest {
-            repository.dataEnabled.value = false
+    fun networkType_alwaysShow_shownEvenWhenDisabled() = runTest {
+        repository.dataEnabled.setValue(false)
 
-            connectionsRepository.defaultDataSubRatConfig.value =
-                MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+        mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+            MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+        )
 
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            val expected =
-                Icon.Resource(
-                    THREE_G.dataType,
-                    ContentDescription.Resource(THREE_G.dataContentDescription),
-                )
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
+        val expected =
+            Icon.Resource(
+                THREE_G.dataType,
+                ContentDescription.Resource(THREE_G.dataContentDescription),
+            )
+        assertThat(latest).isEqualTo(expected)
+    }
 
     @Test
-    fun networkType_alwaysShow_shownEvenWhenDisconnected() =
-        testScope.runTest {
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-            repository.dataConnectionState.value = DataConnectionState.Disconnected
+    fun networkType_alwaysShow_shownEvenWhenDisconnected() = runTest {
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        repository.dataConnectionState.setValue(DataConnectionState.Disconnected)
 
-            connectionsRepository.defaultDataSubRatConfig.value =
-                MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+        mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+            MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+        )
 
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            val expected =
-                Icon.Resource(
-                    THREE_G.dataType,
-                    ContentDescription.Resource(THREE_G.dataContentDescription),
-                )
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
+        val expected =
+            Icon.Resource(
+                THREE_G.dataType,
+                ContentDescription.Resource(THREE_G.dataContentDescription),
+            )
+        assertThat(latest).isEqualTo(expected)
+    }
 
     @Test
-    fun networkType_alwaysShow_shownEvenWhenFailedConnection() =
-        testScope.runTest {
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-            connectionsRepository.mobileIsDefault.value = true
-            connectionsRepository.defaultDataSubRatConfig.value =
-                MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+    fun networkType_alwaysShow_shownEvenWhenFailedConnection() = runTest {
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
+        mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+            MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+        )
 
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            val expected =
-                Icon.Resource(
-                    THREE_G.dataType,
-                    ContentDescription.Resource(THREE_G.dataContentDescription),
-                )
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
+        val expected =
+            Icon.Resource(
+                THREE_G.dataType,
+                ContentDescription.Resource(THREE_G.dataContentDescription),
+            )
+        assertThat(latest).isEqualTo(expected)
+    }
 
     @Test
-    fun networkType_alwaysShow_usesDefaultIconWhenInvalid() =
-        testScope.runTest {
-            // The UNKNOWN icon group doesn't have a valid data type icon ID, and the logic from the
-            // old pipeline was to use the default icon group if the map doesn't exist
-            repository.setNetworkTypeKey(UNKNOWN.name)
-            connectionsRepository.defaultDataSubRatConfig.value =
-                MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+    fun networkType_alwaysShow_usesDefaultIconWhenInvalid() = runTest {
+        // The UNKNOWN icon group doesn't have a valid data type icon ID, and the logic from the
+        // old pipeline was to use the default icon group if the map doesn't exist
+        repository.setNetworkTypeKey(UNKNOWN.name)
+        mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+            MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+        )
 
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            val expected =
-                Icon.Resource(
-                    connectionsRepository.defaultMobileIconGroup.value.dataType,
-                    ContentDescription.Resource(G.dataContentDescription),
-                )
+        val expected =
+            Icon.Resource(
+                kairos.transact {
+                    mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.sample().dataType
+                },
+                ContentDescription.Resource(G.dataContentDescription),
+            )
 
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(expected)
+    }
 
     @Test
-    fun networkType_alwaysShow_shownWhenNotDefault() =
-        testScope.runTest {
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-            connectionsRepository.mobileIsDefault.value = false
-            connectionsRepository.defaultDataSubRatConfig.value =
-                MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+    fun networkType_alwaysShow_shownWhenNotDefault() = runTest {
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(false)
+        mobileConnectionsRepositoryKairos.fake.defaultDataSubRatConfig.setValue(
+            MobileMappings.Config().also { it.alwaysShowDataRatIcon = true }
+        )
 
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            val expected =
-                Icon.Resource(
-                    THREE_G.dataType,
-                    ContentDescription.Resource(THREE_G.dataContentDescription),
-                )
-            assertThat(latest).isEqualTo(expected)
-
-            job.cancel()
-        }
+        val expected =
+            Icon.Resource(
+                THREE_G.dataType,
+                ContentDescription.Resource(THREE_G.dataContentDescription),
+            )
+        assertThat(latest).isEqualTo(expected)
+    }
 
     @Test
-    fun networkType_notShownWhenNotDefault() =
-        testScope.runTest {
-            repository.setNetworkTypeKey(connectionsRepository.GSM_KEY)
-            repository.dataConnectionState.value = DataConnectionState.Connected
-            connectionsRepository.mobileIsDefault.value = false
+    fun networkType_notShownWhenNotDefault() = runTest {
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        repository.dataConnectionState.setValue(DataConnectionState.Connected)
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(false)
 
-            var latest: Icon? = null
-            val job = underTest.networkTypeIcon.onEach { latest = it }.launchIn(this)
+        val latest by underTest.networkTypeIcon.collectLastValue()
 
-            assertThat(latest).isNull()
-
-            job.cancel()
-        }
+        assertThat(latest).isNull()
+    }
 
     @Test
-    fun roaming() =
-        testScope.runTest {
-            repository.setAllRoaming(true)
+    fun roaming() = runTest {
+        repository.setAllRoaming(true)
 
-            var latest: Boolean? = null
-            val job = underTest.roaming.onEach { latest = it }.launchIn(this)
+        val latest by underTest.roaming.collectLastValue()
 
-            assertThat(latest).isTrue()
+        assertThat(latest).isTrue()
 
-            repository.setAllRoaming(false)
+        repository.setAllRoaming(false)
 
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun dataActivity_nullWhenConfigIsOff() =
-        testScope.runTest {
-            // Create a new view model here so the constants are properly read
-            whenever(constants.shouldShowActivityConfig).thenReturn(false)
-            createAndSetViewModel()
+    fun dataActivity_nullWhenConfigIsOff() = runTest {
+        constants.stub { on { shouldShowActivityConfig } doReturn false }
 
-            var inVisible: Boolean? = null
-            val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this)
+        val inVisible by underTest.activityInVisible.collectLastValue()
 
-            var outVisible: Boolean? = null
-            val outJob = underTest.activityInVisible.onEach { outVisible = it }.launchIn(this)
+        val outVisible by underTest.activityInVisible.collectLastValue()
 
-            var containerVisible: Boolean? = null
-            val containerJob =
-                underTest.activityInVisible.onEach { containerVisible = it }.launchIn(this)
+        val containerVisible by underTest.activityInVisible.collectLastValue()
 
-            repository.dataActivityDirection.value =
-                DataActivityModel(hasActivityIn = true, hasActivityOut = true)
+        repository.dataActivityDirection.setValue(
+            DataActivityModel(hasActivityIn = true, hasActivityOut = true)
+        )
 
-            assertThat(inVisible).isFalse()
-            assertThat(outVisible).isFalse()
-            assertThat(containerVisible).isFalse()
-
-            inJob.cancel()
-            outJob.cancel()
-            containerJob.cancel()
-        }
+        assertThat(inVisible).isFalse()
+        assertThat(outVisible).isFalse()
+        assertThat(containerVisible).isFalse()
+    }
 
     @Test
     @DisableFlags(FLAG_STATUS_BAR_STATIC_INOUT_INDICATORS)
-    fun dataActivity_configOn_testIndicators_staticFlagOff() =
-        testScope.runTest {
-            // Create a new view model here so the constants are properly read
-            whenever(constants.shouldShowActivityConfig).thenReturn(true)
-            createAndSetViewModel()
+    fun dataActivity_configOn_testIndicators_staticFlagOff() = runTest {
+        constants.stub { on { shouldShowActivityConfig } doReturn true }
 
-            var inVisible: Boolean? = null
-            val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this)
+        val inVisible by underTest.activityInVisible.collectLastValue()
 
-            var outVisible: Boolean? = null
-            val outJob = underTest.activityOutVisible.onEach { outVisible = it }.launchIn(this)
+        val outVisible by underTest.activityOutVisible.collectLastValue()
 
-            var containerVisible: Boolean? = null
-            val containerJob =
-                underTest.activityContainerVisible.onEach { containerVisible = it }.launchIn(this)
+        val containerVisible by underTest.activityContainerVisible.collectLastValue()
 
-            repository.dataActivityDirection.value =
-                DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+        repository.dataActivityDirection.setValue(
+            DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+        )
 
-            yield()
+        yield()
 
-            assertThat(inVisible).isTrue()
-            assertThat(outVisible).isFalse()
-            assertThat(containerVisible).isTrue()
+        assertThat(inVisible).isTrue()
+        assertThat(outVisible).isFalse()
+        assertThat(containerVisible).isTrue()
 
-            repository.dataActivityDirection.value =
-                DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+        repository.dataActivityDirection.setValue(
+            DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+        )
 
-            assertThat(inVisible).isFalse()
-            assertThat(outVisible).isTrue()
-            assertThat(containerVisible).isTrue()
+        assertThat(inVisible).isFalse()
+        assertThat(outVisible).isTrue()
+        assertThat(containerVisible).isTrue()
 
-            repository.dataActivityDirection.value =
-                DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+        repository.dataActivityDirection.setValue(
+            DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+        )
 
-            assertThat(inVisible).isFalse()
-            assertThat(outVisible).isFalse()
-            assertThat(containerVisible).isFalse()
-
-            inJob.cancel()
-            outJob.cancel()
-            containerJob.cancel()
-        }
+        assertThat(inVisible).isFalse()
+        assertThat(outVisible).isFalse()
+        assertThat(containerVisible).isFalse()
+    }
 
     @Test
     @EnableFlags(FLAG_STATUS_BAR_STATIC_INOUT_INDICATORS)
-    fun dataActivity_configOn_testIndicators_staticFlagOn() =
-        testScope.runTest {
-            // Create a new view model here so the constants are properly read
-            whenever(constants.shouldShowActivityConfig).thenReturn(true)
-            createAndSetViewModel()
+    fun dataActivity_configOn_testIndicators_staticFlagOn() = runTest {
+        constants.stub { on { shouldShowActivityConfig } doReturn true }
 
-            var inVisible: Boolean? = null
-            val inJob = underTest.activityInVisible.onEach { inVisible = it }.launchIn(this)
+        val inVisible by underTest.activityInVisible.collectLastValue()
 
-            var outVisible: Boolean? = null
-            val outJob = underTest.activityOutVisible.onEach { outVisible = it }.launchIn(this)
+        val outVisible by underTest.activityOutVisible.collectLastValue()
 
-            var containerVisible: Boolean? = null
-            val containerJob =
-                underTest.activityContainerVisible.onEach { containerVisible = it }.launchIn(this)
+        val containerVisible by underTest.activityContainerVisible.collectLastValue()
 
-            repository.dataActivityDirection.value =
-                DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+        repository.dataActivityDirection.setValue(
+            DataActivityModel(hasActivityIn = true, hasActivityOut = false)
+        )
 
-            yield()
+        yield()
 
-            assertThat(inVisible).isTrue()
-            assertThat(outVisible).isFalse()
-            assertThat(containerVisible).isTrue()
+        assertThat(inVisible).isTrue()
+        assertThat(outVisible).isFalse()
+        assertThat(containerVisible).isTrue()
 
-            repository.dataActivityDirection.value =
-                DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+        repository.dataActivityDirection.setValue(
+            DataActivityModel(hasActivityIn = false, hasActivityOut = true)
+        )
 
-            assertThat(inVisible).isFalse()
-            assertThat(outVisible).isTrue()
-            assertThat(containerVisible).isTrue()
+        assertThat(inVisible).isFalse()
+        assertThat(outVisible).isTrue()
+        assertThat(containerVisible).isTrue()
 
-            repository.dataActivityDirection.value =
-                DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+        repository.dataActivityDirection.setValue(
+            DataActivityModel(hasActivityIn = false, hasActivityOut = false)
+        )
 
-            assertThat(inVisible).isFalse()
-            assertThat(outVisible).isFalse()
-            assertThat(containerVisible).isTrue()
-
-            inJob.cancel()
-            outJob.cancel()
-            containerJob.cancel()
-        }
+        assertThat(inVisible).isFalse()
+        assertThat(outVisible).isFalse()
+        assertThat(containerVisible).isTrue()
+    }
 
     @Test
-    fun netTypeBackground_nullWhenNoPrioritizedCapabilities() =
-        testScope.runTest {
-            createAndSetViewModel()
+    fun netTypeBackground_nullWhenNoPrioritizedCapabilities() = runTest {
+        val latest by underTest.networkTypeBackground.collectLastValue()
 
-            val latest by collectLastValue(underTest.networkTypeBackground)
+        repository.hasPrioritizedNetworkCapabilities.setValue(false)
 
-            repository.hasPrioritizedNetworkCapabilities.value = false
-
-            assertThat(latest).isNull()
-        }
+        assertThat(latest).isNull()
+    }
 
     @Test
     @EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
-    fun netTypeBackground_sliceUiEnabled_notNullWhenPrioritizedCapabilities_newIcons() =
-        testScope.runTest {
-            createAndSetViewModel()
+    fun netTypeBackground_sliceUiEnabled_notNullWhenPrioritizedCapabilities_newIcons() = runTest {
+        val latest by underTest.networkTypeBackground.collectLastValue()
 
-            val latest by collectLastValue(underTest.networkTypeBackground)
+        repository.hasPrioritizedNetworkCapabilities.setValue(true)
 
-            repository.hasPrioritizedNetworkCapabilities.value = true
-
-            assertThat(latest)
-                .isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background_updated, null))
-        }
+        assertThat(latest)
+            .isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background_updated, null))
+    }
 
     @Test
     @DisableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
-    fun netTypeBackground_sliceUiDisabled_notNullWhenPrioritizedCapabilities_oldIcons() =
-        testScope.runTest {
-            createAndSetViewModel()
+    fun netTypeBackground_sliceUiDisabled_notNullWhenPrioritizedCapabilities_oldIcons() = runTest {
+        val latest by underTest.networkTypeBackground.collectLastValue()
 
-            val latest by collectLastValue(underTest.networkTypeBackground)
+        repository.allowNetworkSliceIndicator.setValue(true)
+        repository.hasPrioritizedNetworkCapabilities.setValue(true)
 
-            repository.hasPrioritizedNetworkCapabilities.value = true
-
-            assertThat(latest)
-                .isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background, null))
-        }
+        assertThat(latest).isEqualTo(Icon.Resource(R.drawable.mobile_network_type_background, null))
+    }
 
     @Test
-    fun nonTerrestrial_defaultProperties() =
-        testScope.runTest {
-            repository.isNonTerrestrial.value = true
+    fun nonTerrestrial_defaultProperties() = runTest {
+        repository.isNonTerrestrial.setValue(true)
 
-            val roaming by collectLastValue(underTest.roaming)
-            val networkTypeIcon by collectLastValue(underTest.networkTypeIcon)
-            val networkTypeBackground by collectLastValue(underTest.networkTypeBackground)
-            val activityInVisible by collectLastValue(underTest.activityInVisible)
-            val activityOutVisible by collectLastValue(underTest.activityOutVisible)
-            val activityContainerVisible by collectLastValue(underTest.activityContainerVisible)
+        val roaming by underTest.roaming.collectLastValue()
+        val networkTypeIcon by underTest.networkTypeIcon.collectLastValue()
+        val networkTypeBackground by underTest.networkTypeBackground.collectLastValue()
+        val activityInVisible by underTest.activityInVisible.collectLastValue()
+        val activityOutVisible by underTest.activityOutVisible.collectLastValue()
+        val activityContainerVisible by underTest.activityContainerVisible.collectLastValue()
 
-            assertThat(roaming).isFalse()
-            assertThat(networkTypeIcon).isNull()
-            assertThat(networkTypeBackground).isNull()
-            assertThat(activityInVisible).isFalse()
-            assertThat(activityOutVisible).isFalse()
-            assertThat(activityContainerVisible).isFalse()
-        }
+        assertThat(roaming).isFalse()
+        assertThat(networkTypeIcon).isNull()
+        assertThat(networkTypeBackground).isNull()
+        assertThat(activityInVisible).isFalse()
+        assertThat(activityOutVisible).isFalse()
+        assertThat(activityContainerVisible).isFalse()
+    }
 
     @Test
-    fun nonTerrestrial_ignoresDefaultProperties() =
-        testScope.runTest {
-            repository.isNonTerrestrial.value = true
+    fun nonTerrestrial_ignoresDefaultProperties() = runTest {
+        repository.isNonTerrestrial.setValue(true)
 
-            val roaming by collectLastValue(underTest.roaming)
-            val networkTypeIcon by collectLastValue(underTest.networkTypeIcon)
-            val networkTypeBackground by collectLastValue(underTest.networkTypeBackground)
-            val activityInVisible by collectLastValue(underTest.activityInVisible)
-            val activityOutVisible by collectLastValue(underTest.activityOutVisible)
-            val activityContainerVisible by collectLastValue(underTest.activityContainerVisible)
+        val roaming by underTest.roaming.collectLastValue()
+        val networkTypeIcon by underTest.networkTypeIcon.collectLastValue()
+        val networkTypeBackground by underTest.networkTypeBackground.collectLastValue()
+        val activityInVisible by underTest.activityInVisible.collectLastValue()
+        val activityOutVisible by underTest.activityOutVisible.collectLastValue()
+        val activityContainerVisible by underTest.activityContainerVisible.collectLastValue()
 
-            repository.setAllRoaming(true)
-            repository.setNetworkTypeKey(connectionsRepository.LTE_KEY)
-            // sets the background on cellular
-            repository.hasPrioritizedNetworkCapabilities.value = true
-            repository.dataActivityDirection.value =
-                DataActivityModel(hasActivityIn = true, hasActivityOut = true)
+        repository.setAllRoaming(true)
+        repository.setNetworkTypeKey(mobileConnectionsRepositoryKairos.fake.LTE_KEY)
+        // sets the background on cellular
+        repository.hasPrioritizedNetworkCapabilities.setValue(true)
+        repository.dataActivityDirection.setValue(
+            DataActivityModel(hasActivityIn = true, hasActivityOut = true)
+        )
 
-            assertThat(roaming).isFalse()
-            assertThat(networkTypeIcon).isNull()
-            assertThat(networkTypeBackground).isNull()
-            assertThat(activityInVisible).isFalse()
-            assertThat(activityOutVisible).isFalse()
-            assertThat(activityContainerVisible).isFalse()
-        }
+        assertThat(roaming).isFalse()
+        assertThat(networkTypeIcon).isNull()
+        assertThat(networkTypeBackground).isNull()
+        assertThat(activityInVisible).isFalse()
+        assertThat(activityOutVisible).isFalse()
+        assertThat(activityContainerVisible).isFalse()
+    }
 
     @DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
     @Test
-    fun nonTerrestrial_usesSatelliteIcon_flagOff() =
-        testScope.runTest {
-            repository.isNonTerrestrial.value = true
-            repository.setAllLevels(0)
-            repository.satelliteLevel.value = 0
+    fun nonTerrestrial_usesSatelliteIcon_flagOff() = runTest {
+        repository.isNonTerrestrial.setValue(true)
+        repository.setAllLevels(0)
+        repository.satelliteLevel.setValue(0)
 
-            val latest by
-                collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
+        val latest by underTest.icon.map { it as SignalIconModel.Satellite }.collectLastValue()
 
-            // Level 0 -> no connection
-            assertThat(latest).isNotNull()
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+        // Level 0 -> no connection
+        assertThat(latest).isNotNull()
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
 
-            // 1-2 -> 1 bar
-            repository.setAllLevels(1)
-            repository.satelliteLevel.value = 1
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+        // 1-2 -> 1 bar
+        repository.setAllLevels(1)
+        repository.satelliteLevel.setValue(1)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
 
-            repository.setAllLevels(2)
-            repository.satelliteLevel.value = 2
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+        repository.setAllLevels(2)
+        repository.satelliteLevel.setValue(2)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
 
-            // 3-4 -> 2 bars
-            repository.setAllLevels(3)
-            repository.satelliteLevel.value = 3
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+        // 3-4 -> 2 bars
+        repository.setAllLevels(3)
+        repository.satelliteLevel.setValue(3)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
 
-            repository.setAllLevels(4)
-            repository.satelliteLevel.value = 4
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
-        }
+        repository.setAllLevels(4)
+        repository.satelliteLevel.setValue(4)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+    }
 
     @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
     @Test
-    fun nonTerrestrial_usesSatelliteIcon_flagOn() =
-        testScope.runTest {
-            repository.isNonTerrestrial.value = true
-            repository.satelliteLevel.value = 0
+    fun nonTerrestrial_usesSatelliteIcon_flagOn() = runTest {
+        repository.isNonTerrestrial.setValue(true)
+        repository.satelliteLevel.setValue(0)
 
-            val latest by
-                collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
+        val latest by underTest.icon.map { it as SignalIconModel.Satellite }.collectLastValue()
 
-            // Level 0 -> no connection
-            assertThat(latest).isNotNull()
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+        // Level 0 -> no connection
+        assertThat(latest).isNotNull()
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
 
-            // 1-2 -> 1 bar
-            repository.satelliteLevel.value = 1
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+        // 1-2 -> 1 bar
+        repository.satelliteLevel.setValue(1)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
 
-            repository.satelliteLevel.value = 2
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+        repository.satelliteLevel.setValue(2)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
 
-            // 3-4 -> 2 bars
-            repository.satelliteLevel.value = 3
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+        // 3-4 -> 2 bars
+        repository.satelliteLevel.setValue(3)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
 
-            repository.satelliteLevel.value = 4
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
-        }
+        repository.satelliteLevel.setValue(4)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+    }
 
     @DisableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
     @Test
-    fun satelliteIcon_ignoresInflateSignalStrength_flagOff() =
-        testScope.runTest {
-            // Note that this is the exact same test as above, but with inflateSignalStrength set to
-            // true we note that the level is unaffected by inflation
-            repository.inflateSignalStrength.value = true
-            repository.isNonTerrestrial.value = true
-            repository.setAllLevels(0)
-            repository.satelliteLevel.value = 0
+    fun satelliteIcon_ignoresInflateSignalStrength_flagOff() = runTest {
+        // Note that this is the exact same test as above, but with inflateSignalStrength set to
+        // true we note that the level is unaffected by inflation
+        repository.inflateSignalStrength.setValue(true)
+        repository.isNonTerrestrial.setValue(true)
+        repository.setAllLevels(0)
+        repository.satelliteLevel.setValue(0)
 
-            val latest by
-                collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
+        val latest by underTest.icon.map { it as SignalIconModel.Satellite }.collectLastValue()
 
-            // Level 0 -> no connection
-            assertThat(latest).isNotNull()
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+        // Level 0 -> no connection
+        assertThat(latest).isNotNull()
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
 
-            // 1-2 -> 1 bar
-            repository.setAllLevels(1)
-            repository.satelliteLevel.value = 1
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+        // 1-2 -> 1 bar
+        repository.setAllLevels(1)
+        repository.satelliteLevel.setValue(1)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
 
-            repository.setAllLevels(2)
-            repository.satelliteLevel.value = 2
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+        repository.setAllLevels(2)
+        repository.satelliteLevel.setValue(2)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
 
-            // 3-4 -> 2 bars
-            repository.setAllLevels(3)
-            repository.satelliteLevel.value = 3
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+        // 3-4 -> 2 bars
+        repository.setAllLevels(3)
+        repository.satelliteLevel.setValue(3)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
 
-            repository.setAllLevels(4)
-            repository.satelliteLevel.value = 4
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
-        }
+        repository.setAllLevels(4)
+        repository.satelliteLevel.setValue(4)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+    }
 
     @EnableFlags(com.android.internal.telephony.flags.Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
     @Test
-    fun satelliteIcon_ignoresInflateSignalStrength_flagOn() =
-        testScope.runTest {
-            // Note that this is the exact same test as above, but with inflateSignalStrength set to
-            // true we note that the level is unaffected by inflation
-            repository.inflateSignalStrength.value = true
-            repository.isNonTerrestrial.value = true
-            repository.satelliteLevel.value = 0
+    fun satelliteIcon_ignoresInflateSignalStrength_flagOn() = runTest {
+        // Note that this is the exact same test as above, but with inflateSignalStrength set to
+        // true we note that the level is unaffected by inflation
+        repository.inflateSignalStrength.setValue(true)
+        repository.isNonTerrestrial.setValue(true)
+        repository.satelliteLevel.setValue(0)
 
-            val latest by
-                collectLastValue(underTest.icon.filterIsInstance(SignalIconModel.Satellite::class))
+        val latest by underTest.icon.map { it as SignalIconModel.Satellite }.collectLastValue()
 
-            // Level 0 -> no connection
-            assertThat(latest).isNotNull()
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
+        // Level 0 -> no connection
+        assertThat(latest).isNotNull()
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_0)
 
-            // 1-2 -> 1 bar
-            repository.satelliteLevel.value = 1
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+        // 1-2 -> 1 bar
+        repository.satelliteLevel.setValue(1)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
 
-            repository.satelliteLevel.value = 2
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
+        repository.satelliteLevel.setValue(2)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_1)
 
-            // 3-4 -> 2 bars
-            repository.satelliteLevel.value = 3
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
+        // 3-4 -> 2 bars
+        repository.satelliteLevel.setValue(3)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
 
-            repository.satelliteLevel.value = 4
-            assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
-        }
-
-    private fun createAndSetViewModel() {
-        underTest =
-            MobileIconViewModelKairos(
-                SUB_1_ID,
-                interactor,
-                airplaneModeInteractor,
-                constants,
-                testScope.backgroundScope,
-            )
+        repository.satelliteLevel.setValue(4)
+        assertThat(latest!!.icon.res).isEqualTo(R.drawable.ic_satellite_connected_2)
     }
 
     companion object {
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt
index e921430..b11bad6 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,348 +16,323 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
 
+import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
 import android.telephony.SubscriptionManager.PROFILE_CLASS_UNSET
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.mobile.TelephonyIcons
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.flags.FakeFeatureFlagsClassic
-import com.android.systemui.statusbar.phone.StatusBarLocation
-import com.android.systemui.statusbar.pipeline.airplane.data.repository.FakeAirplaneModeRepository
-import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.runKairosTest
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
+import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepository
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel
-import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
-import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
-import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import com.android.systemui.statusbar.pipeline.shared.data.repository.FakeConnectivityRepository
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairos
 import com.android.systemui.testKosmos
-import com.android.systemui.util.mockito.mock
 import com.google.common.truth.Truth.assertThat
-import junit.framework.Assert.assertFalse
-import junit.framework.Assert.assertTrue
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.isActive
-import kotlinx.coroutines.test.TestScope
-import kotlinx.coroutines.test.UnconfinedTestDispatcher
-import kotlinx.coroutines.test.runTest
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.MockitoAnnotations
 
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class MobileIconsViewModelKairosTest : SysuiTestCase() {
-    private val kosmos = testKosmos()
 
-    private lateinit var underTest: MobileIconsViewModelKairos
-    private val interactor = FakeMobileIconsInteractor(FakeMobileMappingsProxy(), mock())
-    private val flags = FakeFeatureFlagsClassic()
+    private val Kosmos.underTest
+        get() = mobileIconsViewModelKairos
 
-    private lateinit var airplaneModeInteractor: AirplaneModeInteractor
-    @Mock private lateinit var constants: ConnectivityConstants
-    @Mock private lateinit var logger: MobileViewLogger
-    @Mock private lateinit var verboseLogger: VerboseMobileViewLogger
+    private val kosmos =
+        testKosmos().apply {
+            useUnconfinedTestDispatcher()
+            featureFlagsClassic.fake.apply {
+                setDefault(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS)
+            }
+            mobileConnectionsRepositoryKairos =
+                fakeMobileConnectionsRepositoryKairos.apply {
+                    val subList = listOf(SUB_1, SUB_2)
+                    setActiveMobileDataSubscriptionId(SUB_1.subscriptionId)
+                    subscriptions.setValue(subList)
+                }
+        }
 
-    private val testDispatcher = UnconfinedTestDispatcher()
-    private val testScope = TestScope(testDispatcher)
+    private fun runTest(block: suspend KairosTestScope.() -> Unit) =
+        kosmos.run { runKairosTest { block() } }
 
-    @Before
-    fun setUp() {
-        MockitoAnnotations.initMocks(this)
-
-        airplaneModeInteractor =
-            AirplaneModeInteractor(
-                FakeAirplaneModeRepository(),
-                FakeConnectivityRepository(),
-                kosmos.fakeMobileConnectionsRepository,
-            )
-
-        underTest =
-            MobileIconsViewModelKairos(
-                logger,
-                verboseLogger,
-                interactor,
-                airplaneModeInteractor,
-                constants,
-                testScope.backgroundScope,
-            )
-
-        interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
+    private fun KairosTestScope.setSubscriptions(
+        subList: List<SubscriptionModel>,
+        activeSubId: Int = subList.getOrNull(0)?.subscriptionId ?: INVALID_SUBSCRIPTION_ID,
+    ) {
+        println("setSubscriptions: mobileConnectionsRepositoryKairos.fake.subscriptions")
+        mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(subList)
+        println(
+            "setSubscriptions: mobileConnectionsRepositoryKairos.fake.setActiveMobileDataSubscriptionId"
+        )
+        mobileConnectionsRepositoryKairos.fake.setActiveMobileDataSubscriptionId(activeSubId)
     }
 
     @Test
-    fun subscriptionIdsFlow_matchesInteractor() =
-        testScope.runTest {
-            var latest: List<Int>? = null
-            val job = underTest.subscriptionIdsFlow.onEach { latest = it }.launchIn(this)
-
-            interactor.filteredSubscriptions.value =
-                listOf(
-                    SubscriptionModel(
-                        subscriptionId = 1,
-                        isOpportunistic = false,
-                        carrierName = "Carrier 1",
-                        profileClass = PROFILE_CLASS_UNSET,
-                    )
+    fun subscriptionIdsFlow_matchesInteractor() = runTest {
+        val latest by underTest.subscriptionIds.collectLastValue()
+        setSubscriptions(
+            listOf(
+                SubscriptionModel(
+                    subscriptionId = 1,
+                    isOpportunistic = false,
+                    carrierName = "Carrier 1",
+                    profileClass = PROFILE_CLASS_UNSET,
                 )
-            assertThat(latest).isEqualTo(listOf(1))
+            )
+        )
+        assertThat(latest).isEqualTo(listOf(1))
 
-            interactor.filteredSubscriptions.value =
-                listOf(
-                    SubscriptionModel(
-                        subscriptionId = 2,
-                        isOpportunistic = false,
-                        carrierName = "Carrier 2",
-                        profileClass = PROFILE_CLASS_UNSET,
-                    ),
-                    SubscriptionModel(
-                        subscriptionId = 5,
-                        isOpportunistic = true,
-                        carrierName = "Carrier 5",
-                        profileClass = PROFILE_CLASS_UNSET,
-                    ),
-                    SubscriptionModel(
-                        subscriptionId = 7,
-                        isOpportunistic = true,
-                        carrierName = "Carrier 7",
-                        profileClass = PROFILE_CLASS_UNSET,
-                    ),
-                )
-            assertThat(latest).isEqualTo(listOf(2, 5, 7))
+        setSubscriptions(
+            listOf(
+                SubscriptionModel(
+                    subscriptionId = 2,
+                    isOpportunistic = false,
+                    carrierName = "Carrier 2",
+                    profileClass = PROFILE_CLASS_UNSET,
+                ),
+                SubscriptionModel(
+                    subscriptionId = 5,
+                    isOpportunistic = true,
+                    carrierName = "Carrier 5",
+                    profileClass = PROFILE_CLASS_UNSET,
+                ),
+                SubscriptionModel(
+                    subscriptionId = 7,
+                    isOpportunistic = true,
+                    carrierName = "Carrier 7",
+                    profileClass = PROFILE_CLASS_UNSET,
+                ),
+            )
+        )
+        assertThat(latest).isEqualTo(listOf(2, 5, 7))
 
-            interactor.filteredSubscriptions.value = emptyList()
-            assertThat(latest).isEmpty()
-
-            job.cancel()
-        }
+        setSubscriptions(emptyList())
+        assertThat(latest).isEmpty()
+    }
 
     @Test
-    fun caching_mobileIconViewModelIsReusedForSameSubId() =
-        testScope.runTest {
-            val model1 = underTest.viewModelForSub(1, StatusBarLocation.HOME)
-            val model2 = underTest.viewModelForSub(1, StatusBarLocation.QS)
+    fun firstMobileSubShowingNetworkTypeIcon_noSubs_false() = runTest {
+        val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
 
-            assertThat(model1.commonImpl).isSameInstanceAs(model2.commonImpl)
-        }
+        setSubscriptions(emptyList())
+
+        assertThat(latest).isEqualTo(false)
+    }
 
     @Test
-    fun caching_invalidViewModelsAreRemovedFromCacheWhenSubDisappears() =
-        testScope.runTest {
-            // Retrieve models to trigger caching
-            val model1 = underTest.viewModelForSub(1, StatusBarLocation.HOME)
-            val model2 = underTest.viewModelForSub(2, StatusBarLocation.QS)
+    fun firstMobileSubShowingNetworkTypeIcon_oneSub_notShowingRat_false() = runTest {
+        val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
 
-            // Both impls are cached
-            assertThat(underTest.reuseCache.keys).containsExactly(1, 2)
+        setSubscriptions(listOf(SUB_1))
 
-            // SUB_1 is removed from the list...
-            interactor.filteredSubscriptions.value = listOf(SUB_2)
+        // The unknown icon group doesn't show a RAT
+        mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+            .sample()[SUB_1.subscriptionId]
+            ?.resolvedNetworkType
+            ?.setValue(UnknownNetworkType)
 
-            // ... and dropped from the cache
-            assertThat(underTest.reuseCache.keys).containsExactly(2)
-        }
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun caching_invalidatedViewModelsAreCanceled() =
-        testScope.runTest {
-            // Retrieve models to trigger caching
-            val model1 = underTest.viewModelForSub(1, StatusBarLocation.HOME)
-            val model2 = underTest.viewModelForSub(2, StatusBarLocation.QS)
+    fun firstMobileSubShowingNetworkTypeIcon_oneSub_showingRat_true() = runTest {
+        val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
+        setSubscriptions(listOf(SUB_1))
 
-            var scope1 = underTest.reuseCache[1]?.second
-            var scope2 = underTest.reuseCache[2]?.second
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
 
-            // Scopes are not canceled
-            assertTrue(scope1!!.isActive)
-            assertTrue(scope2!!.isActive)
+        // The 3G icon group will show a RAT
+        val repo =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_1.subscriptionId]!!
 
-            // SUB_1 is removed from the list...
-            interactor.filteredSubscriptions.value = listOf(SUB_2)
+        repo.resolvedNetworkType.setValue(
+            DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        )
+        repo.dataConnectionState.setValue(DataConnectionState.Connected)
 
-            // scope1 is canceled
-            assertFalse(scope1!!.isActive)
-            assertTrue(scope2!!.isActive)
-        }
+        assertThat(latest).isEqualTo(true)
+    }
 
     @Test
-    fun firstMobileSubShowingNetworkTypeIcon_noSubs_false() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job =
-                underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun firstMobileSubShowingNetworkTypeIcon_updatesAsSubUpdates() = runTest {
+        val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
+        setSubscriptions(listOf(SUB_1))
 
-            interactor.filteredSubscriptions.value = emptyList()
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
 
-            assertThat(latest).isFalse()
+        val repo =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_1.subscriptionId]!!
 
-            job.cancel()
-        }
+        repo.dataConnectionState.setValue(DataConnectionState.Connected)
+
+        repo.resolvedNetworkType.setValue(
+            DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        )
+        assertThat(latest).isEqualTo(true)
+
+        mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+            TelephonyIcons.UNKNOWN
+        )
+
+        repo.resolvedNetworkType.setValue(UnknownNetworkType)
+        assertThat(latest).isEqualTo(false)
+
+        repo.resolvedNetworkType.setValue(
+            DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.LTE_KEY)
+        )
+        assertThat(latest).isEqualTo(true)
+    }
 
     @Test
-    fun firstMobileSubShowingNetworkTypeIcon_oneSub_notShowingRat_false() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job =
-                underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun firstMobileSubShowingNetworkTypeIcon_multipleSubs_lastSubNotShowingRat_false() = runTest {
+        val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
 
-            interactor.filteredSubscriptions.value = listOf(SUB_1)
-            // The unknown icon group doesn't show a RAT
-            interactor.getInteractorForSubId(1)!!.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
+        mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+            TelephonyIcons.UNKNOWN
+        )
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
 
-            assertThat(latest).isFalse()
+        val repo1 =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_1.subscriptionId]!!
 
-            job.cancel()
-        }
+        repo1.resolvedNetworkType.setValue(
+            DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        )
+
+        val repo2 =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_2.subscriptionId]!!
+
+        repo2.resolvedNetworkType.setValue(UnknownNetworkType)
+
+        assertThat(latest).isFalse()
+    }
 
     @Test
-    fun firstMobileSubShowingNetworkTypeIcon_oneSub_showingRat_true() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job =
-                underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun firstMobileSubShowingNetworkTypeIcon_multipleSubs_lastSubShowingRat_true() = runTest {
+        val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
 
-            interactor.filteredSubscriptions.value = listOf(SUB_1)
-            // The 3G icon group will show a RAT
-            interactor.getInteractorForSubId(1)!!.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
+        mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+            TelephonyIcons.UNKNOWN
+        )
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
 
-            assertThat(latest).isTrue()
+        val repo1 =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_1.subscriptionId]!!
 
-            job.cancel()
-        }
+        repo1.dataConnectionState.setValue(DataConnectionState.Connected)
+        repo1.resolvedNetworkType.setValue(UnknownNetworkType)
+
+        val repo2 =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_2.subscriptionId]!!
+
+        repo2.dataConnectionState.setValue(DataConnectionState.Connected)
+        repo2.resolvedNetworkType.setValue(
+            DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        )
+
+        assertThat(latest).isEqualTo(true)
+    }
 
     @Test
-    fun firstMobileSubShowingNetworkTypeIcon_updatesAsSubUpdates() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job =
-                underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun firstMobileSubShowingNetworkTypeIcon_subListUpdates_valAlsoUpdates() = runTest {
+        val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
 
-            interactor.filteredSubscriptions.value = listOf(SUB_1)
-            val sub1Interactor = interactor.getInteractorForSubId(1)!!
+        mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+            TelephonyIcons.UNKNOWN
+        )
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
 
-            sub1Interactor.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
-            assertThat(latest).isTrue()
+        val repo1 =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_1.subscriptionId]!!
 
-            sub1Interactor.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
-            assertThat(latest).isFalse()
+        repo1.dataConnectionState.setValue(DataConnectionState.Connected)
+        repo1.resolvedNetworkType.setValue(UnknownNetworkType)
 
-            sub1Interactor.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.LTE)
-            assertThat(latest).isTrue()
+        val repo2 =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_2.subscriptionId]!!
 
-            job.cancel()
-        }
+        repo2.dataConnectionState.setValue(DataConnectionState.Connected)
+        repo2.resolvedNetworkType.setValue(
+            DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        )
+
+        assertThat(latest).isEqualTo(true)
+
+        // WHEN the sub list gets new subscriptions where the last subscription is not showing
+        // the network type icon
+        setSubscriptions(listOf(SUB_1, SUB_2, SUB_3))
+
+        val repo3 =
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_3.subscriptionId]!!
+
+        repo3.dataConnectionState.setValue(DataConnectionState.Connected)
+        repo3.resolvedNetworkType.setValue(UnknownNetworkType)
+
+        // THEN the flow updates
+        assertThat(latest).isEqualTo(false)
+    }
 
     @Test
-    fun firstMobileSubShowingNetworkTypeIcon_multipleSubs_lastSubNotShowingRat_false() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job =
-                underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+    fun firstMobileSubShowingNetworkTypeIcon_subListReorders_valAlsoUpdates() = runTest {
+        val latest by underTest.firstMobileSubShowingNetworkTypeIcon.collectLastValue()
 
-            interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
-            interactor.getInteractorForSubId(1)?.networkTypeIconGroup?.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
-            interactor.getInteractorForSubId(2)!!.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
+        mobileConnectionsRepositoryKairos.fake.defaultMobileIconGroup.setValue(
+            TelephonyIcons.UNKNOWN
+        )
+        mobileConnectionsRepositoryKairos.fake.mobileIsDefault.setValue(true)
 
-            assertThat(latest).isFalse()
+        setSubscriptions(listOf(SUB_1, SUB_2))
+        // Immediately switch the order so that we've created both interactors
+        setSubscriptions(listOf(SUB_2, SUB_1))
 
-            job.cancel()
-        }
+        val repos = mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId.sample()
+        val repo1 = repos[SUB_1.subscriptionId]!!
+        repo1.dataConnectionState.setValue(DataConnectionState.Connected)
 
-    @Test
-    fun firstMobileSubShowingNetworkTypeIcon_multipleSubs_lastSubShowingRat_true() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job =
-                underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+        val repo2 = repos[SUB_2.subscriptionId]!!
+        repo2.dataConnectionState.setValue(DataConnectionState.Connected)
 
-            interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
-            interactor.getInteractorForSubId(1)?.networkTypeIconGroup?.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
-            interactor.getInteractorForSubId(2)!!.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
+        setSubscriptions(listOf(SUB_1, SUB_2))
+        repo1.resolvedNetworkType.setValue(UnknownNetworkType)
+        repo2.resolvedNetworkType.setValue(
+            DefaultNetworkType(mobileConnectionsRepositoryKairos.fake.GSM_KEY)
+        )
 
-            assertThat(latest).isTrue()
-            job.cancel()
-        }
+        assertThat(latest).isEqualTo(true)
 
-    @Test
-    fun firstMobileSubShowingNetworkTypeIcon_subListUpdates_valAlsoUpdates() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job =
-                underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
+        // WHEN sub1 becomes last and sub1 has no network type icon
+        setSubscriptions(listOf(SUB_2, SUB_1))
 
-            interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
-            interactor.getInteractorForSubId(1)?.networkTypeIconGroup?.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
-            interactor.getInteractorForSubId(2)!!.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
+        // THEN the flow updates
+        assertThat(latest).isEqualTo(false)
 
-            assertThat(latest).isTrue()
+        // WHEN sub2 becomes last and sub2 has a network type icon
+        setSubscriptions(listOf(SUB_1, SUB_2))
 
-            // WHEN the sub list gets new subscriptions where the last subscription is not showing
-            // the network type icon
-            interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2, SUB_3)
-            interactor.getInteractorForSubId(3)!!.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
-
-            // THEN the flow updates
-            assertThat(latest).isFalse()
-
-            job.cancel()
-        }
-
-    @Test
-    fun firstMobileSubShowingNetworkTypeIcon_subListReorders_valAlsoUpdates() =
-        testScope.runTest {
-            var latest: Boolean? = null
-            val job =
-                underTest.firstMobileSubShowingNetworkTypeIcon.onEach { latest = it }.launchIn(this)
-
-            interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
-            // Immediately switch the order so that we've created both interactors
-            interactor.filteredSubscriptions.value = listOf(SUB_2, SUB_1)
-            val sub1Interactor = interactor.getInteractorForSubId(1)!!
-            val sub2Interactor = interactor.getInteractorForSubId(2)!!
-
-            interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
-            sub1Interactor.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.UNKNOWN)
-            sub2Interactor.networkTypeIconGroup.value =
-                NetworkTypeIconModel.DefaultIcon(TelephonyIcons.THREE_G)
-            assertThat(latest).isTrue()
-
-            // WHEN sub1 becomes last and sub1 has no network type icon
-            interactor.filteredSubscriptions.value = listOf(SUB_2, SUB_1)
-
-            // THEN the flow updates
-            assertThat(latest).isFalse()
-
-            // WHEN sub2 becomes last and sub2 has a network type icon
-            interactor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
-
-            // THEN the flow updates
-            assertThat(latest).isTrue()
-
-            job.cancel()
-        }
+        // THEN the flow updates
+        assertThat(latest).isEqualTo(true)
+    }
 
     companion object {
         private val SUB_1 =
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt
index ce35d9d..75f5cbb 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosTest.kt
@@ -21,81 +21,83 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.flags.Flags
+import com.android.systemui.flags.fake
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.KairosTestScope
+import com.android.systemui.kairos.runKairosTest
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.kosmos.runTest
-import com.android.systemui.kosmos.testScope
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
-import com.android.systemui.lifecycle.activateIn
 import com.android.systemui.statusbar.core.NewStatusBarIcons
 import com.android.systemui.statusbar.core.StatusBarRootModernization
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.fakeMobileIconsInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fake
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.fakeMobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.mobileConnectionsRepositoryKairos
 import com.android.systemui.testKosmos
 import com.google.common.truth.Truth.assertThat
-import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 
+@OptIn(ExperimentalKairosApi::class)
 @SmallTest
 @RunWith(AndroidJUnit4::class)
 class StackedMobileIconViewModelKairosTest : SysuiTestCase() {
-    private val kosmos = testKosmos().useUnconfinedTestDispatcher()
-    private val testScope = kosmos.testScope
+    private val kosmos =
+        testKosmos().useUnconfinedTestDispatcher().apply {
+            mobileConnectionsRepositoryKairos = fakeMobileConnectionsRepositoryKairos
+            featureFlagsClassic.fake.apply {
+                setDefault(Flags.FILTER_PROVISIONING_NETWORK_SUBSCRIPTIONS)
+            }
+        }
 
-    private val Kosmos.underTest: StackedMobileIconViewModelKairos by Fixture {
-        stackedMobileIconViewModelKairos
-    }
-
-    @Before
-    fun setUp() {
-        kosmos.underTest.activateIn(testScope)
-    }
+    private val Kosmos.underTest
+        get() = stackedMobileIconViewModelKairos
 
     @Test
     @EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
     fun dualSim_filtersOutNonDualConnections() =
-        kosmos.runTest {
-            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf()
+        kosmos.runKairosTest {
+            mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf())
             assertThat(underTest.dualSim).isNull()
 
-            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1)
+            mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1))
             assertThat(underTest.dualSim).isNull()
 
-            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2, SUB_3)
+            mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(
+                listOf(SUB_1, SUB_2, SUB_3)
+            )
             assertThat(underTest.dualSim).isNull()
 
-            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
+            mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1, SUB_2))
             assertThat(underTest.dualSim).isNotNull()
         }
 
     @Test
     @EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
     fun dualSim_filtersOutNonCellularIcons() =
-        kosmos.runTest {
-            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1)
+        kosmos.runKairosTest {
+            mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1))
             assertThat(underTest.dualSim).isNull()
 
-            fakeMobileIconsInteractor
-                .getInteractorForSubId(SUB_1.subscriptionId)!!
-                .signalLevelIcon
-                .value =
-                SignalIconModel.Satellite(
-                    level = 0,
-                    icon = Icon.Resource(res = 0, contentDescription = null),
-                )
-            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
+            mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId
+                .sample()[SUB_1.subscriptionId]!!
+                .apply {
+                    isNonTerrestrial.setValue(true)
+                    satelliteLevel.setValue(0)
+                }
+
+            mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1, SUB_2))
             assertThat(underTest.dualSim).isNull()
         }
 
     @Test
     @EnableFlags(NewStatusBarIcons.FLAG_NAME, StatusBarRootModernization.FLAG_NAME)
     fun dualSim_tracksActiveSubId() =
-        kosmos.runTest {
+        kosmos.runKairosTest {
             // Active sub id is null, order is unchanged
-            fakeMobileIconsInteractor.filteredSubscriptions.value = listOf(SUB_1, SUB_2)
+            mobileConnectionsRepositoryKairos.fake.subscriptions.setValue(listOf(SUB_1, SUB_2))
             setIconLevel(SUB_1.subscriptionId, 1)
             setIconLevel(SUB_2.subscriptionId, 2)
 
@@ -103,16 +105,21 @@
             assertThat(underTest.dualSim!!.secondary.level).isEqualTo(2)
 
             // Active sub is 2, order is swapped
-            fakeMobileIconsInteractor.activeMobileDataSubscriptionId.value = SUB_2.subscriptionId
+            mobileConnectionsRepositoryKairos.fake.setActiveMobileDataSubscriptionId(
+                SUB_2.subscriptionId
+            )
 
             assertThat(underTest.dualSim!!.primary.level).isEqualTo(2)
             assertThat(underTest.dualSim!!.secondary.level).isEqualTo(1)
         }
 
-    private fun setIconLevel(subId: Int, level: Int) {
-        with(kosmos.fakeMobileIconsInteractor.getInteractorForSubId(subId)!!) {
-            signalLevelIcon.value =
-                (signalLevelIcon.value as SignalIconModel.Cellular).copy(level = level)
+    private suspend fun KairosTestScope.setIconLevel(subId: Int, level: Int) {
+        mobileConnectionsRepositoryKairos.fake.mobileConnectionsBySubId.sample()[subId]!!.apply {
+            isNonTerrestrial.setValue(false)
+            isInService.setValue(true)
+            inflateSignalStrength.setValue(false)
+            isGsm.setValue(true)
+            primaryLevel.setValue(level)
         }
     }
 
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt
index d7bcf88..8a7b698 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelTest.kt
@@ -45,8 +45,8 @@
     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
     private val testScope = kosmos.testScope
 
-    private val Kosmos.underTest: StackedMobileIconViewModel by Fixture {
-        stackedMobileIconViewModel
+    private val Kosmos.underTest: StackedMobileIconViewModelImpl by Fixture {
+        stackedMobileIconViewModelImpl
     }
 
     @Before
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
index 91b3896..39cf02d 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/FakeHomeStatusBarViewModel.kt
@@ -54,9 +54,7 @@
         MutableStateFlow(OngoingActivityChipModel.Inactive())
 
     override val ongoingActivityChips =
-        MutableStateFlow(
-            ChipsVisibilityModel(MultipleOngoingActivityChipsModel(), areChipsAllowed = false)
-        )
+        ChipsVisibilityModel(MultipleOngoingActivityChipsModel(), areChipsAllowed = false)
 
     override val ongoingActivityChipsLegacy =
         MutableStateFlow(MultipleOngoingActivityChipsModelLegacy())
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
index 2da692b..20cf3ae 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModelImplTest.kt
@@ -49,6 +49,7 @@
 import com.android.systemui.kosmos.runTest
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.kosmos.useUnconfinedTestDispatcher
+import com.android.systemui.lifecycle.activateIn
 import com.android.systemui.log.assertLogsWtf
 import com.android.systemui.mediaprojection.data.model.MediaProjectionState
 import com.android.systemui.mediaprojection.data.repository.fakeMediaProjectionRepository
@@ -107,7 +108,8 @@
 @RunWith(AndroidJUnit4::class)
 class HomeStatusBarViewModelImplTest : SysuiTestCase() {
     private val kosmos = testKosmos().useUnconfinedTestDispatcher()
-    private val Kosmos.underTest by Kosmos.Fixture { kosmos.homeStatusBarViewModel }
+    private val Kosmos.underTest by
+        Kosmos.Fixture { kosmos.homeStatusBarViewModel.also { it.activateIn(kosmos.testScope) } }
 
     @Before
     fun setUp() {
@@ -891,32 +893,26 @@
     @EnableChipsModernization
     fun ongoingActivityChips_statusBarHidden_noSecureCamera_noHun_notAllowed() =
         kosmos.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChips)
-
             // home status bar not allowed
             kosmos.sceneContainerRepository.snapToScene(Scenes.Lockscreen)
             kosmos.keyguardOcclusionRepository.setShowWhenLockedActivityInfo(false, taskInfo = null)
 
-            assertThat(latest!!.areChipsAllowed).isFalse()
+            assertThat(underTest.ongoingActivityChips.areChipsAllowed).isFalse()
         }
 
     @Test
     @EnableChipsModernization
     fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_noHun_isAllowed() =
         kosmos.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChips)
-
             transitionKeyguardToGone()
 
-            assertThat(latest!!.areChipsAllowed).isTrue()
+            assertThat(underTest.ongoingActivityChips.areChipsAllowed).isTrue()
         }
 
     @Test
     @EnableChipsModernization
     fun ongoingActivityChips_statusBarNotHidden_secureCamera_noHun_notAllowed() =
         kosmos.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChips)
-
             fakeKeyguardTransitionRepository.sendTransitionSteps(
                 from = KeyguardState.LOCKSCREEN,
                 to = KeyguardState.OCCLUDED,
@@ -924,7 +920,7 @@
             )
             kosmos.keyguardInteractor.onCameraLaunchDetected(CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP)
 
-            assertThat(latest!!.areChipsAllowed).isFalse()
+            assertThat(underTest.ongoingActivityChips.areChipsAllowed).isFalse()
         }
 
     @Test
@@ -932,8 +928,6 @@
     @EnableChipsModernization
     fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOff_notAllowed() =
         kosmos.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChips)
-
             transitionKeyguardToGone()
 
             headsUpNotificationRepository.setNotifications(
@@ -943,7 +937,7 @@
                 )
             )
 
-            assertThat(latest!!.areChipsAllowed).isFalse()
+            assertThat(underTest.ongoingActivityChips.areChipsAllowed).isFalse()
         }
 
     @Test
@@ -951,8 +945,6 @@
     @EnableChipsModernization
     fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOff_isAllowed() =
         kosmos.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChips)
-
             transitionKeyguardToGone()
 
             headsUpNotificationRepository.setNotifications(
@@ -962,16 +954,14 @@
                 )
             )
 
-            assertThat(latest!!.areChipsAllowed).isTrue()
+            assertThat(underTest.ongoingActivityChips.areChipsAllowed).isTrue()
         }
 
     @Test
     @EnableFlags(StatusBarNoHunBehavior.FLAG_NAME)
     @EnableChipsModernization
-    fun ongoingActivityChips_tatusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_isAllowed() =
+    fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunBySystem_noHunFlagOn_isAllowed() =
         kosmos.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChips)
-
             transitionKeyguardToGone()
 
             headsUpNotificationRepository.setNotifications(
@@ -981,7 +971,7 @@
                 )
             )
 
-            assertThat(latest!!.areChipsAllowed).isTrue()
+            assertThat(underTest.ongoingActivityChips.areChipsAllowed).isTrue()
         }
 
     @Test
@@ -989,8 +979,6 @@
     @EnableChipsModernization
     fun ongoingActivityChips_statusBarNotHidden_noSecureCamera_hunByUser_noHunFlagOn_isAllowed() =
         kosmos.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChips)
-
             transitionKeyguardToGone()
 
             headsUpNotificationRepository.setNotifications(
@@ -1000,7 +988,7 @@
                 )
             )
 
-            assertThat(latest!!.areChipsAllowed).isTrue()
+            assertThat(underTest.ongoingActivityChips.areChipsAllowed).isTrue()
         }
 
     @Test
@@ -1008,17 +996,16 @@
     @EnableChipsModernization
     fun ongoingActivityChips_followsChipsViewModel() =
         kosmos.runTest {
-            val latest by collectLastValue(underTest.ongoingActivityChips)
             transitionKeyguardToGone()
 
             screenRecordRepository.screenRecordState.value = ScreenRecordModel.Recording
 
-            assertIsScreenRecordChip(latest!!.chips.active[0])
+            assertIsScreenRecordChip(underTest.ongoingActivityChips.chips.active[0])
 
             addOngoingCallState(key = "call")
 
-            assertIsScreenRecordChip(latest!!.chips.active[0])
-            assertIsCallChip(latest!!.chips.active[1], "call", context)
+            assertIsScreenRecordChip(underTest.ongoingActivityChips.chips.active[0])
+            assertIsCallChip(underTest.ongoingActivityChips.chips.active[1], "call", context)
         }
 
     @Test
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
index 92bec70..18a124c 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/DisplaySwitchLatencyTrackerTest.kt
@@ -38,7 +38,6 @@
 import com.android.systemui.display.data.repository.fakeDeviceStateRepository
 import com.android.systemui.foldedDeviceStateList
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAwakeForTest
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setScreenPowerState
@@ -47,6 +46,7 @@
 import com.android.systemui.power.shared.model.ScreenPowerState.SCREEN_ON
 import com.android.systemui.shared.system.SysUiStatsLog
 import com.android.systemui.statusbar.policy.FakeConfigurationController
+import com.android.systemui.testKosmos
 import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.COOL_DOWN_DURATION
 import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.FOLDABLE_DEVICE_STATE_CLOSED
 import com.android.systemui.unfold.DisplaySwitchLatencyTracker.Companion.FOLDABLE_DEVICE_STATE_HALF_OPEN
@@ -89,7 +89,7 @@
     private lateinit var displaySwitchLatencyTracker: DisplaySwitchLatencyTracker
     @Captor private lateinit var loggerArgumentCaptor: ArgumentCaptor<DisplaySwitchLatencyEvent>
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val mockContext = mock<Context>()
     private val resources = mock<Resources>()
     private val foldStateRepository = kosmos.fakeDeviceStateRepository
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
index dfc4d0f..98d99f7 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/unfold/FoldLightRevealOverlayAnimationTest.kt
@@ -28,7 +28,6 @@
 import com.android.systemui.animation.AnimatorTestRule
 import com.android.systemui.display.data.repository.DeviceStateRepository.DeviceState
 import com.android.systemui.display.data.repository.fakeDeviceStateRepository
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.power.domain.interactor.PowerInteractor.Companion.setAsleepForTest
@@ -36,6 +35,7 @@
 import com.android.systemui.power.domain.interactor.powerInteractor
 import com.android.systemui.power.shared.model.ScreenPowerState
 import com.android.systemui.statusbar.LightRevealScrim
+import com.android.systemui.testKosmos
 import com.android.systemui.util.animation.data.repository.fakeAnimationStatusRepository
 import kotlinx.coroutines.test.TestScope
 import kotlinx.coroutines.test.advanceTimeBy
@@ -61,7 +61,7 @@
 class FoldLightRevealOverlayAnimationTest : SysuiTestCase() {
     @get:Rule val animatorTestRule = AnimatorTestRule(this)
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val testScope: TestScope = kosmos.testScope
     private val fakeDeviceStateRepository = kosmos.fakeDeviceStateRepository
     private val powerInteractor = kosmos.powerInteractor
@@ -93,7 +93,7 @@
                 fakeAnimationStatusRepository,
                 mockControllerFactory,
                 mockFoldLockSettingAvailabilityProvider,
-                mockJankMonitor
+                mockJankMonitor,
             )
         foldLightRevealAnimation.init()
     }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
index bafa8cf..da5622a 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/user/data/repository/UserRepositoryImplTest.kt
@@ -17,8 +17,10 @@
 
 package com.android.systemui.user.data.repository
 
+import android.app.admin.DevicePolicyManager
 import android.app.admin.devicePolicyManager
 import android.content.Intent
+import android.content.applicationContext
 import android.content.pm.UserInfo
 import android.internal.statusbar.fakeStatusBarService
 import android.os.UserHandle
@@ -77,10 +79,7 @@
     fun setUp() {
         MockitoAnnotations.initMocks(this)
         tracker = FakeUserTracker()
-        context.orCreateTestableResources.addOverride(
-            R.bool.config_userSwitchingMustGoThroughLoginScreen,
-            false,
-        )
+        setUserSwitchingMustGoThroughLoginScreen(false)
     }
 
     @Test
@@ -308,6 +307,117 @@
             job.cancel()
         }
 
+    @Test
+    fun isSecondaryUserLogoutEnabled_secondaryLogoutDisabled_alwaysFalse() =
+        testScope.runTest {
+            underTest = create(testScope.backgroundScope)
+            mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT)
+            setSecondaryUserLogoutEnabled(false)
+            setUpUsers(count = 2, selectedIndex = 0)
+            tracker.onProfileChanged()
+
+            val secondaryUserLogoutEnabled by
+                collectLastValue(underTest.isSecondaryUserLogoutEnabled)
+
+            assertThat(secondaryUserLogoutEnabled).isFalse()
+
+            setUpUsers(count = 2, selectedIndex = 1)
+            tracker.onProfileChanged()
+            assertThat(secondaryUserLogoutEnabled).isFalse()
+        }
+
+    @Test
+    fun isSecondaryUserLogoutEnabled_secondaryLogoutEnabled_NullLogoutUser_alwaysFalse() =
+        testScope.runTest {
+            underTest = create(testScope.backgroundScope)
+            mockLogoutUser(LogoutUserResult.NONE)
+            setSecondaryUserLogoutEnabled(true)
+            setUpUsers(count = 2, selectedIndex = 0)
+            tracker.onProfileChanged()
+
+            val secondaryUserLogoutEnabled by
+                collectLastValue(underTest.isSecondaryUserLogoutEnabled)
+
+            assertThat(secondaryUserLogoutEnabled).isFalse()
+
+            setUpUsers(count = 2, selectedIndex = 1)
+            tracker.onProfileChanged()
+            assertThat(secondaryUserLogoutEnabled).isFalse()
+        }
+
+    @Test
+    fun isSecondaryUserLogoutEnabled_secondaryLogoutEnabled_NonSystemLogoutUser_trueWhenNonSystem() =
+        testScope.runTest {
+            underTest = create(testScope.backgroundScope)
+            mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT)
+            setSecondaryUserLogoutEnabled(true)
+            setUpUsers(count = 2, selectedIndex = 0)
+            tracker.onProfileChanged()
+
+            val secondaryUserLogoutEnabled by
+                collectLastValue(underTest.isSecondaryUserLogoutEnabled)
+
+            assertThat(secondaryUserLogoutEnabled).isFalse()
+
+            setUpUsers(count = 2, selectedIndex = 1)
+            tracker.onProfileChanged()
+            assertThat(secondaryUserLogoutEnabled).isTrue()
+        }
+
+    @Test
+    fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenDisabled_alwaysFalse() =
+        testScope.runTest {
+            underTest = create(testScope.backgroundScope)
+            mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT)
+            setUserSwitchingMustGoThroughLoginScreen(false)
+            setUpUsers(count = 2, selectedIndex = 0)
+            tracker.onProfileChanged()
+
+            val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled)
+
+            assertThat(logoutToSystemUserEnabled).isFalse()
+
+            setUpUsers(count = 2, selectedIndex = 1)
+            tracker.onProfileChanged()
+            assertThat(logoutToSystemUserEnabled).isFalse()
+        }
+
+    @Test
+    fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenEnabled_NullLogoutUser_alwaysFalse() =
+        testScope.runTest {
+            underTest = create(testScope.backgroundScope)
+            mockLogoutUser(LogoutUserResult.NONE)
+            setUserSwitchingMustGoThroughLoginScreen(true)
+            setUpUsers(count = 2, selectedIndex = 0)
+            tracker.onProfileChanged()
+
+            val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled)
+
+            assertThat(logoutToSystemUserEnabled).isFalse()
+
+            setUpUsers(count = 2, selectedIndex = 1)
+            tracker.onProfileChanged()
+            assertThat(logoutToSystemUserEnabled).isFalse()
+        }
+
+    @Test
+    fun isLogoutToSystemUserEnabled_logoutThroughLoginScreenEnabled_NonSystemLogoutUser_trueWhenNonSystem() =
+        testScope.runTest {
+            underTest = create(testScope.backgroundScope)
+            mockLogoutUser(LogoutUserResult.NON_SYSTEM_CURRENT)
+            setUserSwitchingMustGoThroughLoginScreen(true)
+            setUpUsers(count = 2, selectedIndex = 0)
+            tracker.onProfileChanged()
+
+            val logoutToSystemUserEnabled by collectLastValue(underTest.isLogoutToSystemUserEnabled)
+
+            assertThat(logoutToSystemUserEnabled).isFalse()
+
+            setUpUsers(count = 2, selectedIndex = 1)
+            tracker.onProfileChanged()
+            assertThat(logoutToSystemUserEnabled).isTrue()
+        }
+
     private fun createUserInfo(id: Int, isGuest: Boolean): UserInfo {
         val flags = 0
         return UserInfo(
@@ -354,6 +464,38 @@
         assertThat(model.isUserSwitcherEnabled).isEqualTo(expectedUserSwitcherEnabled)
     }
 
+    private fun setSecondaryUserLogoutEnabled(enabled: Boolean) {
+        whenever(devicePolicyManager.isLogoutEnabled).thenReturn(enabled)
+        broadcastDispatcher.sendIntentToMatchingReceiversOnly(
+            kosmos.applicationContext,
+            Intent(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
+        )
+    }
+
+    private fun setUserSwitchingMustGoThroughLoginScreen(enabled: Boolean) {
+        context.orCreateTestableResources.addOverride(
+            R.bool.config_userSwitchingMustGoThroughLoginScreen,
+            enabled,
+        )
+    }
+
+    private fun mockLogoutUser(result: LogoutUserResult) {
+        when (result) {
+            LogoutUserResult.NONE -> {
+                whenever(devicePolicyManager.logoutUser).thenReturn(null)
+            }
+            LogoutUserResult.NON_SYSTEM_CURRENT -> {
+                whenever(devicePolicyManager.logoutUser).thenAnswer {
+                    if (tracker.userHandle != UserHandle.SYSTEM) {
+                        tracker.userHandle
+                    } else {
+                        null
+                    }
+                }
+            }
+        }
+    }
+
     private fun create(scope: CoroutineScope): UserRepositoryImpl {
         return UserRepositoryImpl(
             appContext = context,
@@ -373,4 +515,9 @@
     companion object {
         @JvmStatic private val IMMEDIATE = Dispatchers.Main.immediate
     }
+
+    private enum class LogoutUserResult {
+        NONE,
+        NON_SYSTEM_CURRENT,
+    }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/UtilsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/UtilsTest.kt
index b4ba41a..a180d51 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/UtilsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/UtilsTest.kt
@@ -27,7 +27,7 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.deviceStateManager
-import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.testKosmos
 import junit.framework.Assert.assertFalse
 import junit.framework.Assert.assertTrue
 import org.junit.Before
@@ -39,7 +39,7 @@
 @RunWith(AndroidJUnit4::class)
 class UtilsTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
     private val deviceStateManager = kosmos.deviceStateManager
     private lateinit var testableResources: TestableResources
 
@@ -53,7 +53,7 @@
     fun isFoldableReturnsFalse_overlayConfigurationValues() {
         testableResources.addOverride(
             com.android.internal.R.array.config_foldedDeviceStates,
-            intArrayOf() // empty array <=> device is not foldable
+            intArrayOf(), // empty array <=> device is not foldable
         )
         whenever(deviceStateManager.supportedDeviceStates).thenReturn(listOf(DEFAULT_DEVICE_STATE))
         assertFalse(Utils.isDeviceFoldable(testableResources.resources, deviceStateManager))
@@ -64,7 +64,7 @@
     fun isFoldableReturnsFalse_deviceStateManager() {
         testableResources.addOverride(
             com.android.internal.R.array.config_foldedDeviceStates,
-            intArrayOf() // empty array <=> device is not foldable
+            intArrayOf(), // empty array <=> device is not foldable
         )
         whenever(deviceStateManager.supportedDeviceStates).thenReturn(listOf(DEFAULT_DEVICE_STATE))
         assertFalse(Utils.isDeviceFoldable(testableResources.resources, deviceStateManager))
@@ -75,7 +75,7 @@
     fun isFoldableReturnsTrue_overlayConfigurationValues() {
         testableResources.addOverride(
             com.android.internal.R.array.config_foldedDeviceStates,
-            intArrayOf(FOLDED_DEVICE_STATE.identifier)
+            intArrayOf(FOLDED_DEVICE_STATE.identifier),
         )
         whenever(deviceStateManager.supportedDeviceStates)
             .thenReturn(listOf(FOLDED_DEVICE_STATE, UNFOLDED_DEVICE_STATE))
@@ -87,7 +87,7 @@
     fun isFoldableReturnsTrue_deviceStateManager() {
         testableResources.addOverride(
             com.android.internal.R.array.config_foldedDeviceStates,
-            intArrayOf(FOLDED_DEVICE_STATE.identifier)
+            intArrayOf(FOLDED_DEVICE_STATE.identifier),
         )
         whenever(deviceStateManager.supportedDeviceStates)
             .thenReturn(listOf(FOLDED_DEVICE_STATE, UNFOLDED_DEVICE_STATE))
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt
index 04ab988..b1a3caf 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelTest.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel
 
 import android.bluetooth.BluetoothDevice
+import android.graphics.drawable.TestStubDrawable
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
@@ -63,6 +64,12 @@
 
             assertThat(audioSharingSlider!!.label).isEqualTo("my headset 2")
             assertThat(audioSharingSlider!!.icon)
-                .isEqualTo(Icon.Resource(R.drawable.ic_volume_media_bt, null))
+                .isEqualTo(
+                    Icon.Loaded(
+                        drawable = TestStubDrawable(),
+                        res = R.drawable.ic_volume_media_bt,
+                        contentDescription = null,
+                    )
+                )
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelTest.kt
index 9e8cde3..ffe8e92 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelTest.kt
@@ -18,6 +18,7 @@
 
 import android.app.Flags
 import android.app.NotificationManager.INTERRUPTION_FILTER_NONE
+import android.graphics.drawable.TestStubDrawable
 import android.media.AudioManager
 import android.platform.test.annotations.EnableFlags
 import android.service.notification.ZenPolicy
@@ -28,7 +29,6 @@
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
 import com.android.systemui.kosmos.collectLastValue
@@ -39,8 +39,6 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.volume.data.repository.audioSharingRepository
 import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.test.runCurrent
-import kotlinx.coroutines.test.runTest
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.kotlin.mock
@@ -173,6 +171,12 @@
 
             assertThat(mediaSlider!!.label).isEqualTo("my headset 1")
             assertThat(mediaSlider!!.icon)
-                .isEqualTo(Icon.Resource(R.drawable.ic_volume_media_bt, null))
+                .isEqualTo(
+                    Icon.Loaded(
+                        drawable = TestStubDrawable(),
+                        res = R.drawable.ic_volume_media_bt,
+                        contentDescription = null,
+                    )
+                )
         }
 }
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt
index f232d52..93e5721 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/volume/panel/domain/interactor/ComponentsInteractorImplTest.kt
@@ -20,8 +20,8 @@
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.coroutines.collectLastValue
-import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
 import com.android.systemui.volume.panel.domain.availableCriteria
 import com.android.systemui.volume.panel.domain.defaultCriteria
 import com.android.systemui.volume.panel.domain.model.ComponentModel
@@ -39,7 +39,7 @@
 @RunWith(AndroidJUnit4::class)
 class ComponentsInteractorImplTest : SysuiTestCase() {
 
-    private val kosmos = Kosmos()
+    private val kosmos = testKosmos()
 
     private lateinit var underTest: ComponentsInteractor
 
@@ -60,12 +60,7 @@
     fun componentsAvailability_checked() {
         with(kosmos) {
             testScope.runTest {
-                enabledComponents =
-                    setOf(
-                        BOTTOM_BAR,
-                        COMPONENT_1,
-                        COMPONENT_2,
-                    )
+                enabledComponents = setOf(BOTTOM_BAR, COMPONENT_1, COMPONENT_2)
                 criteriaByKey =
                     mapOf(
                         BOTTOM_BAR to Provider { availableCriteria },
@@ -90,12 +85,7 @@
     fun noCriteria_fallbackToDefaultCriteria() {
         with(kosmos) {
             testScope.runTest {
-                enabledComponents =
-                    setOf(
-                        BOTTOM_BAR,
-                        COMPONENT_1,
-                        COMPONENT_2,
-                    )
+                enabledComponents = setOf(BOTTOM_BAR, COMPONENT_1, COMPONENT_2)
                 criteriaByKey =
                     mapOf(
                         BOTTOM_BAR to Provider { availableCriteria },
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt
index 235475f..0fc3470 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockEvents.kt
@@ -44,5 +44,5 @@
     fun onZenDataChanged(data: ZenData)
 
     /** Update reactive axes for this clock */
-    fun onFontAxesChanged(axes: List<ClockFontAxisSetting>)
+    fun onFontAxesChanged(axes: ClockAxisStyle)
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
index 0cbc30d..2147ca1 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockPickerConfig.kt
@@ -35,10 +35,54 @@
     /** Font axes that can be modified on this clock */
     val axes: List<ClockFontAxis> = listOf(),
 
-    /** List of font presets for this clock. Can be assigned directly. */
-    val axisPresets: List<List<ClockFontAxisSetting>> = listOf(),
+    /** Presets for this clock. Null indicates the preset list should be disabled. */
+    val presetConfig: AxisPresetConfig? = null,
 )
 
+data class AxisPresetConfig(
+    /** Groups of Presets. Each group can be used together in a single control. */
+    val groups: List<Group>,
+
+    /** Preset item currently being used, null when the current style is not a preset */
+    val current: IndexedStyle? = null,
+) {
+    /** The selected clock axis style, and its indices */
+    data class IndexedStyle(
+        /** Index of the group that this clock axis style appears in */
+        val groupIndex: Int,
+
+        /** Index of the preset within the group */
+        val presetIndex: Int,
+
+        /** Reference to the style in question */
+        val style: ClockAxisStyle,
+    )
+
+    /** A group of preset styles */
+    data class Group(
+        /* List of preset styles in this group */
+        val presets: List<ClockAxisStyle>,
+
+        /* Icon to use when this preset-group is active */
+        val icon: Drawable,
+    )
+
+    fun findStyle(style: ClockAxisStyle): IndexedStyle? {
+        groups.forEachIndexed { groupIndex, group ->
+            group.presets.forEachIndexed { presetIndex, preset ->
+                if (preset == style) {
+                    return@findStyle IndexedStyle(
+                        groupIndex = groupIndex,
+                        presetIndex = presetIndex,
+                        style = preset,
+                    )
+                }
+            }
+        }
+        return null
+    }
+}
+
 /** Represents an Axis that can be modified */
 data class ClockFontAxis(
     /** Axis key, not user renderable */
@@ -62,19 +106,12 @@
     /** Description of the axis */
     val description: String,
 ) {
-    fun toSetting() = ClockFontAxisSetting(key, currentValue)
-
     companion object {
-        fun List<ClockFontAxis>.merge(
-            axisSettings: List<ClockFontAxisSetting>
-        ): List<ClockFontAxis> {
-            val result = mutableListOf<ClockFontAxis>()
-            for (axis in this) {
-                val setting = axisSettings.firstOrNull { axis.key == it.key }
-                val output = setting?.let { axis.copy(currentValue = it.value) } ?: axis
-                result.add(output)
-            }
-            return result
+        fun List<ClockFontAxis>.merge(axisStyle: ClockAxisStyle): List<ClockFontAxis> {
+            return this.map { axis ->
+                    axisStyle.get(axis.key)?.let { axis.copy(currentValue = it) } ?: axis
+                }
+                .toList()
         }
     }
 }
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
index e7b3662..cccc558 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/clocks/ClockSettings.kt
@@ -22,7 +22,7 @@
 data class ClockSettings(
     val clockId: ClockId? = null,
     val seedColor: Int? = null,
-    val axes: List<ClockFontAxisSetting> = listOf(),
+    val axes: ClockAxisStyle = ClockAxisStyle(),
 ) {
     // Exclude metadata from equality checks
     var metadata: JSONObject = JSONObject()
@@ -38,15 +38,15 @@
                 put(KEY_CLOCK_ID, setting.clockId)
                 put(KEY_SEED_COLOR, setting.seedColor)
                 put(KEY_METADATA, setting.metadata)
-                put(KEY_AXIS_LIST, ClockFontAxisSetting.toJson(setting.axes))
+                put(KEY_AXIS_LIST, ClockAxisStyle.toJson(setting.axes))
             }
         }
 
         fun fromJson(json: JSONObject): ClockSettings {
             val clockId = if (!json.isNull(KEY_CLOCK_ID)) json.getString(KEY_CLOCK_ID) else null
             val seedColor = if (!json.isNull(KEY_SEED_COLOR)) json.getInt(KEY_SEED_COLOR) else null
-            val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockFontAxisSetting::fromJson)
-            return ClockSettings(clockId, seedColor, axisList ?: listOf()).apply {
+            val axisList = json.optJSONArray(KEY_AXIS_LIST)?.let(ClockAxisStyle::fromJson)
+            return ClockSettings(clockId, seedColor, axisList ?: ClockAxisStyle()).apply {
                 metadata = json.optJSONObject(KEY_METADATA) ?: JSONObject()
             }
         }
@@ -54,64 +54,102 @@
 }
 
 @Keep
-/** Axis setting value for a clock */
-data class ClockFontAxisSetting(
-    /** Axis key; matches ClockFontAxis.key */
-    val key: String,
+class ClockAxisStyle {
+    private val settings: MutableMap<String, Float>
 
-    /** Value to set this axis to */
-    val value: Float,
-) {
+    // Iterable would be implemented on ClockAxisStyle directly,
+    // but that doesn't appear to work with plugins/dynamic libs.
+    val items: Iterable<Map.Entry<String, Float>>
+        get() = settings.asIterable()
+
+    val isEmpty: Boolean
+        get() = settings.isEmpty()
+
+    constructor(initialize: ClockAxisStyle.() -> Unit = {}) {
+        settings = mutableMapOf()
+        this.initialize()
+    }
+
+    constructor(style: ClockAxisStyle) {
+        settings = style.settings.toMutableMap()
+    }
+
+    constructor(items: Map<String, Float>) {
+        settings = items.toMutableMap()
+    }
+
+    constructor(key: String, value: Float) {
+        settings = mutableMapOf(key to value)
+    }
+
+    constructor(items: List<ClockFontAxis>) {
+        settings = items.associate { it.key to it.currentValue }.toMutableMap()
+    }
+
+    fun copy(initialize: ClockAxisStyle.() -> Unit): ClockAxisStyle {
+        return ClockAxisStyle(this).apply { initialize() }
+    }
+
+    operator fun get(key: String): Float? = settings[key]
+
+    operator fun set(key: String, value: Float) = put(key, value)
+
+    fun put(key: String, value: Float) {
+        settings.put(key, value)
+    }
+
+    fun toFVar(): String {
+        val sb = StringBuilder()
+        for (axis in settings) {
+            if (sb.length > 0) sb.append(", ")
+            sb.append("'${axis.key}' ${axis.value.toInt()}")
+        }
+        return sb.toString()
+    }
+
+    fun copyWith(replacements: ClockAxisStyle): ClockAxisStyle {
+        val result = ClockAxisStyle(this)
+        for ((key, value) in replacements.settings) {
+            result[key] = value
+        }
+        return result
+    }
+
+    override fun equals(other: Any?): Boolean {
+        if (this === other) return true
+        if (other !is ClockAxisStyle) return false
+        return settings == other.settings
+    }
+
     companion object {
         private val KEY_AXIS_KEY = "key"
         private val KEY_AXIS_VALUE = "value"
 
-        fun toJson(setting: ClockFontAxisSetting): JSONObject {
-            return JSONObject().apply {
-                put(KEY_AXIS_KEY, setting.key)
-                put(KEY_AXIS_VALUE, setting.value)
-            }
-        }
-
-        fun toJson(settings: List<ClockFontAxisSetting>): JSONArray {
-            return JSONArray().apply {
-                for (axis in settings) {
-                    put(toJson(axis))
-                }
-            }
-        }
-
-        fun fromJson(jsonObj: JSONObject): ClockFontAxisSetting {
-            return ClockFontAxisSetting(
-                key = jsonObj.getString(KEY_AXIS_KEY),
-                value = jsonObj.getDouble(KEY_AXIS_VALUE).toFloat(),
-            )
-        }
-
-        fun fromJson(jsonArray: JSONArray): List<ClockFontAxisSetting> {
-            val result = mutableListOf<ClockFontAxisSetting>()
+        fun fromJson(jsonArray: JSONArray): ClockAxisStyle {
+            val result = ClockAxisStyle()
             for (i in 0..jsonArray.length() - 1) {
                 val obj = jsonArray.getJSONObject(i)
                 if (obj == null) continue
-                result.add(fromJson(obj))
+
+                result.put(
+                    key = obj.getString(KEY_AXIS_KEY),
+                    value = obj.getDouble(KEY_AXIS_VALUE).toFloat(),
+                )
             }
             return result
         }
 
-        fun List<ClockFontAxisSetting>.toFVar(): String {
-            val sb = StringBuilder()
-            for (axis in this) {
-                if (sb.length > 0) sb.append(", ")
-                sb.append("'${axis.key}' ${axis.value.toInt()}")
+        fun toJson(style: ClockAxisStyle): JSONArray {
+            return JSONArray().apply {
+                for ((key, value) in style.settings) {
+                    put(
+                        JSONObject().apply {
+                            put(KEY_AXIS_KEY, key)
+                            put(KEY_AXIS_VALUE, value)
+                        }
+                    )
+                }
             }
-            return sb.toString()
-        }
-
-        fun List<ClockFontAxisSetting>.replace(
-            replacements: List<ClockFontAxisSetting>
-        ): List<ClockFontAxisSetting> {
-            var remaining = this.filterNot { lhs -> replacements.any { rhs -> lhs.key == rhs.key } }
-            return remaining + replacements
         }
     }
 }
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index fe6636b..15471a6 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -63,8 +63,8 @@
     <string name="kg_bio_try_again_or_password" msgid="1473132729225398039">"আবার চেষ্টা করুন বা পাসওয়ার্ড লিখুন"</string>
     <string name="kg_bio_try_again_or_pattern" msgid="4867893307468801501">"আবার চেষ্টা করুন বা প্যাটার্ন দিন"</string>
     <string name="kg_bio_too_many_attempts_pin" msgid="5850845723433047605">"অনেক বেশিবার চেষ্টা করার পরে পিন দিতে হবে"</string>
-    <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"অনেক বেশিবার চেষ্টা করার পরে পাসওয়ার্ড দিতে হবে"</string>
-    <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"অনেক বেশিবার চেষ্টা করার পরে প্যাটার্ন দিতে হবে"</string>
+    <string name="kg_bio_too_many_attempts_password" msgid="5551690347827728042">"অনেকবার চেষ্টা করার পর পাসওয়ার্ড দিতে হয়"</string>
+    <string name="kg_bio_too_many_attempts_pattern" msgid="736884689355181602">"অনেকবার চেষ্টা করার পর প্যাটার্ন দিতে হয়"</string>
     <string name="kg_unlock_with_pin_or_fp" msgid="5635161174698729890">"পিন বা ফিঙ্গারপ্রিন্টের সাহায্যে আনলক করুন"</string>
     <string name="kg_unlock_with_password_or_fp" msgid="2251295907826814237">"পাসওয়ার্ড বা ফিঙ্গারপ্রিন্টের সাহায্যে আনলক করুন"</string>
     <string name="kg_unlock_with_pattern_or_fp" msgid="2391870539909135046">"প্যাটার্ন বা ফিঙ্গারপ্রিন্টের সাহায্যে আনলক করুন"</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index 609a517..0c844ab 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -23,7 +23,7 @@
     <string name="keyguard_enter_your_pin" msgid="5429932527814874032">"Inserisci il PIN"</string>
     <string name="keyguard_enter_pin" msgid="8114529922480276834">"Inserisci il PIN"</string>
     <string name="keyguard_enter_your_pattern" msgid="351503370332324745">"Inserisci la sequenza"</string>
-    <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Inserisci la sequenza"</string>
+    <string name="keyguard_enter_pattern" msgid="7616595160901084119">"Traccia la sequenza"</string>
     <string name="keyguard_enter_your_password" msgid="7225626204122735501">"Inserisci la password"</string>
     <string name="keyguard_enter_password" msgid="6483623792371009758">"Inserisci la password"</string>
     <string name="keyguard_sim_error_message_short" msgid="633630844240494070">"Scheda non valida."</string>
diff --git a/packages/SystemUI/res/color/brightness_slider_track.xml b/packages/SystemUI/res/color/brightness_slider_track.xml
new file mode 100644
index 0000000..c6e9b65
--- /dev/null
+++ b/packages/SystemUI/res/color/brightness_slider_track.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?><!--
+  ~ Copyright (C) 2025 The Android Open Source Project
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~      http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT 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/brightness_progress_drawable.xml b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
index 88d3ecb..d38da7b 100644
--- a/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
+++ b/packages/SystemUI/res/drawable/brightness_progress_drawable.xml
@@ -25,7 +25,7 @@
             <shape>
                 <size android:height="@dimen/rounded_slider_track_width" />
                 <corners android:radius="@dimen/rounded_slider_track_corner_radius" />
-                <solid android:color="@androidprv:color/customColorShadeInactive" />
+                <solid android:color="@color/brightness_slider_track" />
             </shape>
         </inset>
     </item>
diff --git a/packages/SystemUI/res/drawable/hearing_device_ambient_expand_icon_background.xml b/packages/SystemUI/res/drawable/hearing_device_ambient_expand_icon_background.xml
new file mode 100644
index 0000000..2173641
--- /dev/null
+++ b/packages/SystemUI/res/drawable/hearing_device_ambient_expand_icon_background.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<inset xmlns:android="http://schemas.android.com/apk/res/android"
+    android:drawable="@drawable/hearing_device_ambient_icon_background"
+    android:insetTop="10dp"
+    android:insetBottom="10dp"/>
diff --git a/packages/SystemUI/res/drawable/hearing_device_ambient_icon_background.xml b/packages/SystemUI/res/drawable/hearing_device_ambient_icon_background.xml
new file mode 100644
index 0000000..81ef3d7
--- /dev/null
+++ b/packages/SystemUI/res/drawable/hearing_device_ambient_icon_background.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     Copyright (C) 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+    android:shape="rectangle">
+    <solid android:color="@androidprv:color/materialColorSurfaceContainerHighest" />
+    <corners
+        android:bottomLeftRadius="?android:attr/dialogCornerRadius"
+        android:topLeftRadius="?android:attr/dialogCornerRadius"
+        android:bottomRightRadius="?android:attr/dialogCornerRadius"
+        android:topRightRadius="?android:attr/dialogCornerRadius" />
+</shape>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/rear_display_dialog_seekbar.xml b/packages/SystemUI/res/drawable/rear_display_dialog_seekbar.xml
index 73704f8..f17cc96 100644
--- a/packages/SystemUI/res/drawable/rear_display_dialog_seekbar.xml
+++ b/packages/SystemUI/res/drawable/rear_display_dialog_seekbar.xml
@@ -21,7 +21,7 @@
         android:height="2dp"
         android:width="@dimen/rear_display_progress_width">
         <shape android:shape="rectangle">
-            <solid android:color="@androidprv:color/materialColorSurfaceContainer" />
+            <solid android:color="?android:attr/colorAccent"/>
         </shape>
     </item>
     <item
@@ -29,4 +29,4 @@
         android:gravity="center_vertical|fill_horizontal">
         <com.android.systemui.util.RoundedCornerProgressDrawable android:drawable="@drawable/rear_display_dialog_seekbar_progress" />
     </item>
-</layer-list>
\ No newline at end of file
+</layer-list>
diff --git a/packages/SystemUI/res/layout/hearing_device_ambient_volume_layout.xml b/packages/SystemUI/res/layout/hearing_device_ambient_volume_layout.xml
index fd409a5..d3e9db1 100644
--- a/packages/SystemUI/res/layout/hearing_device_ambient_volume_layout.xml
+++ b/packages/SystemUI/res/layout/hearing_device_ambient_volume_layout.xml
@@ -36,7 +36,8 @@
             android:padding="12dp"
             android:contentDescription="@string/hearing_devices_ambient_unmute"
             android:src="@drawable/ic_ambient_volume"
-            android:tint="@androidprv:color/materialColorOnSurface" />
+            android:tint="@androidprv:color/materialColorOnSurface"
+            android:background="@drawable/hearing_device_ambient_icon_background"/>
         <TextView
             android:id="@+id/ambient_title"
             android:layout_width="0dp"
@@ -56,7 +57,8 @@
             android:padding="10dp"
             android:contentDescription="@string/hearing_devices_ambient_expand_controls"
             android:src="@drawable/ic_hearing_device_expand"
-            android:tint="@androidprv:color/materialColorOnSurface" />
+            android:tint="@androidprv:color/materialColorOnSurface"
+            android:background="@drawable/hearing_device_ambient_expand_icon_background"/>
     </LinearLayout>
     <LinearLayout
         android:id="@+id/ambient_control_container"
diff --git a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml
index 949a6ab..a1b26fc 100644
--- a/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml
+++ b/packages/SystemUI/res/layout/hearing_devices_tile_dialog.xml
@@ -85,13 +85,49 @@
             android:longClickable="false"/>
     </LinearLayout>
 
+    <LinearLayout
+        android:id="@+id/input_routing_layout"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintTop_toBottomOf="@id/preset_layout"
+        android:layout_marginTop="@dimen/hearing_devices_layout_margin"
+        android:orientation="vertical"
+        android:visibility="gone">
+        <TextView
+            android:id="@+id/input_routing_title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_marginStart="@dimen/bluetooth_dialog_layout_margin"
+            android:layout_marginEnd="@dimen/bluetooth_dialog_layout_margin"
+            android:paddingStart="@dimen/hearing_devices_small_title_padding_horizontal"
+            android:text="@string/hearing_devices_input_routing_label"
+            android:textAppearance="@style/TextAppearance.Dialog.Title"
+            android:textSize="14sp"
+            android:gravity="center_vertical"
+            android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
+            android:textDirection="locale"/>
+        <Spinner
+            android:id="@+id/input_routing_spinner"
+            style="@style/BluetoothTileDialog.Device"
+            android:layout_height="@dimen/bluetooth_dialog_device_height"
+            android:layout_marginTop="4dp"
+            android:paddingStart="0dp"
+            android:paddingEnd="0dp"
+            android:background="@drawable/hearing_devices_spinner_background"
+            android:popupBackground="@drawable/hearing_devices_spinner_popup_background"
+            android:dropDownWidth="match_parent"
+            android:longClickable="false"/>
+    </LinearLayout>
+
     <com.android.systemui.accessibility.hearingaid.AmbientVolumeLayout
         android:id="@+id/ambient_layout"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         app:layout_constraintStart_toStartOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
-        app:layout_constraintTop_toBottomOf="@id/preset_layout"
+        app:layout_constraintTop_toBottomOf="@id/input_routing_layout"
         android:layout_marginTop="@dimen/hearing_devices_layout_margin" />
 
     <LinearLayout
diff --git a/packages/SystemUI/res/layout/notification_2025_info.xml b/packages/SystemUI/res/layout/notification_2025_info.xml
index 7b69166..fa852a2 100644
--- a/packages/SystemUI/res/layout/notification_2025_info.xml
+++ b/packages/SystemUI/res/layout/notification_2025_info.xml
@@ -18,6 +18,7 @@
 <!-- extends LinearLayout -->
 <com.android.systemui.statusbar.notification.row.NotificationInfo
     xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
     xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
     android:id="@+id/notification_guts"
     android:layout_width="match_parent"
@@ -324,18 +325,34 @@
             </com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
 
         </LinearLayout>
-
-        <LinearLayout
+        <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:id="@+id/bottom_buttons"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:layout_marginTop="@*android:dimen/notification_2025_margin"
             android:minHeight="@dimen/notification_2025_guts_button_size"
-            android:gravity="center_vertical"
-            >
+            android:gravity="center_vertical">
+
+            <TextView
+                android:id="@+id/inline_dismiss"
+                android:text="@string/notification_inline_dismiss"
+                android:paddingEnd="@dimen/notification_importance_button_padding"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingTop="8dp"
+                android:paddingBottom="@*android:dimen/notification_2025_margin"
+                app:layout_constraintStart_toStartOf="parent"
+                android:gravity="center"
+                android:minWidth="@dimen/notification_2025_min_tap_target_size"
+                android:minHeight="@dimen/notification_2025_min_tap_target_size"
+                android:maxWidth="200dp"
+                style="@style/TextAppearance.NotificationInfo.Button"
+                android:textSize="@*android:dimen/notification_2025_action_text_size"
+                />
             <TextView
                 android:id="@+id/turn_off_notifications"
                 android:text="@string/inline_turn_off_notifications"
+                android:paddingStart="@dimen/notification_importance_button_padding"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_marginEnd="32dp"
@@ -345,6 +362,8 @@
                 android:minWidth="@dimen/notification_2025_min_tap_target_size"
                 android:minHeight="@dimen/notification_2025_min_tap_target_size"
                 android:maxWidth="200dp"
+                app:layout_constraintStart_toEndOf="@id/inline_dismiss"
+                app:layout_constraintBaseline_toBaselineOf="@id/inline_dismiss"
                 style="@style/TextAppearance.NotificationInfo.Button"
                 android:textSize="@*android:dimen/notification_2025_action_text_size"/>
             <TextView
@@ -354,12 +373,18 @@
                 android:layout_height="wrap_content"
                 android:paddingTop="8dp"
                 android:paddingBottom="@*android:dimen/notification_2025_margin"
-                android:gravity="center"
+                android:gravity="end"
+                app:layout_constraintEnd_toEndOf="parent"
                 android:minWidth="@dimen/notification_2025_min_tap_target_size"
                 android:minHeight="@dimen/notification_2025_min_tap_target_size"
                 android:maxWidth="125dp"
                 style="@style/TextAppearance.NotificationInfo.Button"
                 android:textSize="@*android:dimen/notification_2025_action_text_size"/>
-        </LinearLayout>
+            <androidx.constraintlayout.helper.widget.Flow
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                app:constraint_referenced_ids="inline_dismiss,turn_off_notifications,done"
+                app:flow_wrapMode="chain"/>
+        </androidx.constraintlayout.widget.ConstraintLayout>
     </LinearLayout>
 </com.android.systemui.statusbar.notification.row.NotificationInfo>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 089ceae..d4bd142 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -341,8 +341,8 @@
             android:paddingEnd="4dp"
             >
             <TextView
-                android:id="@+id/turn_off_notifications"
-                android:text="@string/inline_turn_off_notifications"
+                android:id="@+id/inline_dismiss"
+                android:text="@string/notification_inline_dismiss"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_alignParentStart="true"
@@ -350,6 +350,19 @@
                 android:minWidth="@dimen/notification_importance_toggle_size"
                 android:minHeight="@dimen/notification_importance_toggle_size"
                 android:maxWidth="200dp"
+                android:paddingEnd="@dimen/notification_importance_button_padding"
+                style="@style/TextAppearance.NotificationInfo.Button"/>
+            <TextView
+                android:id="@+id/turn_off_notifications"
+                android:text="@string/inline_turn_off_notifications"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/inline_dismiss"
+                android:gravity="start|center_vertical"
+                android:minWidth="@dimen/notification_importance_toggle_size"
+                android:minHeight="@dimen/notification_importance_toggle_size"
+                android:maxWidth="200dp"
+                android:paddingStart="@dimen/notification_importance_button_padding"
                 style="@style/TextAppearance.NotificationInfo.Button"/>
             <TextView
                 android:id="@+id/done"
diff --git a/packages/SystemUI/res/layout/partial_conversation_info.xml b/packages/SystemUI/res/layout/partial_conversation_info.xml
index 4850b35..d1755ef 100644
--- a/packages/SystemUI/res/layout/partial_conversation_info.xml
+++ b/packages/SystemUI/res/layout/partial_conversation_info.xml
@@ -143,8 +143,8 @@
             android:paddingEnd="4dp"
             >
             <TextView
-                android:id="@+id/turn_off_notifications"
-                android:text="@string/inline_turn_off_notifications"
+                android:id="@+id/inline_dismiss"
+                android:text="@string/notification_inline_dismiss"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_alignParentStart="true"
@@ -152,6 +152,19 @@
                 android:minWidth="@dimen/notification_importance_toggle_size"
                 android:minHeight="@dimen/notification_importance_toggle_size"
                 android:maxWidth="200dp"
+                android:paddingEnd="@dimen/notification_importance_button_padding"
+                style="@style/TextAppearance.NotificationInfo.Button"/>
+            <TextView
+                android:id="@+id/turn_off_notifications"
+                android:text="@string/inline_turn_off_notifications"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/inline_dismiss"
+                android:gravity="start|center_vertical"
+                android:minWidth="@dimen/notification_importance_toggle_size"
+                android:minHeight="@dimen/notification_importance_toggle_size"
+                android:maxWidth="200dp"
+                android:paddingStart="@dimen/notification_importance_button_padding"
                 style="@style/TextAppearance.NotificationInfo.Button"/>
             <TextView
                 android:id="@+id/done"
diff --git a/packages/SystemUI/res/layout/promoted_notification_info.xml b/packages/SystemUI/res/layout/promoted_notification_info.xml
index 2e0a0ca..3982a66 100644
--- a/packages/SystemUI/res/layout/promoted_notification_info.xml
+++ b/packages/SystemUI/res/layout/promoted_notification_info.xml
@@ -373,8 +373,8 @@
             android:paddingEnd="4dp"
             >
             <TextView
-                android:id="@+id/turn_off_notifications"
-                android:text="@string/inline_turn_off_notifications"
+                android:id="@+id/inline_dismiss"
+                android:text="@string/notification_inline_dismiss"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:layout_alignParentStart="true"
@@ -382,6 +382,19 @@
                 android:minWidth="@dimen/notification_importance_toggle_size"
                 android:minHeight="@dimen/notification_importance_toggle_size"
                 android:maxWidth="200dp"
+                android:paddingEnd="@dimen/notification_importance_button_padding"
+                style="@style/TextAppearance.NotificationInfo.Button"/>
+            <TextView
+                android:id="@+id/turn_off_notifications"
+                android:text="@string/inline_turn_off_notifications"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_toEndOf="@id/inline_dismiss"
+                android:gravity="start|center_vertical"
+                android:minWidth="@dimen/notification_importance_toggle_size"
+                android:minHeight="@dimen/notification_importance_toggle_size"
+                android:maxWidth="200dp"
+                android:paddingStart="@dimen/notification_importance_button_padding"
                 style="@style/TextAppearance.NotificationInfo.Button"/>
             <TextView
                 android:id="@+id/done"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 6236335..0619281 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nuwe toestel saam te bind"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kon nie voorafstelling opdateer nie"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorafstelling"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Gekies"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgewing"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Regs"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Omgewing"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Linker omgewing"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Regter omgewing"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Vou uit na links- en regsgeskeide kontroles"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Vou in na verenigde kontrole"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Demp omgewing"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ontdemp omgewing"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nutsgoed"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Intydse Onderskrifte"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Instellings"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokkeer toestelmikrofoon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokkeer toestelkamera?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Wanneer jy ’n app deel, is enigiets wat in die app wys of speel, sigbaar aan <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Wees dus versigtig met dinge soos wagwoorde, betalingbesonderhede, boodskappe, foto’s, en oudio en video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deel skerm"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> het hierdie opsie gedeaktiveer"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Kies app om te deel"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Saai jou skerm uit?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Saai een app uit"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aan – gesiggegrond"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Klaar"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Pas toe"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Skakel kennisgewings af"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Stil"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Verstek"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Outomaties"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gebruik verdeelde skerm met app aan die regterkant"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gebruik verdeelde skerm met app aan die linkerkant"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Gebruik volskerm"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Gebruik werkskermvensters"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skakel oor na app regs of onder terwyl jy verdeelde skerm gebruik"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skakel oor na app links of bo terwyl jy verdeelde skerm gebruik"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tydens verdeelde skerm: verplaas ’n app van een skerm na ’n ander"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Sleep hierheen om te verwyder"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Jy moet minstens <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> teëls hê"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Wysig"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Tyd"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Wys ure, minute en sekondes"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Voeg by posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisie is ongeldig."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Teël is reeds bygevoeg"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Teël is bygevoeg"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Teël is verwyder"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kitsinstellingswysiger."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Versteek hierdie mediakontrole vir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Die huidige mediasessie kan nie versteek word nie."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Versteek"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Hervat"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Instellings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> deur <xliff:g id="ARTIST_NAME">%2$s</xliff:g> speel tans vanaf <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> van <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-af/tiles_states_strings.xml b/packages/SystemUI/res/values-af/tiles_states_strings.xml
index fde914f..36830c9 100644
--- a/packages/SystemUI/res/values-af/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-af/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Af"</item>
     <item msgid="4875147066469902392">"Aan"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Onbeskikbaar"</item>
+    <item msgid="8589336868985358191">"Af"</item>
+    <item msgid="726072717827778234">"Aan"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Onbeskikbaar"</item>
     <item msgid="5044688398303285224">"Af"</item>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index e180d11..3e4ca1c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"አዲስ መሣሪያ ለማጣመር ጠቅ ያድርጉ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ቅድመ-ቅምጥን ማዘመን አልተቻለም"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ቅድመ-ቅምጥ"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ተመርጧል"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"በዙሪያ ያሉ"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ግራ"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ቀኝ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"በዙሪያ ያሉ"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"በግራ ዙሪያ ያሉ"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"በቀኝ ዙሪያ ያሉ"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ወደ ግራ እና ቀኝ የተለያዩ ቁጥጥሮች ዘርጋ"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ወደ የተዋሃደ ቁጥጥር ሰብስብ"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"በዙሪያ ያሉትን ድምፀ-ከል አድርግ"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"በዙሪያ ያሉትን ድምፅ-ከል አንሳ"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"መሣሪያዎች"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"የቀጥታ መግለጫ ጽሑፍ"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ቅንብሮች"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ማስታወሻ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"የመሣሪያ ማይክሮፎን እገዳ ይነሳ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"የመሣሪያ ካሜራ እገዳ ይነሳ?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"መተግበሪያን ሲያጋሩ በዚያ መተግበሪያ ውስጥ የሚታይ ወይም የሚጫወት ማንኛውም ነገር ለ<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ይታያል። ስለዚህ እንደ የይለፍ ቃላት፣ የክፍያ ዝርዝሮች፣ መልዕክቶች፣ ፎቶዎች እና ኦዲዮ እና ቪድዮ ላሉ ነገሮች ጥንቃቄ ያድርጉ።"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ማያ ገፅ አጋራ"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ይህን አማራጭ አሰናክሏል"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ለማጋራት መተግበሪያ ይምረጡ"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ማያ ገፅዎ cast ይደረግ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"አንድ መተግበሪያ cast ያድርጉ"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"በርቷል - መልክ ላይ የተመሠረተ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ተከናውኗል"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ተግብር"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ማሳወቂያዎችን አጥፋ"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"ፀጥ ያለ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ነባሪ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ራስ-ሰር"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"መተግበሪያ በስተቀኝ ላይ ሆኖ የተከፈለ ማያ ገፅን ይጠቀሙ"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"መተግበሪያ በስተግራ ላይ ሆኖ የተከፈለ ማያ ገፅን ይጠቀሙ"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ሙሉ ገፅ ዕይታን ይጠቀሙ"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"የዴስክቶፕ መስኮት ይጠቀሙ"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከታች ወዳለ መተግበሪያ ይቀይሩ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"የተከፈለ ማያ ገጽን ሲጠቀሙ በቀኝ ወይም ከላይ ወዳለ መተግበሪያ ይቀይሩ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"በተከፈለ ማያ ገጽ ወቅት፡- መተግበሪያን ከአንዱ ወደ ሌላው ተካ"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ለማስወገድ ወደዚህ ይጎትቱ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"ቢያንስ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ሰቆች ያስፈልገዎታል"</string>
     <string name="qs_edit" msgid="5583565172803472437">"አርትዕ"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"ሰዓት"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ሰዓቶችን፣ ደቂቃዎችን፣ ሴኮንዶችን አሳይ"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ወደ <xliff:g id="POSITION">%1$d</xliff:g> ቦታ አክል"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"አቀማመጡ ተቀባይነት የለውም።"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"የ<xliff:g id="POSITION">%1$d</xliff:g> አቀማመጥ"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ሰቅ አስቀድሞ ታክሏል"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ሰቅ ታክሏል"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ሰቅ ተወግዷል"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"የፈጣን ቅንብሮች አርታዒ።"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"ለ<xliff:g id="APP_NAME">%1$s</xliff:g> የዚህ ሚዲያ መቆጣጠሪያ ይደበቅ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"የአሁኑ የሚዲያ ክፍለ ጊዜ ሊደበቅ አይቻልም።"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ደብቅ"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"ከቆመበት ቀጥል"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ቅንብሮች"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> በ<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ከ<xliff:g id="APP_LABEL">%3$s</xliff:g> እየተጫወተ ነው"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ከ<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-am/tiles_states_strings.xml b/packages/SystemUI/res/values-am/tiles_states_strings.xml
index f8e7a43..bd24065 100644
--- a/packages/SystemUI/res/values-am/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-am/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"ጠፍቷል"</item>
     <item msgid="4875147066469902392">"በርቷል"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"አይገኝም"</item>
+    <item msgid="8589336868985358191">"ጠፍቷል"</item>
+    <item msgid="726072717827778234">"በርቷል"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"አይገኝም"</item>
     <item msgid="5044688398303285224">"ጠፍቷል"</item>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 416eee8..f9660a3 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"انقر لإقران جهاز جديد"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"تعذَّر تعديل الإعداد المسبق"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"الإعدادات المسبقة"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"تمّ اختياره"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"الأصوات المحيطة"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"اليسرى"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"إعادة الأصوات المحيطة"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"الأدوات"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"النسخ النصي التلقائي"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"الإعدادات"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ملاحظات"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"هل تريد إزالة حظر ميكروفون الجهاز؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"هل تريد إزالة حظر كاميرا الجهاز؟"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ستتم مشاركة كل المحتوى المعروض أو المشغَّل على شاشة هذا التطبيق مع تطبيق \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\"، لذا يُرجى توخي الحذر بشأن المعلومات الظاهرة على الشاشة، مثل كلمات المرور وتفاصيل الدفع والرسائل والصور والمقاطع الصوتية والفيديوهات."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"مشاركة الشاشة"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"تم إيقاف هذا الخيار من خلال تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>."</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"يُرجى اختيار تطبيق لمشاركة محتواه"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"هل تريد بث محتوى الشاشة؟"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"بث محتوى تطبيق واحد"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"تفعيل - استنادًا للوجه"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"تمّ"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"تطبيق"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"إيقاف الإشعارات"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"إشعارات صامتة"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"تلقائية"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"تلقائي"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"استخدام \"وضع تقسيم الشاشة\" مع تثبيت التطبيق على اليمين"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"استخدام \"وضع تقسيم الشاشة\" مع تثبيت التطبيق على اليسار"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"استخدام وضع ملء الشاشة"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"استخدام وضع عرض النوافذ على سطح المكتب"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"التبديل إلى التطبيق على اليسار أو الأسفل أثناء استخدام \"تقسيم الشاشة\""</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"التبديل إلى التطبيق على اليمين أو الأعلى أثناء استخدام \"تقسيم الشاشة\""</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"استبدال تطبيق بآخر في وضع \"تقسيم الشاشة\""</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"اسحب هنا للإزالة"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"الحدّ الأدنى من عدد المربعات الذي تحتاج إليه هو <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"تعديل"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"الوقت"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"عرض الساعات والدقائق والثواني"</item>
@@ -1003,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"الإضافة إلى الموضع <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"الموضِع غير صالح."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"الموضع: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"سبق أن تمت إضافة شاشة المعلومات"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"تمت إضافة البطاقة."</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"تمت إزالة البطاقة."</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"برنامج تعديل الإعدادات السريعة."</string>
@@ -1205,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"هل تريد إخفاء عنصر التحكم في الوسائط هذا للتطبيق <xliff:g id="APP_NAME">%1$s</xliff:g>؟"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"لا يمكن إخفاء جلسة الوسائط الحالية."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"إخفاء"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"استئناف التشغيل"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"الإعدادات"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"يتم تشغيل <xliff:g id="SONG_NAME">%1$s</xliff:g> للفنان <xliff:g id="ARTIST_NAME">%2$s</xliff:g> من تطبيق <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> من إجمالي <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ar/tiles_states_strings.xml b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
index aac5a35..31607b9 100644
--- a/packages/SystemUI/res/values-ar/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ar/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"الميزة غير مفعّلة"</item>
     <item msgid="4875147066469902392">"الميزة مفعّلة"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"الميزة غير متاحة"</item>
     <item msgid="5044688398303285224">"الميزة غير مفعّلة"</item>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 4340f21..595432e 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"নতুন ডিভাইচ পেয়াৰ কৰিবলৈ ক্লিক কৰক"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"প্ৰিছেট আপডে’ট কৰিব পৰা নগ’ল"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্ৰিছেট"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বাছনি কৰা হৈছে"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"আশ-পাশ"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"বাওঁফাল"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"সোঁফাল"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"আশে-পাশে থকা"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"বাওঁফালে আশে-পাশে থকা"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"সোঁফালে আশে-পাশে থকা"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"বাওঁ আৰু সোঁফালৰ পৃথক কৰা নিয়ন্ত্ৰণলৈ সংকোচন কৰক"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"একত্ৰিত নিয়ন্ত্ৰণলৈ সংকোচন কৰক"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"আশ-পাশৰ ধ্বনি মিউট কৰক"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"আশ-পাশৰ ধ্বনি আনমিউট কৰক"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"সঁজুলি"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ কেপশ্বন"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ছেটিং"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"টোকা"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইচৰ মাইক্ৰ\'ফ\'ন অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইচৰ কেমেৰা অৱৰোধৰ পৰা আঁতৰাবনে?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"আপুনি কোনো এপ্‌ শ্বেয়াৰ কৰি থাকোঁতে সেই এপ্‌টোত দেখুওৱা বা প্লে’ কৰা যিকোনো বস্তু <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ত দৃশ্যমান হয়। সেয়ে পাছৱৰ্ড, পৰিশোধৰ সবিশেষ, বাৰ্তা, ফট’ আৰু অডিঅ’ আৰু ভিডিঅ’ৰ ক্ষেত্ৰত সাৱধান হওক।"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"স্ক্ৰীন শ্বেয়াৰ কৰক"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ এই বিকল্পটো অক্ষম কৰিছে"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"শ্বেয়াৰ কৰিবলৈ এপ্ বাছনি কৰক"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"আপোনাৰ স্ক্ৰীনখন কাষ্ট কৰিবনে?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"এটা এপ্‌ কাষ্ট কৰক"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"অন আছে - মুখাৱয়ব ভিত্তিক"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"কৰা হ’ল"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"প্ৰয়োগ কৰক"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"জাননী অফ কৰক"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"নীৰৱ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ডিফ’ল্ট"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"স্বয়ংক্ৰিয়"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"সোঁফালে থকা এপ্‌টোৰ সৈতে বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰক"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"বাওঁফালে থকা এপ্‌টোৰ সৈতে বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰক"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"পূৰ্ণ স্ক্ৰীন ব্যৱহাৰ কৰক"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ডেস্কটপ ৱিণ্ড’ৱিং ব্যৱহাৰ কৰক"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত সোঁফালে অথবা তলত থকা এপলৈ সলনি কৰক"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰাৰ সময়ত বাওঁফালে অথবা ওপৰত থকা এপলৈ সলনি কৰক"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"বিভাজিত স্ক্ৰীনৰ ব্যৱহাৰ কৰাৰ সময়ত: কোনো এপ্ এখন স্ক্ৰীনৰ পৰা আনখনলৈ নিয়ক"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"আঁতৰাবৰ বাবে টানি আনি ইয়াত এৰি দিয়ক"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"আপোনাক অতিকমেও <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>খন টাইল লাগিব"</string>
     <string name="qs_edit" msgid="5583565172803472437">"সম্পাদনা কৰক"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"সময়"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ঘন্টা, মিনিট আৰু ছেকেণ্ড দেখুৱাওক"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থানত যোগ দিয়ক"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"স্থান অমান্য।"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> নম্বৰ স্থান"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ইতিমধ্যে টাইল যোগ দিয়া হৈছে"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"টাইল যোগ দিয়া হৈছে"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"টাইল আঁতৰোৱা হৈছে"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ক্ষিপ্ৰ ছেটিঙৰ সম্পাদক।"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>ৰ বাবে এই মিডিয়া নিয়ন্ত্ৰণটো লুকুৱাবনে?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"বৰ্তমানৰ মিডিয়াৰ ছেশ্বনটো লুকুৱাব নোৱাৰি।"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকুৱাওক"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"পুনৰ আৰম্ভ কৰক"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ছেটিং"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ত <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ৰ <xliff:g id="SONG_NAME">%1$s</xliff:g> গীতটো প্লে’ হৈ আছে"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ৰ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-as/tiles_states_strings.xml b/packages/SystemUI/res/values-as/tiles_states_strings.xml
index ba30c1e..d07f11b 100644
--- a/packages/SystemUI/res/values-as/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-as/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"অফ আছে"</item>
     <item msgid="4875147066469902392">"অন কৰা আছে"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"উপলব্ধ নহয়"</item>
+    <item msgid="8589336868985358191">"অফ আছে"</item>
+    <item msgid="726072717827778234">"অন আছে"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"উপলব্ধ নহয়"</item>
     <item msgid="5044688398303285224">"অফ আছে"</item>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 226c39d..3cf675d 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz birləşdirmək üçün klikləyin"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncəllənmədi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçilib"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ətraf mühit"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sol"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Sağ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ətraf mühit"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Sol tərəf"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Sağ tərəf"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Sola və sağa ayrılmış idarəetmələr üçün genişləndirin"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Vahid nəzarət üçün yığcamlaşdırın"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ətraf mühiti səssiz edin"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ətraf mühiti səssiz rejimdən çıxarın"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alətlər"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ayarlar"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qeyd"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonu blokdan çıxarılsın?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerası blokdan çıxarılsın?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Tətbiq paylaşdığınız zaman həmin tətbiqdə göstərilən və ya işə salınan hər şey <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> üçün görünən olacaq. Parol, ödəniş məlumatı, mesaj, foto, habelə audio və video kimi məlumatlarla bağlı diqqətli olun."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ekranı paylaşın"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu seçimi deaktiv edib"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Paylaşmaq üçün tətbiq seçin"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ekran yayımlansın?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Bir tətbiqi yayımlayın"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aktiv - Üz əsaslı"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Hazırdır"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Tətbiq edin"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Bildirişləri deaktiv edin"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Səssiz"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Defolt"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Tətbiq sağda olmaqla bölünmüş ekranı istifadə edin"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Tətbiq solda olmaqla bölünmüş ekranı istifadə edin"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Tam ekrandan istifadə edin"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Masaüstü pəncərə rejimindən istifadə edin"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran istifadə edərkən sağda və ya aşağıda tətbiqə keçin"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran istifadə edərkən solda və ya yuxarıda tətbiqə keçin"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran rejimində: tətbiqi birindən digərinə dəyişin"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Silmək üçün bura sürüşdürün"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimum <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mozaika lazımdır"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Redaktə edin"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Vaxt"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Saat, dəqiqə və saniyəni göstərin"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyinə əlavə edin"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Mövqe yanlışdır."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> mövqeyi"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Mozaik əlavə edilib"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Mozaik əlavə edilib"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Mozaik silinib"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Sürətli ayarlar redaktoru."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> üçün bu media nizamlayıcısı gizlədilsin?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Cari media sessiyası gizlədilə bilməz."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizlədin"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Davam edin"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> tərəfindən <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> tətbiqindən oxudulur"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-az/tiles_states_strings.xml b/packages/SystemUI/res/values-az/tiles_states_strings.xml
index 74b95e2..9fdca5de 100644
--- a/packages/SystemUI/res/values-az/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-az/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Deaktiv"</item>
     <item msgid="4875147066469902392">"Aktiv"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Əlçatan deyil"</item>
+    <item msgid="8589336868985358191">"Deaktiv"</item>
+    <item msgid="726072717827778234">"Aktiv"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Əlçatan deyil"</item>
     <item msgid="5044688398303285224">"Deaktiv"</item>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 0d7619d..b74094e5 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili nov uređaj"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadatih podešavanja nije uspelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unapred određena podešavanja"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izabrano"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Levo"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Okruženje"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Levo okruženje"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Desno okruženje"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširi na kontrole razdvojene na levu i desnu stranu"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Skupi u jedinstvenu kontrolu"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključi zvuk okruženja"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Uključi zvuk okruženja"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatke"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titl uživo"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Podešavanja"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Beleška"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite da odblokirate mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite da odblokirate kameru uređaja?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada delite aplikaciju, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vidi sav sadržaj koji se prikazuje ili pušta u njoj. Zato pazite na lozinke, informacije o plaćanju, poruke, slike, audio i video sadržaj."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deli ekran"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila ovu opciju"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Odaberite aplikaciju za deljenje"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Želite da prebacite ekran?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Prebaci jednu aplikaciju"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Uključeno – na osnovu lica"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Gotovo"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Primeni"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obaveštenja"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Podrazumevano"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatska"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Koristi podeljeni ekran sa aplikacijom s desne strane"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Koristi podeljeni ekran sa aplikacijom s leve strane"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Koristi prikaz preko celog ekrana"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Koristi prozorski prikaz na računaru"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pređi u aplikaciju zdesna ili ispod dok je podeljen ekran"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju sleva ili iznad dok koristite podeljeni ekran"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"U režimu podeljenog ekrana: zamena jedne aplikacije drugom"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Prevucite ovde da biste uklonili"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimalan broj pločica je <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Izmeni"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Vreme"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Prikaži sate, minute i sekunde"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodajte na <xliff:g id="POSITION">%1$d</xliff:g>. poziciju"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozicija je nevažeća."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. pozicija"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Pločica je već dodata"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pločica je dodata"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pločica je uklonjena"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač za Brza podešavanja."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Želite da sakrijete ovu kontrolu za medije za: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuelna sesija medija ne može da bude sakrivena."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se pušta iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
index 51b667c..5784d47 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Isključeno"</item>
     <item msgid="4875147066469902392">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nedostupno"</item>
+    <item msgid="8589336868985358191">"Isključeno"</item>
+    <item msgid="726072717827778234">"Uključeno"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nedostupno"</item>
     <item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 809b60b..11c2715 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -33,7 +33,7 @@
     <string name="battery_saver_dismiss_action" msgid="7199342621040014738">"Не, дзякуй"</string>
     <string name="standard_battery_saver_text" msgid="6855876746552374119">"Стандартны рэжым"</string>
     <string name="extreme_battery_saver_text" msgid="8455810156739865335">"Максімальная"</string>
-    <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аўтаматычны паварот экрана"</string>
+    <string name="status_bar_settings_auto_rotation" msgid="8329080442278431708">"Аўтапаварот экрана"</string>
     <string name="usb_device_permission_prompt" msgid="4414719028369181772">"Дазволіць праграме <xliff:g id="APPLICATION">%1$s</xliff:g> доступ да прылады <xliff:g id="USB_DEVICE">%2$s</xliff:g>?"</string>
     <string name="usb_device_permission_prompt_warn" msgid="2309129784984063656">"Даць праграме \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ да прылады \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?\nУ гэтай праграмы няма дазволу на запіс, аднак яна зможа запісваць аўдыя праз гэту прыладу USB."</string>
     <string name="usb_audio_device_permission_prompt_title" msgid="4221351137250093451">"Дазволіць праграме \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" доступ да прылады \"<xliff:g id="USB_DEVICE">%2$s</xliff:g>\"?"</string>
@@ -333,7 +333,7 @@
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"Уключэнне…"</string>
     <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"Не ўдаецца адрэгуляваць яркасць, бо яна кантралюецца верхняй праграмай"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"Аўтапаварот"</string>
-    <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтаматычны паварот экрана"</string>
+    <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Аўтапаварот экрана"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"Месцазнаходжанне"</string>
     <string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Экранная застаўка"</string>
     <string name="quick_settings_camera_label" msgid="5612076679385269339">"Доступ да камеры"</string>
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Націсніце, каб спалучыць новую прыладу"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не ўдалося абнавіць набор налад"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор налад"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрана"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Навакольныя гукі"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Левы бок"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Правы бок"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Навакольныя гукі"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Навакольныя гукі злева"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Навакольныя гукі справа"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Зрабіць левую і правую панэлі кіравання"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Зрабіць адну панэль кіравання"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Выключыць навакольныя гукі"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Уключыць навакольныя гукі"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменты"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Аўтаматычныя субцітры"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Налады"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нататка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблакіраваць мікрафон прылады?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблакіраваць камеру прылады?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Калі вы абагульваеце праграму, праграма \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\" можа бачыць усё, што паказваецца ці прайграецца ў гэтай праграме. Таму прадухіліце паказ пароляў, плацежных рэквізітаў, паведамленняў, фота, відэа і аўдыя."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Абагуліць экран"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" адключыла гэты параметр"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Выберыце праграму для абагульвання"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Уключыць трансляцыю экрана?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Трансліраваць адну праграму"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Уключана – З улікам паставы галавы"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Гатова"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Прымяніць"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Выключыць апавяшчэнні"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Бязгучны рэжым"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Стандартна"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Аўтаматычна"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Падзяліць экран і памясціць праграму справа"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Падзяліць экран і памясціць праграму злева"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Выкарыстоўваць поўнаэкранны рэжым"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Выкарыстоўваць рэжым вокнаў працоўнага стала"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пераключыцца на праграму справа або ўнізе на падзеленым экране"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пераключыцца на праграму злева або ўверсе на падзеленым экране"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"У рэжыме падзеленага экрана замяніць адну праграму на іншую"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Перацягніце сюды, каб выдаліць"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Мінімальная колькасць плітак: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Рэдагаваць"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Час"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Паказваць гадзіны, хвіліны і секунды"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Дадаць на пазіцыю <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Няправільнае месца."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Пазіцыя <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Плітка ўжо дададзена"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плітка дададзена"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плітка выдалена"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Рэдактар хуткіх налад."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Схаваць гэту панэль мультымедыя для праграмы \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Не ўдалося схаваць бягучы сеанс мультымедыя."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Схаваць"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Узнавіць"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Налады"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"У праграме \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\" прайграецца кампазіцыя \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", выканаўца – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> з <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-be/tiles_states_strings.xml b/packages/SystemUI/res/values-be/tiles_states_strings.xml
index cbbfe92..67468b4 100644
--- a/packages/SystemUI/res/values-be/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-be/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Выключана"</item>
     <item msgid="4875147066469902392">"Уключана"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Недаступна"</item>
+    <item msgid="8589336868985358191">"Выключана"</item>
+    <item msgid="726072717827778234">"Уключана"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Недаступна"</item>
     <item msgid="5044688398303285224">"Выключана"</item>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 9f7a9cd..a085b154 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за сдвояване на ново устройство"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Предварително зададените настройки не бяха актуализирани"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Предварително зададено"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Околни звуци"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ляво"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Включване на околните звуци"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменти"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Надписи на живо"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Настройки"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Бележка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се отблокира ли микрофонът на устройството?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се отблокира ли камерата на устройството?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Когато споделяте приложение, всичко, което се показва или възпроизвежда в него, е видимо за <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Затова бъдете внимателни с неща като пароли, подробности за начини на плащане, съобщения, снимки, аудио и видео."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Споделяне на екрана"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> деактивира тази опция"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Изберете приложение за споделяне"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Искате ли да предавате екрана си?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Предаване на едно приложение"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Вкл. – въз основа на лицето"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Прилагане"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Изключване на известията"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Тих режим"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Стандартно"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Използване на разделен екран с приложението вдясно"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Използване на разделен екран с приложението вляво"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Използване режима на цял екран"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Използване на режима за настолни компютри"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Превключване към приложението вдясно/отдолу в режима на разделен екран"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Превключване към приложението вляво/отгоре в режима на разделен екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"При разделен екран: замяна на дадено приложение с друго"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Преместете тук с плъзгане за премахване"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Трябва да останат поне <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> плочки"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Редактиране"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Час"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Показване на часовете, минутите и секундите"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Скриване на мултимед. контрола за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Текущата сесия за мултимедия не бе скрита."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриване"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> на <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се възпроизвежда от <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> от <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-bg/tiles_states_strings.xml b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
index 636585d..535ddcd 100644
--- a/packages/SystemUI/res/values-bg/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bg/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Изкл."</item>
     <item msgid="4875147066469902392">"Вкл."</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Не е налице"</item>
+    <item msgid="8589336868985358191">"Изкл."</item>
+    <item msgid="726072717827778234">"Вкл."</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Не е налице"</item>
     <item msgid="5044688398303285224">"Изкл."</item>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index f1d9770..18d632e 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"নতুন ডিভাইস পেয়ার করতে ক্লিক করুন"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"প্রিসেট আপডেট করা যায়নি"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"প্রিসেট"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"বেছে নেওয়া হয়েছে"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"সারাউন্ডিং"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"বাঁদিক"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ডানদিক"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"সারাউন্ডিং"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"লেফ্ট সারাউন্ডিং"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"রাইট সারাউন্ডিং"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"বাঁদিক ও ডানদিকের আলাদা করা কন্ট্রোল বড় করুন"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ইউনিফায়েড কন্ট্রোল আড়াল করুন"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"সারাউন্ডিং মিউট করুন"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"সারাউন্ডিং আনমিউট করুন"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"টুল"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"লাইভ ক্যাপশন"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"সেটিংস"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"মনে রাখবেন"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ডিভাইসের মাইক্রোফোন আনব্লক করতে চান?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ডিভাইসের ক্যামেরা আনব্লক করতে চান?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"কোনও অ্যাপ শেয়ার করার সময়, সেই অ্যাপে দেখা ও চালানো হয় এমন সব কিছু <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> দেখতে পাবে। তাই পাসওয়ার্ড, পেমেন্টের বিবরণ, মেসেজ, ফটো এবং অডিও ও ভিডিওর মতো বিষয়ের ক্ষেত্রে সতর্ক থাকুন।"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"স্ক্রিন শেয়ার করুন"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> এই বিকল্পটি বন্ধ করে দিয়েছে"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"শেয়ার করার জন্য অ্যাপ বেছে নিন"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"আপনার স্ক্রিন কাস্ট করতে চান?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"একটি অ্যাপ কাস্ট করুন"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"চালু আছে - মুখের হিসেবে"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"হয়ে গেছে"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"প্রয়োগ করুন"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"বিজ্ঞপ্তি বন্ধ করুন"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"সাইলেন্ট"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ডিফল্ট"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"অটোমেটিক"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ডানদিকে বর্তমান অ্যাপে স্প্লিট স্ক্রিন ব্যবহার করুন"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"বাঁদিকে বর্তমান অ্যাপে স্প্লিট স্ক্রিন ব্যবহার করুন"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ফুল-স্ক্রিন মোড ব্যবহার করুন"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ডেস্কটপ উইন্ডোয়িং ব্যবহার করুন"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"স্প্লিট স্ক্রিন ব্যবহার করার সময় ডানদিকের বা নিচের অ্যাপে পাল্টে নিন"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"স্প্লিট স্ক্রিন ব্যবহার করার সময় বাঁদিকের বা উপরের অ্যাপে পাল্টে নিন"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"\'স্প্লিট স্ক্রিন\' থাকাকালীন: একটি অ্যাপ থেকে অন্যটিতে পাল্টান"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"সরানোর জন্য এখানে টেনে আনুন"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"আপনাকে কমপক্ষে <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>টি টাইল রাখতে হবে"</string>
     <string name="qs_edit" msgid="5583565172803472437">"এডিট করুন"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"সময়"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ঘণ্টা, মিনিট, এবং সেকেন্ড দেখান"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>-এ যোগ করুন"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"পজিশন সঠিক নয়।"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"অবস্থান <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"টাইল আগেই যোগ করা হয়েছে"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"টাইল যোগ করা হয়েছে"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"টাইল সরানো হয়েছে"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"দ্রুত সেটিংস সম্পাদক৷"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>-এর মিডিয়া কন্ট্রোল লুকিয়ে রাখতে চান?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"বর্তমান মিডিয়া সেশন লুকিয়ে রাখা যাবে না।"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"লুকান"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>-এর <xliff:g id="SONG_NAME">%1$s</xliff:g> গানটি <xliff:g id="APP_LABEL">%3$s</xliff:g> অ্যাপে চলছে"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>টির মধ্যে <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>টি"</string>
diff --git a/packages/SystemUI/res/values-bn/tiles_states_strings.xml b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
index 08231e4..852986c 100644
--- a/packages/SystemUI/res/values-bn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bn/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"বন্ধ আছে"</item>
     <item msgid="4875147066469902392">"চালু আছে"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"উপলভ্য নেই"</item>
     <item msgid="5044688398303285224">"বন্ধ আছে"</item>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 57b83d9..c18af99 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da uparite novi uređaj"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje zadane postavke nije uspjelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Zadana postavka"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lijevo"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Okruženje"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Lijevo okruženje"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Desno okruženje"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširivanje u zasebne kontrole ulijevo i udesno"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sužavanje u objedinjenu kontrolu"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključivanje zvuka okruženja"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Uključivanje zvuka okruženja"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Postavke"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Bilješka"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblokirati mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblokirati kameru uređaja?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada dijelite aplikaciju, sve što se prikazuje ili reproducira u toj aplikaciji će biti vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga budite oprezni s informacijama kao što su lozinke, podaci o plaćanju, poruke, fotografije, audio i videozapisi."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Dijeli ekran"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogućila tu opciju"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Odaberite aplikaciju koju želite dijeliti"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Emitirati ekran?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emitiraj jednu aplikaciju"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Uključeno – na osnovu lica"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Gotovo"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Primijeni"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obavještenja"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Nečujno"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Zadano"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Korištenje podijeljenog ekrana s aplikacijom na desnoj strani"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Korištenje podijeljenog ekrana s aplikacijom na lijevoj strani"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Korištenje prikaza preko cijelog ekrana"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Korištenje prikaza u prozorima na računaru"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak u aplikaciju desno ili ispod uz podijeljeni ekran"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pređite u aplikaciju lijevo ili iznad dok koristite podijeljeni ekran"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Za vrijeme podijeljenog ekrana: zamjena jedne aplikacije drugom"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Prevucite ovdje za uklanjanje"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Broj polja mora biti najmanje <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Uredite"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Vrijeme"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Prikaži sate, minute i sekunde"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje u položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nevažeći položaj."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Kartica je već dodana"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartica je dodana"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartica je uklonjena"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivanje brzih postavki"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Sakriti kontrolu medija za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Trenutna sesija medija se ne može sakriti."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Pjesma <xliff:g id="SONG_NAME">%1$s</xliff:g> izvođača <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se reproducira pomoću aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-bs/tiles_states_strings.xml b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
index 51b667c..5784d47 100644
--- a/packages/SystemUI/res/values-bs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-bs/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Isključeno"</item>
     <item msgid="4875147066469902392">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nedostupno"</item>
+    <item msgid="8589336868985358191">"Isključeno"</item>
+    <item msgid="726072717827778234">"Uključeno"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nedostupno"</item>
     <item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index d2f942e..0404bc7 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fes clic per vincular un dispositiu nou"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No s\'ha pogut actualitzar el valor predefinit"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Valors predefinits"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionat"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Entorn"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerra"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Deixa de silenciar l\'entorn"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eines"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítols instantanis"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Configuració"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vols desbloquejar el micròfon del dispositiu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vols desbloquejar la càmera del dispositiu?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quan comparteixes una aplicació, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> pot veure qualsevol cosa que s\'hi mostra o que s\'hi reprodueix. Per aquest motiu, ves amb compte amb les contrasenyes, les dades de pagament, els missatges, les fotos i l\'àudio i el vídeo."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Comparteix la pantalla"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha desactivat aquesta opció"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Tria una aplicació per compartir"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vols emetre la pantalla?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emet una aplicació"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activat: basat en cares"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Fet"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplica"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactiva les notificacions"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silenci"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminat"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automàtic"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Utilitzar la pantalla dividida amb l\'aplicació a la dreta"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Utilitzar la pantalla dividida amb l\'aplicació a l\'esquerra"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Utilitza la pantalla completa"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Utilitza l\'enfinestrament d\'escriptori"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Canvia a l\'aplicació de la dreta o de sota amb la pantalla dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Canvia a l\'aplicació de l\'esquerra o de dalt amb la pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Durant el mode de pantalla dividida: substitueix una app per una altra"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrossega aquí per suprimir"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Necessites com a mínim <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mosaics"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Edita"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Mostra les hores, els minuts i els segons"</item>
@@ -1003,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Afegeix a la posició <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"La posició no és vàlida."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posició <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"La targeta ja s\'ha afegit"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"El mosaic s\'ha afegit"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"El mosaic s\'ha suprimit"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuració ràpida."</string>
@@ -1205,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Amagar aquest control multimèdia per a <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"La sessió multimèdia actual no es pot amagar."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Amaga"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuració"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) s\'està reproduint des de l\'aplicació <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ca/tiles_states_strings.xml b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
index 3b0b9d7..7afc00f 100644
--- a/packages/SystemUI/res/values-ca/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ca/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Desactivat"</item>
     <item msgid="4875147066469902392">"Activat"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"No disponible"</item>
+    <item msgid="8589336868985358191">"Desactivat"</item>
+    <item msgid="726072717827778234">"Activat"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"No disponible"</item>
     <item msgid="5044688398303285224">"Desactivat"</item>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 5149f9d..e438d63 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zařízení"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Předvolbu nelze aktualizovat"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Předvolba"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybráno"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolí"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vlevo"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Vpravo"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Okolí"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Okolí vlevo"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Okolí vpravo"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Rozbalit na samostatné ovládání levé a pravé strany"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sbalit na sjednocené ovládání"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ztlumit okolí"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Zapnout zvuk okolí"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okamžité titulky"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Nastavení"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokovat mikrofon zařízení?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokovat fotoaparát zařízení?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Při sdílení aplikace vidí <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vše, co se ve sdílené aplikaci nachází nebo děje. Buďte proto opatrní, když jde o hesla, platební údaje, zprávy, fotografie, zvuk a video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Sdílet obrazovku"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> tuto možnost zakázala"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Vyberte aplikaci ke sdílení"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Odeslat obrazovku?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Odeslat jednu aplikaci"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Zapnuto – podle obličeje"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Hotovo"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Použít"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Vypnout oznámení"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Tichý režim"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Výchozí"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automaticky"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Použít rozdělenou obrazovku s aplikací vpravo"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Použít rozdělenou obrazovku s aplikací vlevo"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Použít celou obrazovku"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Používat okna jako na počítači"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Přepnout na aplikaci vpravo nebo dole v režimu rozdělené obrazovky"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Přepnout na aplikaci vlevo nebo nahoře v režimu rozdělené obrazovky"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"V režimu rozdělené obrazovky: nahradit jednu aplikaci druhou"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Přetažením sem dlaždice odstraníte"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Potřebujete alespoň tento počet dlaždic: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Upravit"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Čas"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Zobrazovat hodiny, minuty a sekundy"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Přidat dlaždici na pozici <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozice není platná."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozice <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Karta byla už přidána"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Dlaždice byla přidána"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Dlaždice byla odstraněna"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor rychlého nastavení"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Skrýt toto ovládání médií aplikace <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuální mediální relaci nelze skrýt."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrýt"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Pokračovat"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavení"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> hrajte z aplikace <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-cs/tiles_states_strings.xml b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
index 4977032..46ef4ea 100644
--- a/packages/SystemUI/res/values-cs/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-cs/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Vypnuto"</item>
     <item msgid="4875147066469902392">"Zapnuto"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nedostupné"</item>
+    <item msgid="8589336868985358191">"Vypnuto"</item>
+    <item msgid="726072717827778234">"Zapnuto"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nedostupné"</item>
     <item msgid="5044688398303285224">"Vypnuto"</item>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index baf010d..52abc4a 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik for at parre en ny enhed"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Forindstillingen kunne ikke opdateres"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forindstilling"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivelser"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Venstre"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Højre"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Omgivelser"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Omgivelser til venstre"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Omgivelser til højre"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Udvid til adskilte styringselementer til venstre og højre"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Minimer til samlet styringselement"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ignorer omgivelser"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ignorer ikke omgivelser"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Værktøjer"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstning"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Indstillinger"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du fjerne blokeringen af enhedens mikrofon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du fjerne blokeringen af enhedens kamera?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Når du deler en app, er alt, der vises eller afspilles i den pågældende app, synligt for <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Vær derfor forsigtig med f.eks. adgangskoder, betalingsoplysninger, beskeder, billeder, lyd og video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Del skærm"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har deaktiveret denne valgmulighed"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Vælg den app, du vil dele fra"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vil du caste din skærm?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast én app"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Til – ansigtsbaseret"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Udfør"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Anvend"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Deaktiver notifikationer"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Lydløs"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Brug opdelt skærm med appen til højre"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Brug opdelt skærm med appen til venstre"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Brug fuld skærm"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Brug vinduer på skrivebordet"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skift til en app til højre eller nedenfor, når du bruger opdelt skærm"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skift til en app til venstre eller ovenfor, når du bruger opdelt skærm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ved opdelt skærm: Udskift én app med en anden"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Træk herhen for at fjerne"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Du skal bruge mindst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> felter"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Rediger"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Tid"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Vis timer, minutter og sekunder"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Føj til lokation <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positionen er ugyldig."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Lokation <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Handlingsfeltet er allerede tilføjet"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Feltet blev tilføjet"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Feltet blev fjernet"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsværktøj til Kvikmenu."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Vil du skjule denne mediefunktion for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Den aktuelle mediesession kan ikke skjules."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Genoptag"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Indstillinger"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> af <xliff:g id="ARTIST_NAME">%2$s</xliff:g> afspilles via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> af <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-da/tiles_states_strings.xml b/packages/SystemUI/res/values-da/tiles_states_strings.xml
index af6dafb..b4a3eaf 100644
--- a/packages/SystemUI/res/values-da/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-da/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Fra"</item>
     <item msgid="4875147066469902392">"Til"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Ikke tilgængelig"</item>
+    <item msgid="8589336868985358191">"Fra"</item>
+    <item msgid="726072717827778234">"Til"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Ikke tilgængelig"</item>
     <item msgid="5044688398303285224">"Fra"</item>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 8c8e994..612c52f 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicken, um neues Gerät zu koppeln"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Voreinstellung konnte nicht aktualisiert werden"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voreinstellung"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ausgewählt"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Umgebungsgeräusche"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Rechts"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Umgebungsgeräusche"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Umgebungsgeräusche links"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Umgebungsgeräusche rechts"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"In ein linkes und ein rechtes Steuerfeld maximieren"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Zu einem einzigen Steuerfeld minimieren"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Umgebungsgeräusche stummschalten"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Stummschaltung der Umgebungsgeräusche aufheben"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatische Untertitel"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Einstellungen"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notiz"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Blockierung des Gerätemikrofons aufheben?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Blockierung der Gerätekamera aufheben?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Wenn du eine App streamst, ist für <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> alles sichtbar, was in dieser App angezeigt oder abgespielt wird. Sei also vorsichtig mit Informationen wie Passwörtern, Zahlungsdetails, Nachrichten, Fotos sowie Audio- und Videoinhalten."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Bildschirm teilen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> hat diese Option deaktiviert"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"App zum Teilen auswählen"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Bildschirm streamen?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Eine App streamen"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"An – gesichtsbasiert"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Fertig"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Anwenden"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Benachrichtigungen deaktivieren"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Lautlos"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Splitscreen mit der App auf der rechten Seite nutzen"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Splitscreen mit der App auf der linken Seite nutzen"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Vollbildmodus verwenden"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Desktop-Windowing verwenden"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Im Splitscreen-Modus zu einer App rechts oder unten wechseln"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Im Splitscreen-Modus zu einer App links oder oben wechseln"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Im Splitscreen: eine App durch eine andere ersetzen"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Zum Entfernen hierher ziehen"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Du brauchst mindestens <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> Kacheln"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Bearbeiten"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Uhrzeit"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Stunden, Minuten und Sekunden anzeigen"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Zur Position <xliff:g id="POSITION">%1$d</xliff:g> hinzufügen"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Position ist ungültig."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Kachel bereits hinzugefügt"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ansicht hinzugefügt"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ansicht entfernt"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor für Schnelleinstellungen."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Mediensteuerung für <xliff:g id="APP_NAME">%1$s</xliff:g> ausblenden?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Die Mediensitzung kann nicht ausgeblendet werden."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ausblenden"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> von <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wird gerade über <xliff:g id="APP_LABEL">%3$s</xliff:g> wiedergegeben"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> von <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-de/tiles_states_strings.xml b/packages/SystemUI/res/values-de/tiles_states_strings.xml
index 44734ae..ecae8dc 100644
--- a/packages/SystemUI/res/values-de/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-de/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Aus"</item>
     <item msgid="4875147066469902392">"An"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nicht verfügbar"</item>
+    <item msgid="8589336868985358191">"Aus"</item>
+    <item msgid="726072717827778234">"An"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nicht verfügbar"</item>
     <item msgid="5044688398303285224">"Aus"</item>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index daebf70..2c17a39 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Κάντε κλικ για σύζευξη νέας συσκευής"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Δεν ήταν δυνατή η ενημέρωση της προεπιλογής"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Προεπιλογή"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Έχει επιλεγεί"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ήχοι περιβάλλοντος"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Αριστερά"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Δεξιά"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ήχοι περιβάλλοντος"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ήχοι περιβάλλοντος στα αριστερά"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ήχοι περιβάλλοντος στα δεξιά"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Ανάπτυξη σε ξεχωριστά στοιχεία ελέγχου αριστερά και δεξιά"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Σύμπτυξη σε ενοποιημένο στοιχείο ελέγχου"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Σίγαση ήχων περιβάλλοντος"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Κατάργηση σίγασης ήχων περιβάλλοντος"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Εργαλεία"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ζωντανοί υπότιτλοι"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ρυθμίσεις"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Σημείωση"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Κατάργηση αποκλεισμού μικροφώνου συσκευής;"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Κατάργηση αποκλεισμού κάμερας συσκευής;"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Όταν μοιράζεστε μια εφαρμογή, οτιδήποτε εμφανίζεται ή αναπαράγεται σε αυτή την εφαρμογή, είναι ορατό στην εφαρμογή <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Επομένως, να είστε προσεκτικοί με τους κωδικούς πρόσβασης, τα στοιχεία πληρωμής, τα μηνύματα, τις φωτογραφίες, τον ήχο και το βίντεο."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Κοινή χρήση οθόνης"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> απενεργοποίησε αυτή την επιλογή"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Επιλογή εφαρμογής για κοινή χρήση"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Να γίνει μετάδοση της οθόνης σας;"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Μετάδοση μίας εφαρμογής"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ενεργό - Βάσει προσώπου"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Τέλος"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Εφαρμογή"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Απενεργοποίηση ειδοποιήσεων"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Σίγαση"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Προεπιλογή"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Αυτόματο"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Χρήση διαχωρισμού οθόνης με την εφαρμογή στα δεξιά"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Χρήση διαχωρισμού οθόνης με την εφαρμογή στα αριστερά"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Χρήση πλήρους οθόνης"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Χρήση της λειτουργίας προσαρμογής σε παράθυρο στην επιφάνεια εργασίας"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Εναλλαγή στην εφαρμογή δεξιά ή κάτω κατά τη χρήση διαχωρισμού οθόνης"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Εναλλαγή σε εφαρμογή αριστερά ή επάνω κατά τη χρήση διαχωρισμού οθόνης"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Κατά τον διαχωρισμό οθόνης: αντικατάσταση μιας εφαρμογής με άλλη"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Σύρετε εδώ για κατάργηση"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Χρειάζεστε τουλάχιστον <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> πλακίδια"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Επεξεργασία"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Ώρα"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Να εμφανίζονται ώρες, λεπτά και δευτερόλεπτα"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Προσθήκη στη θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Μη έγκυρη θέση."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Θέση <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Το πλακίδιο έχει ήδη προστεθεί"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Το πλακίδιο προστέθηκε"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Το πλακίδιο καταργήθηκε"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Επεξεργασία γρήγορων ρυθμίσεων."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Απόκρυψη στοιχ. ελέγχου μέσων για <xliff:g id="APP_NAME">%1$s</xliff:g>;"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Αδυναμία απόκρ. τρέχουσας περιόδ. λειτουργ. μέσου."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Απόκρυψη"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ρυθμίσεις"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Γίνεται αναπαραγωγή του <xliff:g id="SONG_NAME">%1$s</xliff:g> από <xliff:g id="ARTIST_NAME">%2$s</xliff:g> στην εφαρμογή <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> από <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-el/tiles_states_strings.xml b/packages/SystemUI/res/values-el/tiles_states_strings.xml
index b649db4..d8910b3 100644
--- a/packages/SystemUI/res/values-el/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-el/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Ανενεργό"</item>
     <item msgid="4875147066469902392">"Ενεργό"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Μη διαθέσιμο"</item>
+    <item msgid="8589336868985358191">"Ανενεργό"</item>
+    <item msgid="726072717827778234">"Ενεργό"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Μη διαθέσιμο"</item>
     <item msgid="5044688398303285224">"Ανενεργός"</item>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 875b21a..7b8f982 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Unmute surroundings"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Settings"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"When you\'re sharing an app, anything shown or played in that app is visible to <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Share screen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choose app to share"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Cast your screen?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast one app"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On – Face-based"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Done"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Apply"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Turn off notifications"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use split screen with app on the right"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use split screen with app on the left"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use fullscreen"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use desktop windowing"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Time"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Show hours, minutes and seconds"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
index e17eeb2..3014e62 100644
--- a/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Off"</item>
     <item msgid="4875147066469902392">"On"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Unavailable"</item>
+    <item msgid="8589336868985358191">"Off"</item>
+    <item msgid="726072717827778234">"On"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Unavailable"</item>
     <item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 4e4295a..15056c6 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -419,6 +419,11 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <string name="hearing_devices_input_routing_label" msgid="730396728151232306">"Default microphone for calls"</string>
+  <string-array name="hearing_device_input_routing_options">
+    <item msgid="4582190415045337003">"Hearing aid microphone"</item>
+    <item msgid="8501466270452446450">"This phone\'s microphone"</item>
+  </string-array>
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
@@ -582,6 +587,7 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"When you’re sharing an app, anything shown or played in that app is visible to <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. So be careful with things like passwords, payment details, messages, photos, and audio and video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Share screen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
+    <string name="media_projection_entry_app_permission_dialog_single_app_not_supported" msgid="4860247304058870233">"Not supported by the app"</string>
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choose app to share"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Cast your screen?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast one app"</string>
@@ -794,7 +800,7 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On - Face-based"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Done"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Apply"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Turn off notifications"</string>
+    <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Turn off"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
@@ -905,8 +911,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use split screen with app on the right"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use split screen with app on the left"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use full screen"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use desktop windowing"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to app on right or below while using split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to app on left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: replace an app from one to another"</string>
@@ -980,6 +985,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Time"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Show hours, minutes, and seconds"</item>
@@ -1203,7 +1210,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
index e17eeb2..3014e62 100644
--- a/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Off"</item>
     <item msgid="4875147066469902392">"On"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Unavailable"</item>
+    <item msgid="8589336868985358191">"Off"</item>
+    <item msgid="726072717827778234">"On"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Unavailable"</item>
     <item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 875b21a..7b8f982 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Unmute surroundings"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Settings"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"When you\'re sharing an app, anything shown or played in that app is visible to <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Share screen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choose app to share"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Cast your screen?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast one app"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On – Face-based"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Done"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Apply"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Turn off notifications"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use split screen with app on the right"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use split screen with app on the left"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use fullscreen"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use desktop windowing"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Time"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Show hours, minutes and seconds"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
index e17eeb2..3014e62 100644
--- a/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Off"</item>
     <item msgid="4875147066469902392">"On"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Unavailable"</item>
+    <item msgid="8589336868985358191">"Off"</item>
+    <item msgid="726072717827778234">"On"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Unavailable"</item>
     <item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 875b21a..7b8f982 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Click to pair new device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Couldn\'t update preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selected"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Surroundings"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Left"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Unmute surroundings"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Settings"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Unblock device microphone?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Unblock device camera?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"When you\'re sharing an app, anything shown or played in that app is visible to <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. So be careful with things like passwords, payment details, messages, photos, audio and video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Share screen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> has disabled this option"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choose app to share"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Cast your screen?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast one app"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On – Face-based"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Done"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Apply"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Turn off notifications"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatic"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use split screen with app on the right"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use split screen with app on the left"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use fullscreen"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use desktop windowing"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Switch to the app on the right or below while using split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Switch to the app on the left or above while using split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"During split screen: Replace an app from one to another"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Drag here to remove"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"You need at least <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tiles"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Time"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Show hours, minutes and seconds"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Hide this media control for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"The current media session cannot be hidden."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Hide"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Resume"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Settings"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> by <xliff:g id="ARTIST_NAME">%2$s</xliff:g> is playing from <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> of <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
index e17eeb2..3014e62 100644
--- a/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Off"</item>
     <item msgid="4875147066469902392">"On"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Unavailable"</item>
+    <item msgid="8589336868985358191">"Off"</item>
+    <item msgid="726072717827778234">"On"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Unavailable"</item>
     <item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c2dd040..1b15b1b 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para vincular un dispositivo nuevo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No se pudo actualizar el ajuste predeterminado"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ajuste predeterminado"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Sonido envolvente"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Izquierda"</string>
@@ -582,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Cuando compartes una app, todo lo que se muestre o reproduzca en ella será visible en <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Por lo tanto, debes tener cuidado con contraseñas, detalles de pagos, mensajes, fotos, audios y videos."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartir pantalla"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> inhabilitó esta opción"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Elige la app para compartir"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"¿Quieres transmitir la pantalla?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir una app"</string>
@@ -794,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activa - En función del rostro"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Listo"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactivar notificaciones"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silenciada"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminada"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
@@ -905,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar la pantalla dividida con la app a la derecha"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar la pantalla dividida con la app a la izquierda"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar la pantalla completa"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar renderización en ventanas para computadoras de escritorio"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ubicar la app a la derecha o abajo cuando usas la pantalla dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ubicar la app a la izquierda o arriba cuando usas la pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante pantalla dividida: Reemplaza una app con otra"</string>
@@ -980,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastra aquí para quitar"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Necesitas al menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tarjetas"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Mostrar horas, minutos y segundos"</item>
@@ -1203,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"¿Ocultar control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"No se puede ocultar la sesión multimedia actual."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
index 91f5f88..3310d2b 100644
--- a/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"Desactivado"</item>
     <item msgid="4875147066469902392">"Activado"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"No disponible"</item>
     <item msgid="5044688398303285224">"Desactivada"</item>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 7902db8..2311b48 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Haz clic para emparejar un nuevo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"No se ha podido actualizar el preajuste"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preajuste"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seleccionado"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Alrededores"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Izquierda"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Derecha"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Entorno"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Entorno izquierdo"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Entorno derecho"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Expandir a los controles separados de izquierda y derecha"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Contraer al control unificado"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar alrededores"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Dejar de silenciar alrededores"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Herramientas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos automáticos"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ajustes"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"¿Desbloquear el micrófono del dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"¿Desbloquear la cámara del dispositivo?"</string>
@@ -517,7 +517,7 @@
     <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Desliza hacia la izquierda para iniciar el tutorial de la comunidad"</string>
     <string name="cta_tile_button_to_open_widget_editor" msgid="3871562362382963878">"Personalizar"</string>
     <string name="cta_tile_button_to_dismiss" msgid="3377597875997861754">"Cerrar"</string>
-    <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Añade, elimina y reordena tus widgets en este espacio"</string>
+    <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Añade, elimina y reordena tus widgets"</string>
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Añade más widgets"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Mantén pulsado para personalizar los widgets"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Personalizar widgets"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Cuando compartes una aplicación, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> puede ver todo lo que se muestra o reproduce en ella. Debes tener cuidado con elementos como contraseñas, detalles de pagos, mensajes, fotos, audio y vídeo."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartir pantalla"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha inhabilitado esta opción"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Elige la aplicación que quieres compartir"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"¿Enviar tu pantalla?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Enviar una aplicación"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activado: basado en caras"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Hecho"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactivar notificaciones"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silencio"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predeterminado"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar la pantalla dividida con la aplicación a la derecha"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar la pantalla dividida con la aplicación a la izquierda"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar pantalla completa"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar el escritorio basado en ventanas"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar a la aplicación de la derecha o de abajo en pantalla dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar a la app de la izquierda o de arriba en pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Con pantalla dividida: reemplazar una aplicación por otra"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastra aquí para quitar una función"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Necesitas al menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> recuadros"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Mostrar horas, minutos y segundos"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Añadir a la posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición no válida."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Tarjeta ya añadida"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Recuadro añadido"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Recuadro quitado"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de ajustes rápidos."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"¿Ocultar este control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"La sesión multimedia no se puede ocultar."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ajustes"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Se está reproduciendo <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-es/tiles_states_strings.xml b/packages/SystemUI/res/values-es/tiles_states_strings.xml
index c5b6c2e..546190f 100644
--- a/packages/SystemUI/res/values-es/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-es/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"Desactivado"</item>
     <item msgid="4875147066469902392">"Activado"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"No disponible"</item>
     <item msgid="5044688398303285224">"Desactivado"</item>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 723a3eb1..9d22171 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Uue seadme sidumiseks klõpsake"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Eelseadistust ei saanud värskendada"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Eelseadistus"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valitud"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ümbritsevad helid"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vasakule"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Paremale"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ümbritsevad helid"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Vasak ümbrus"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Parem ümbrus"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Vasaku ja parema poole eraldi juhtimine"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Mõlema poole ühtne juhtimine"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ümbritsevate helide vaigistamine"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ümbritsevate helide vaigistuse tühistamine"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tööriistad"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Reaalajas subtiitrid"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Seaded"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Märkus"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kas tühistada seadme mikrofoni blokeerimine?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kas tühistada seadme kaamera blokeerimine?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Rakenduse jagamisel on kogu rakenduses kuvatav või esitatav sisu nähtav rakendusele <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Seega olge ettevaatlik selliste andmetega nagu paroolid, makseteave, sõnumid, fotod ning heli ja video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Jaga ekraani"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> on selle valiku keelanud"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Vali jagamiseks rakendus"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Kas kanda ekraanikuva üle?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Ühe rakenduse ülekandmine"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Sees – näopõhine"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Valmis"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Rakenda"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Lülita märguanded välja"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Hääletu"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Vaikeseade"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automaatne"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Jagatud ekraanikuva kasutamine, rakendus kuvatakse paremal"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Jagatud ekraanikuva kasutamine, rakendus kuvatakse vasakul"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Lülita täisekraanile"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Kasuta töölaua aknaid"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Paremale või alumisele rakendusele lülitamine jagatud ekraani ajal"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vasakule või ülemisele rakendusele lülitamine jagatud ekraani ajal"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekraanikuva jagamise ajal: ühe rakenduse asendamine teisega"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Lohistage eemaldamiseks siia"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Teil on vaja vähemalt <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> paani"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Muutmine"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Kellaaeg"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Kuva tunnid, minutid ja sekundid"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisamine asendisse <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Sobimatu asukoht."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Asend <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Paan on juba lisatud"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Paan on lisatud"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Paan on eemaldatud"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kiirseadete redigeerija."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Kas peita see rakenduse <xliff:g id="APP_NAME">%1$s</xliff:g> meediajuhik?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Praegust meediaseanssi ei saa peita."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Peida"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Seaded"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> esitajalt <xliff:g id="ARTIST_NAME">%2$s</xliff:g> esitatakse rakenduses <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-et/tiles_states_strings.xml b/packages/SystemUI/res/values-et/tiles_states_strings.xml
index e9949bf..819e976 100644
--- a/packages/SystemUI/res/values-et/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-et/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Väljas"</item>
     <item msgid="4875147066469902392">"Sees"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Pole saadaval"</item>
+    <item msgid="8589336868985358191">"Väljas"</item>
+    <item msgid="726072717827778234">"Sees"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Pole saadaval"</item>
     <item msgid="5044688398303285224">"Väljas"</item>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 55b223a..443632b 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Egin klik beste gailu bat parekatzeko"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ezin izan da eguneratu aurrezarpena"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Aurrezarpena"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Hautatuta"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ingurunea"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ezkerrekoa"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Eskuinekoa"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ingurunea"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ezkerreko ingurunea"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Eskuineko ingurunea"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Zabaldu ezkerreko eta eskuineko kontrolatzeko aukerak bereiz erabiltzeko"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Tolestu kontrolatzeko aukerak bateratuta erabiltzeko"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Desaktibatu ingurunearen audioa"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Aktibatu ingurunearen audioa"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tresnak"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Istanteko azpitituluak"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ezarpenak"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Oharra"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Gailuaren mikrofonoa desblokeatu nahi duzu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Gailuaren kamera desblokeatu nahi duzu?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Aplikazio bat partekatzen ari zarenean, aplikazio horretan agertzen den edo bertan erreproduzitzen ari den guztia ikusi dezake <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> aplikazioak. Beraz, kontuz ibili pasahitzekin, ordainketen xehetasunekin, mezuekin, argazkiekin, audioekin eta bideoekin, besteak beste."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Partekatu pantaila"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> aplikazioak aukera desgaitu du"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Aukeratu zein aplikazio partekatu nahi duzun"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Pantaila igorri nahi duzu?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Igorri aplikazio bat"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aktibatuta: aurpegian oinarrituta"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Eginda"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplikatu"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desaktibatu jakinarazpenak"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Isila"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Lehenetsia"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikoa"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Erabili pantaila zatitua eta ezarri aplikazio hau eskuinean"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Erabili pantaila zatitua eta ezarri aplikazio hau ezkerrean"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Erabili pantaila osoa"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Erabili ordenagailuan leihoak erabiltzeko modua"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Aldatu eskuineko edo beheko aplikaziora pantaila zatitua erabiltzean"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Aldatu ezkerreko edo goiko aplikaziora pantaila zatitua erabiltzean"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Pantaila zatituan zaudela, ordeztu aplikazio bat beste batekin"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Kentzeko, arrastatu hona"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> lauza behar dituzu gutxienez"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editatu"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Ordua"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Erakutsi orduak, minutuak eta segundoak"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Gehitu <xliff:g id="POSITION">%1$d</xliff:g>garren lekuan"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Kokapenak ez du balio."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>garren lekua"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Lauza gehituta dago jada"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Gehitu da lauza"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kendu da lauza"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ezarpen bizkorren editorea."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Multimedia kontrolatzeko aukerak (<xliff:g id="APP_NAME">%1$s</xliff:g>) ezkutatu?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Ezin da ezkutatu multimedia-saioa."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ezkutatu"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>) ari da erreproduzitzen <xliff:g id="APP_LABEL">%3$s</xliff:g> bidez"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
@@ -1576,6 +1578,5 @@
     <string name="qs_edit_mode_category_unknown" msgid="509314252124053550">"Ezezagunak"</string>
     <string name="qs_edit_mode_reset_dialog_title" msgid="5344853290033761627">"Lauza guztiak berrezarri nahi dituzu?"</string>
     <string name="qs_edit_mode_reset_dialog_content" msgid="7474773130622653653">"Gailuaren jatorrizko ezarpenak berrezarriko dira ezarpen bizkorren lauza guztietan"</string>
-    <!-- no translation found for volume_slider_disabled_message_template (1305088816797803460) -->
-    <skip />
+    <string name="volume_slider_disabled_message_template" msgid="1305088816797803460">"<xliff:g id="STREAM_NAME">%1$s</xliff:g>, <xliff:g id="DISABLED_MESSAGE">%2$s</xliff:g>"</string>
 </resources>
diff --git a/packages/SystemUI/res/values-eu/tiles_states_strings.xml b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
index e47b658..923d84f 100644
--- a/packages/SystemUI/res/values-eu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-eu/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"Desaktibatuta"</item>
     <item msgid="4875147066469902392">"Aktibatuta"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Ez dago erabilgarri"</item>
     <item msgid="5044688398303285224">"Desaktibatuta"</item>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index c28ec97..58f35d1 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"برای جفت کردن دستگاه جدید، کلیک کنید"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"پیش‌تنظیم به‌روزرسانی نشد"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"پیش‌تنظیم"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"انتخاب‌شده"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"پیرامون"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"چپ"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"راست"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"پیرامون"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"پیرامون چپ"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"پیرامون راست"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ازهم بازکردن برای کنترل‌های جداگانه چپ و راست"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"جمع کردن برای کنترل یکپارچه"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"بی‌صدا کردن پیرامون"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"صدادار کردن پیرامون"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ابزارها"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"زیرنویس زنده ناشنوایان"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"تنظیمات"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"یادداشت"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"میکروفون دستگاه لغو انسداد شود؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"دوربین دستگاه لغو انسداد شود؟"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"وقتی برنامه‌ای را هم‌رسانی می‌کنید، هر چیزی که در آن برنامه نمایش داده شود یا پخش شود برای <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> قابل‌مشاهده خواهد بود. درنتیجه مراقب چیزهایی مثل گذرواژه‌ها، جزئیات پرداخت، پیام‌ها، عکس‌ها، و صدا و تصویر باشید."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"هم‌رسانی صفحه‌نمایش"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>این گزینه را غیرفعال کرده است"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"برنامه‌ای را برای هم‌رسانی انتخاب کنید"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"محتوای صفحه‌نمایش شما پخش شود؟"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"پخش کردن محتوای یک برنامه"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"روشن - براساس چهره"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"تمام"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"اعمال"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"خاموش کردن اعلان‌ها"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"بی‌صدا"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"پیش‌فرض"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"خودکار"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"استفاده از صفحهٔ دونیمه با قرار گرفتن برنامه در سمت راست"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"استفاده از صفحهٔ دونیمه با قرار گرفتن برنامه در سمت چپ"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"استفاده از حالت تمام‌صفحه"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"استفاده از پردازش پنجره‌ای رایانه"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"رفتن به برنامه سمت راست یا پایین درحین استفاده از صفحهٔ دونیمه"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"رفتن به برنامه سمت چپ یا بالا درحین استفاده از صفحهٔ دونیمه"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"درحین صفحهٔ دونیمه: برنامه‌ای را با دیگری جابه‌جا می‌کند"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"برای حذف، به اینجا بکشید"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"حداقل به <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> کاشی نیاز دارید"</string>
     <string name="qs_edit" msgid="5583565172803472437">"ویرایش"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"زمان"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ساعت، دقیقه و ثانیه نشان داده شود"</item>
@@ -1207,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"این کنترل رسانه برای <xliff:g id="APP_NAME">%1$s</xliff:g> پنهان شود؟"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"جلسه رسانه کنونی نمی‌تواند پنهان شود."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"پنهان کردن"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"ازسرگیری"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"تنظیمات"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> از <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ازطریق <xliff:g id="APP_LABEL">%3$s</xliff:g> پخش می‌شود"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> از <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fa/tiles_states_strings.xml b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
index 1025f3d..68ca663 100644
--- a/packages/SystemUI/res/values-fa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fa/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"خاموش"</item>
     <item msgid="4875147066469902392">"روشن"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"دردسترس نیست"</item>
+    <item msgid="8589336868985358191">"خاموش"</item>
+    <item msgid="726072717827778234">"روشن"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"دردسترس نیست"</item>
     <item msgid="5044688398303285224">"خاموش"</item>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 98f4883..1b767db 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -421,24 +421,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Muodosta uusi laitepari klikkaamalla"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Esiasetusta ei voitu muuttaa"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Esiasetus"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valittu"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ympäristö"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vasen"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Oikea"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ympäristö"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ympäristö vasemmalla"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ympäristö oikealla"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Laajenna vasemmalle ja oikealle erilliset ohjaimet"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Tiivistä yhtenäiseksi säätimeksi"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Mykistä ympäristö"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Poista ympäristön mykistys"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Työkalut"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Livetekstitys"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Asetukset"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Muistiinpano"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Kumotaanko laitteen mikrofonin esto?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Kumotaanko laitteen kameran esto?"</string>
@@ -588,6 +588,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kun jaat sovelluksen, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> näkee kaiken sovelluksessa näkyvän tai toistetun sisällön. Ole siis varovainen, kun lisäät salasanoja, maksutietoja, viestejä, kuvia, audiota tai videoita."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Jaa näyttö"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> on poistanut vaihtoehdon käytöstä"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Valitse jaettava sovellus"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Striimataanko näyttö?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Striimaa yksi sovellus"</string>
@@ -800,7 +802,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Päällä – kasvojen perusteella"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Valmis"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Käytä"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Poista ilmoitukset käytöstä"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Äänetön"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Oletus"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automaattinen"</string>
@@ -911,8 +914,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Käytä jaettua näyttöä niin, että sovellus on oikealla"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Käytä jaettua näyttöä niin, että sovellus on vasemmalla"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Käytä koko näytön tilaa"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Käytä työpöydän ikkunointia"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Vaihda sovellukseen oikealla tai alapuolella jaetussa näytössä"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Vaihda sovellukseen vasemmalla tai yläpuolella jaetussa näytössä"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Jaetun näytön aikana: korvaa sovellus toisella"</string>
@@ -986,6 +988,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Poista vetämällä tähän."</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kiekkoa on vähimmäismäärä"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Muokkaa"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Aika"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Näytä tunnit, minuutit ja sekunnit"</item>
@@ -1008,8 +1012,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Lisää paikkaan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Virheellinen sijainti."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Paikka <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Laatta on jo lisätty"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kiekko lisätty"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kiekko poistettu"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Pika-asetusten muokkausnäkymä"</string>
@@ -1210,7 +1213,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Piilotetaanko mediaohjain (<xliff:g id="APP_NAME">%1$s</xliff:g>)?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Tätä median käyttökertaa ei voi piilottaa."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Piilota"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Jatka"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Asetukset"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> soittaa nyt tätä: <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fi/tiles_states_strings.xml b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
index 5452f26..12487bd 100644
--- a/packages/SystemUI/res/values-fi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fi/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Poissa päältä"</item>
     <item msgid="4875147066469902392">"Päällä"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Ei saatavilla"</item>
+    <item msgid="8589336868985358191">"Pois päältä"</item>
+    <item msgid="726072717827778234">"Päällä"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Ei saatavilla"</item>
     <item msgid="5044688398303285224">"Poissa päältä"</item>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 95adcd3..2a315e4 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquez ici pour associer un nouvel appareil"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour le préréglage"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Environnement"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Gauche"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Droit"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Environnement"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Environnement à gauche"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Environnement à droite"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Développer les commandes distinctes à gauche et à droite"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Passer au contrôle unifié"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Ignorer les sons de l\'environnement"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Réactiver les sons de l\'environnement"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Paramètres"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le microphone de l\'appareil?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer l\'appareil photo de l\'appareil?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Lorsque vous partagez une appli, tout ce qui s\'y affiche ou s\'y joue est visible par <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Par conséquent, soyez prudent avec 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="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Partager l\'écran"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a désactivé cette option"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choisir l\'appli à partager"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Diffuser votre écran?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Diffuser une appli"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activé : en fonction du visage"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Terminé"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Appliquer"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Désactiver les notifications"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Mode silencieux"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Par défaut"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Utiliser l\'Écran divisé avec l\'appli à droite"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Utiliser l\'Écran divisé avec l\'appli à gauche"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Utiliser le mode plein écran"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Utiliser le fenêtrage du bureau"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'Écran divisé"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passer à l\'appli à gauche ou au-dessus avec l\'Écran divisé"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode d\'écran divisé : remplacer une appli par une autre"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Faites glisser les tuiles ici pour les retirer"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Vous avez besoin d\'au moins <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tuiles"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Modifier"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Heure"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Afficher les heures, les minutes et les secondes"</item>
@@ -1207,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Masquer ce contrôleur de contenu multimédia pour <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Impossible de masquer la session multimédia actuelle"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecteur à partir de <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
index 487c566..6b94691 100644
--- a/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Désactivée"</item>
     <item msgid="4875147066469902392">"Activé"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Non accessible"</item>
+    <item msgid="8589336868985358191">"Désactivé"</item>
+    <item msgid="726072717827778234">"Activé"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Non disponible"</item>
     <item msgid="5044688398303285224">"Désactivée"</item>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 04c147c..d7e9d44 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Cliquer pour associer un nouvel appareil"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossible de mettre à jour les préréglages"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Préréglage"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Sélectionné"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Sons environnants"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Gauche"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Droite"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Sons environnants"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Environnement à gauche"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Environnement à droite"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Développer les commandes gauche et droite"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Réduire en une commande unifiée"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Couper le mode Sons environnants"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Réactiver le mode Sons environnants"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Outils"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sous-titres instantanés"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Paramètres"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Note"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Débloquer le micro de l\'appareil ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Débloquer la caméra de l\'appareil ?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Lorsque vous partagez une appli, tout ce qui est affiché ou lu dans celle-ci est visible par <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. 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="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Partager l\'écran"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a désactivé cette option"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Choisir l\'appli à partager"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Caster votre écran ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Caster une appli"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Active - En fonction du visage"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"OK"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Appliquer"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Désactiver les notifications"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silencieux"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Par défaut"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatique"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Utiliser l\'écran partagé avec l\'appli sur la droite"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Utiliser l\'écran partagé avec l\'appli sur la gauche"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Utiliser le mode plein écran"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Utiliser le fenêtrage de l\'ordinateur"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passer à l\'appli à droite ou en dessous avec l\'écran partagé"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passez à l\'appli à gauche ou au-dessus avec l\'écran partagé"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"En mode écran partagé : Remplacer une appli par une autre"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Faites glisser les blocs ici pour les supprimer"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Au minimum <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tuiles sont nécessaires"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Modifier"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Heure"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Afficher les heures, les minutes et les secondes"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ajouter à la position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Emplacement non valide."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Position <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"La carte a déjà été ajoutée"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloc ajouté"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloc supprimé"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Éditeur Réglages rapides"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Masquer cette commande multimédia pour <xliff:g id="APP_NAME">%1$s</xliff:g> ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Session multimédia en cours impossible à masquer."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Masquer"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> par <xliff:g id="ARTIST_NAME">%2$s</xliff:g> est en cours de lecture depuis <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sur <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-fr/tiles_states_strings.xml b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
index 52c7c0c..ea91d2f 100644
--- a/packages/SystemUI/res/values-fr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-fr/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Désactivé"</item>
     <item msgid="4875147066469902392">"Activé"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Indisponible"</item>
+    <item msgid="8589336868985358191">"Désactivé"</item>
+    <item msgid="726072717827778234">"Activé"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Indisponible"</item>
     <item msgid="5044688398303285224">"Désactivé"</item>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 6ab779a2..f4a4ceb 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic para vincular un novo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Non se puido actualizar a configuración predeterminada"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Configuración predeterminada"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Elemento seleccionado"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambiente"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerdo"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Dereito"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ambiente"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ambiente á esquerda"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ambiente á dereita"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Despregar para controis separados do lado esquerdo e do dereito"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Contraer para control unificado"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar o ambiente"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Activar o son ambiental"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtítulos instantáneos"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Configuración"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Queres desbloquear o micrófono do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Queres desbloquear a cámara do dispositivo?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Se compartes toda a pantalla, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> poderá ver todo o contido que apareza ou se reproduza nesa aplicación. Ten coidado con determinada información, como os contrasinais, os detalles de pago, as mensaxes e as fotos, así como co contido de audio e de vídeo."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartir pantalla"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> desactivou esta opción"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Escoller unha aplicación para compartir"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Queres emitir a túa pantalla?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emitir unha aplicación"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activada: baseada na cara"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Feito"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desactivar notificacións"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silenciadas"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Configuración predeterminada"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar pantalla dividida coa aplicación na dereita"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar pantalla dividida coa aplicación na esquerda"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar a pantalla completa"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar as ventás do ordenador"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Cambiar á aplicación da dereita ou de abaixo coa pantalla dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Cambiar á aplicación da esquerda ou de arriba coa pantalla dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"En modo de pantalla dividida: Substituír unha aplicación por outra"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastra o elemento ata aquí para quitalo"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Como mínimo ten que haber <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> mosaicos"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Mostrar horas, minutos e segundos"</item>
@@ -997,17 +1001,16 @@
   </string-array>
     <string name="tuner_low_priority" msgid="8412666814123009820">"Mostrar iconas das notificacións que teñan baixa prioridade"</string>
     <string name="other" msgid="429768510980739978">"Outros"</string>
-    <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"activar/desactivar o tamaño do recadro"</string>
-    <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"quitar tarxeta"</string>
+    <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"cambiar o tamaño do atallo"</string>
+    <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"quitar atallo"</string>
     <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"engadir o atallo á última posición"</string>
-    <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover tarxeta"</string>
+    <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"Mover atallo"</string>
     <string name="accessibility_qs_edit_tile_start_add" msgid="8141710006899065161">"Engadir o atallo á última posición"</string>
     <string name="accessibility_qs_edit_tile_move_to_position" msgid="5198161544045930556">"Mover a <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engadir á posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posición non válida."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posición <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Atallo xa engadido"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Engadiuse a tarxeta"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Quitouse a tarxeta"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configuración rápida."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Queres ocultar este control multimedia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Non se pode ocultar esta sesión multimedia."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Estase reproducindo <xliff:g id="SONG_NAME">%1$s</xliff:g>, de <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, en <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-gl/tiles_states_strings.xml b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
index 7cf5f82..9b05a87 100644
--- a/packages/SystemUI/res/values-gl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gl/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Non"</item>
     <item msgid="4875147066469902392">"Si"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Non dispoñible"</item>
+    <item msgid="8589336868985358191">"Desactivado"</item>
+    <item msgid="726072717827778234">"Activado"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Non dispoñible"</item>
     <item msgid="5044688398303285224">"Non"</item>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index a0dbf73..2a8fe31 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -252,10 +252,8 @@
     <string name="accessibility_bluetooth_name" msgid="7300973230214067678">"<xliff:g id="BLUETOOTH">%s</xliff:g> થી કનેક્ટ થયાં."</string>
     <string name="accessibility_cast_name" msgid="7344437925388773685">"<xliff:g id="CAST">%s</xliff:g> થી કનેક્ટ કરેલ."</string>
     <string name="accessibility_expand_group" msgid="521237935987978624">"ગ્રૂપને મોટું કરો."</string>
-    <!-- no translation found for accessibility_add_device_to_group (5446422960697860806) -->
-    <skip />
-    <!-- no translation found for accessibility_remove_device_from_group (3114694270949142228) -->
-    <skip />
+    <string name="accessibility_add_device_to_group" msgid="5446422960697860806">"ડિવાઇસને ગ્રૂપમાં ઉમેરો."</string>
+    <string name="accessibility_remove_device_from_group" msgid="3114694270949142228">"ડિવાઇસને ગ્રૂપમાંથી કાઢી નાખો."</string>
     <string name="accessibility_open_application" msgid="1749126077501259712">"ઍપ્લિકેશન ખોલો."</string>
     <string name="accessibility_not_connected" msgid="4061305616351042142">"કનેક્ટ થયેલું નથી."</string>
     <string name="data_connection_roaming" msgid="375650836665414797">"રોમિંગ"</string>
@@ -333,8 +331,7 @@
     <string name="quick_settings_bluetooth_secondary_label_input" msgid="3887552721233148132">"ઇનપુટ"</string>
     <string name="quick_settings_bluetooth_secondary_label_hearing_aids" msgid="5553051568867097111">"સાંભળવામાં મદદ આપતા યંત્રો"</string>
     <string name="quick_settings_bluetooth_secondary_label_transient" msgid="3882884317600669650">"ચાલુ કરી રહ્યાં છીએ…"</string>
-    <!-- no translation found for quick_settings_brightness_unable_adjust_msg (4124028416057617517) -->
-    <skip />
+    <string name="quick_settings_brightness_unable_adjust_msg" msgid="4124028416057617517">"બ્રાઇટનેસ ગોઠવી શકાતી નથી કારણ કે તે લોકપ્રિય ઍપ દ્વારા નિયંત્રિત કરવામાં આવી રહી છે"</string>
     <string name="quick_settings_rotation_unlocked_label" msgid="2359922767950346112">"ઑટો રોટેટ"</string>
     <string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"ઑટો રોટેટ સ્ક્રીન"</string>
     <string name="quick_settings_location_label" msgid="2621868789013389163">"લોકેશન"</string>
@@ -422,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"નવા ડિવાઇસ સાથે જોડાણ કરવા માટે ક્લિક કરો"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"પ્રીસેટ અપડેટ કરી શક્યા નથી"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"પ્રીસેટ"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"પસંદ કરી છે"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"આસપાસના અવાજો"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ડાબે"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"જમણે"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"આસપાસના અવાજો"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ડાબી તરફથી આવતા અવાજો"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"જમણી તરફથી આવતા અવાજો"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ડાબે અને જમણે અલગ કરેલા નિયંત્રણો સુધી વિસ્તૃત કરો"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"એકીકૃત નિયંત્રણ સુધી નાનું કરો"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"આસપાસના અવાજો મ્યૂટ કરો"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"આસપાસના અવાજો અનમ્યૂટ કરો"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ટૂલ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"લાઇવ કૅપ્શન"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"સેટિંગ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"નોંધ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ડિવાઇસના માઇક્રોફોનને અનબ્લૉક કરીએ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ડિવાઇસના કૅમેરાને અનબ્લૉક કરીએ?"</string>
@@ -589,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"જ્યારે તમે કોઈ ઍપને શેર કરી રહ્યાં હો, ત્યારે તે ઍપ પર બતાવવામાં કે ચલાવવામાં આવતી હોય તેવી બધી વસ્તુ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ને દેખાય છે. તેથી પાસવર્ડ, ચુકવણીની વિગતો, મેસેજ, ફોટા અને ડિવાઇસ પર વાગી રહેલા ઑડિયો તથા વીડિયો જેવી બાબતોને લઈને સાવચેત રહો."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"સ્ક્રીન શેર કરો"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> દ્વારા આ વિકલ્પ બંધ કરવામાં આવ્યો છે"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"શેર કરવા માટે ઍપ પસંદ કરો"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"તમારી સ્ક્રીનને કાસ્ટ કરીએ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"એક ઍપને કાસ્ટ કરો"</string>
@@ -801,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ચાલુ છે - ચહેરા આધારિત રોટેશન"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"થઈ ગયું"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"લાગુ કરો"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"નોટિફિકેશન બંધ કરો"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"સાઇલન્ટ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ડિફૉલ્ટ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ઑટોમૅટિક રીતે"</string>
@@ -912,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"હાલની ઍપને જમણી બાજુએ રાખીને વિભાજિત સ્ક્રીનનો ઉપયોગ કરો"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"હાલની ઍપને ડાબી બાજુએ રાખીને વિભાજિત સ્ક્રીનનો ઉપયોગ કરો"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"પૂર્ણ સ્ક્રીનનો ઉપયોગ કરો"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ડેસ્કટૉપ વિન્ડોઇંગનો ઉપયોગ કરો"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે જમણી બાજુ કે નીચેની ઍપ પર સ્વિચ કરો"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"વિભાજિત સ્ક્રીનનો ઉપયોગ કરતી વખતે ડાબી બાજુની કે ઉપરની ઍપ પર સ્વિચ કરો"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"વિભાજિત સ્ક્રીન દરમિયાન: એક ઍપને બીજી ઍપમાં બદલો"</string>
@@ -987,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"દૂર કરવા માટે અહીં ખેંચો"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"તમને ઓછામાં ઓછી <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ટાઇલની જરૂર છે"</string>
     <string name="qs_edit" msgid="5583565172803472437">"ફેરફાર કરો"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"સમય"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"કલાક, મિનિટ અને સેકન્ડ બતાવો"</item>
@@ -1009,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"જગ્યા પર <xliff:g id="POSITION">%1$d</xliff:g> ઉમેરો"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"સ્થિતિ અમાન્ય છે."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"જગ્યા <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ટાઇલ પહેલેથી ઉમેરેલી છે"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ટાઇલ ઉમેરી"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ટાઇલ કાઢી નાખી"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ઝડપી સેટિંગ એડિટર."</string>
@@ -1211,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"શું <xliff:g id="APP_NAME">%1$s</xliff:g> માટે મીડિયાના નિયંત્રણો છુપાવીએ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"હાલનું મીડિયા સત્ર છુપાવી શકાતું નથી."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"છુપાવો"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> પર <xliff:g id="ARTIST_NAME">%2$s</xliff:g>નું <xliff:g id="SONG_NAME">%1$s</xliff:g> ગીત ચાલી રહ્યું છે"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>માંથી <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
@@ -1350,7 +1349,7 @@
     <string name="qs_tile_request_dialog_add" msgid="4888460910694986304">"ટાઇલ ઉમેરો"</string>
     <string name="qs_tile_request_dialog_not_add" msgid="4168716573114067296">"ટાઇલ ઉમેરશો નહીં"</string>
     <string name="qs_user_switch_dialog_title" msgid="3045189293587781366">"વપરાશકર્તા પસંદ કરો"</string>
-    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ઍપ સક્રિય છે}one{# ઍપ સક્રિય છે}other{# ઍપ સક્રિય છે}}"</string>
+    <string name="fgs_manager_footer_label" msgid="8276763570622288231">"{count,plural, =1{# ઍપ ઍક્ટિવ છે}one{# ઍપ ઍક્ટિવ છે}other{# ઍપ ઍક્ટિવ છે}}"</string>
     <string name="fgs_dot_content_description" msgid="2865071539464777240">"નવી માહિતી"</string>
     <string name="fgs_manager_dialog_title" msgid="5879184257257718677">"સક્રિય ઍપ"</string>
     <string name="fgs_manager_dialog_message" msgid="2670045017200730076">"જ્યારે તમે આ ઍપનો ઉપયોગ ન કરતા હો, ત્યારે પણ તે સક્રિય અને ચાલતી હોય છે. આનાથી તેની કાર્યક્ષમતામાં સુધારો થાય છે, પરંતુ બૅટરીની આવરદાને અસર પણ થઈ શકે છે."</string>
diff --git a/packages/SystemUI/res/values-gu/tiles_states_strings.xml b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
index a003106..c3fb941 100644
--- a/packages/SystemUI/res/values-gu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-gu/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"બંધ છે"</item>
     <item msgid="4875147066469902392">"ચાલુ છે"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"અનુપલબ્ધ"</item>
+    <item msgid="8589336868985358191">"બંધ"</item>
+    <item msgid="726072717827778234">"ચાલુ"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"ઉપલબ્ધ નથી"</item>
     <item msgid="5044688398303285224">"બંધ છે"</item>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 0b86661..922794d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नया डिवाइस जोड़ने के लिए क्लिक करें"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट नहीं किया जा सका"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चुना गया"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"आस-पास का वॉल्यूम"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"बाईं ओर के वॉल्यूम के लिए"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"दाईं ओर के वॉल्यूम के लिए"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"आस-पास का वॉल्यूम"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"बाईं ओर का वॉल्यूम"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"दाईं ओर का वॉल्यूम"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"दाईं और बाईं ओर के वॉल्यूम को अलग-अलग मैनेज करने के लिए, वॉल्यूम पैनल को बड़ा करें"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"यूनिफ़ाइड कंट्रोल पर जाने के लिए पैनल को छोटा करें"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"आस-पास के वॉल्यूम को म्यूट करें"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"आस-पास के वॉल्यूम को अनम्यूट करें"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव कैप्शन"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"सेटिंग"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"क्या आपको माइक्रोफ़ोन का ऐक्सेस अनब्लॉक करना है?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"क्या आपको कैमरे का ऐक्सेस अनब्लॉक करना है?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"जब कोई ऐप्लिकेशन शेयर किया जाता है, तो उस ऐप्लिकेशन में दिख रहा या चलाया जा रहा पूरा कॉन्टेंट <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> पर दिखता है. इसलिए, पासवर्ड, पेमेंट के तरीके की जानकारी, मैसेज, फ़ोटो, ऑडियो, और वीडियो को लेकर सावधानी बरतें."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"स्क्रीन शेयर करें"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ने इस विकल्प को बंद कर दिया है"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"शेयर करने के लिए ऐप्लिकेशन चुनें"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"क्या स्क्रीन को कास्ट करना है?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"एक ऐप्लिकेशन को कास्ट करें"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"चालू है - चेहरे की गतिविधि के हिसाब से कैमरे को घुमाने की सुविधा"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"हो गया"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"लागू करें"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"सूचनाएं बंद करें"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"बिना आवाज़ के सूचनाएं दिखाएं"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"डिफ़ॉल्ट"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"अपने-आप"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"स्प्लिट स्क्रीन की सुविधा चालू करें और इस ऐप्लिकेशन को दाईं ओर दिखाएं"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"स्प्लिट स्क्रीन की सुविधा चालू करें और इस ऐप्लिकेशन को बाईं ओर दिखाएं"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"फ़ुल स्क्रीन मोड का इस्तेमाल करें"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"डेस्कटॉप विंडोविंग का इस्तेमाल करें"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन पर, दाईं ओर या नीचे के ऐप पर स्विच करने के लिए"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन पर, बाईं ओर या ऊपर के ऐप पर स्विच करने के लिए"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीन के दौरान: एक ऐप्लिकेशन को दूसरे ऐप्लिकेशन से बदलें"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"हटाने के लिए यहां खींचें और छोड़ें"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"आपके पास कम से कम <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> टाइलें होनी चाहिए"</string>
     <string name="qs_edit" msgid="5583565172803472437">"बदलाव करें"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"समय"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"घंटे, मिनट और सेकंड दिखाएं"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल को <xliff:g id="POSITION">%1$d</xliff:g> पोज़िशन पर जोड़ें"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"मौजूदा जगह अमान्य है."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"टाइल की पोज़िशन <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"टाइल पहले से जोड़ा गया है"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल जोड़ी गई"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल हटाई गई"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"त्वरित सेटिंग संपादक."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"क्या <xliff:g id="APP_NAME">%1$s</xliff:g> के लिए, इस मीडिया कंट्रोल को छिपाना है?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"मौजूदा मीडिया सेशन को छिपाया नहीं जा सकता."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"छिपाएं"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"फिर से शुरू करें"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> पर, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> का <xliff:g id="SONG_NAME">%1$s</xliff:g> चल रहा है"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> में से <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-hi/tiles_states_strings.xml b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
index ae08316..d331e3a 100644
--- a/packages/SystemUI/res/values-hi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hi/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"बंद है"</item>
     <item msgid="4875147066469902392">"चालू है"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"उपलब्ध नहीं है"</item>
+    <item msgid="8589336868985358191">"बंद है"</item>
+    <item msgid="726072717827778234">"चालू है"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"उपलब्ध नहीं है"</item>
     <item msgid="5044688398303285224">"बंद है"</item>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 608b498..3213d59 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite da biste uparili novi uređaj"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ažuriranje unaprijed definiranih postavki nije uspjelo"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Unaprijed definirana postavka"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Odabrano"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okruženje"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lijevo"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Desno"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Okruženje"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Okruženje s lijeve strane"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Okruženje s desne strane"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Proširi u zasebne kontrole slijeva i zdesna"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sažmi u objedinjenu kontrolu"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Isključi zvuk okruženja"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Uključi zvuk okruženja"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alati"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Automatski titlovi"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Postavke"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Napomena"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Želite li deblokirati mikrofon uređaja?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Želite li deblokirati kameru uređaja?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kada dijelite aplikaciju, sve što se prikazuje ili reproducira u toj aplikaciji bit će vidljivo aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Stoga pazite na stvari kao što su zaporke, podaci o plaćanju, poruke, fotografije te audio i videozapisi."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Dijeljenje zaslona"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> onemogućila je ovu opciju"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Odaberite aplikaciju za dijeljenje"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Želite li emitirati zaslon?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Emitiranje jedne aplikacije"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Uključeno – na temelju lica"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Gotovo"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Primijeni"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Isključi obavijesti"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Bešumno"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Zadano"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatski"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Upotreba podijeljenog zaslona s aplikacijom s desne strane"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Upotreba podijeljenog zaslona s aplikacijom s lijeve strane"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Upotreba prikaza na cijelom zaslonu"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Upotreba prikaza u prozorima na računalu"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prelazak na aplikaciju zdesna ili ispod uz podijeljeni zaslon"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prelazak na aplikaciju slijeva ili iznad uz podijeljeni zaslon"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijekom podijeljenog zaslona: zamijeni aplikaciju drugom"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Povucite ovdje za uklanjanje"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Potrebno je barem <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> pločica"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Uređivanje"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Vrijeme"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Prikaži sate, minute i sekunde"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodavanje na položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Položaj nije važeći."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Položaj <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Pločica je već dodana"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartica je dodana"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartica je uklonjena"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Uređivač brzih postavki."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Želite li sakriti kontroler medija za aplikaciju <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Trenutačna medijska sesija ne može se sakriti."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sakrij"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g> reproducira se putem aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-hr/tiles_states_strings.xml b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
index 51b667c..5784d47 100644
--- a/packages/SystemUI/res/values-hr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hr/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Isključeno"</item>
     <item msgid="4875147066469902392">"Uključeno"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nedostupno"</item>
+    <item msgid="8589336868985358191">"Isključeno"</item>
+    <item msgid="726072717827778234">"Uključeno"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nedostupno"</item>
     <item msgid="5044688398303285224">"Isključeno"</item>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 36187b9..4327594 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kattintson új eszköz párosításához"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nem sikerült frissíteni a beállításkészletet"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Beállításkészlet"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Kiválasztva"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Környezet"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Bal"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Jobb"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Környezet"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Bal oldali környezet"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Jobb oldali környezet"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Kibontás a balra és jobbra elválasztott vezérlőkhöz"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Összecsukás az egységes vezérléshez"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Környezet némítása"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Környezet némításának feloldása"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Eszközök"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Élő feliratozás"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Beállítások"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Megjegyzés"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Feloldja az eszköz mikrofonjának letiltását?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Feloldja az eszköz kamerájának letiltását?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Alkalmazás megosztása közben az adott appban megjelenített vagy lejátszott minden tartalom látható a(z) <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> számára. Ezért legyen elővigyázatos a jelszavakkal, a fizetési adatokkal, az üzenetekkel, a fotókkal, valamint a hang- és videófelvételekkel."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Képernyő megosztása"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> letiltotta ezt a beállítást"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Válassza ki a megosztani kívánt alkalmazást"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Átküldi a képernyőt?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Egyetlen app átküldése"</string>
@@ -798,7 +800,7 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Be: Arcalapú"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Kész"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Alkalmaz"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Az értesítések kikapcsolása"</string>
+    <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Kikapcsolás"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Néma"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Alapértelmezett"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatikus"</string>
@@ -909,8 +911,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Osztott képernyő használata, az alkalmazás a jobb oldalon van"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Osztott képernyő használata, az alkalmazás a bal oldalon van"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Teljes képernyő használata"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Asztali ablakkezelési mód használata"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Váltás a jobb oldalt, illetve lent lévő appra osztott képernyő esetén"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Váltás a bal oldalt, illetve fent lévő appra osztott képernyő esetén"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Osztott képernyőn: az egyik alkalmazás lecserélése egy másikra"</string>
@@ -984,6 +985,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Húzza ide az eltávolításhoz"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Legalább <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kártya szükséges"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Szerkesztés"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Idő"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Óra, perc és másodperc megjelenítése"</item>
@@ -1207,7 +1210,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Elrejti ezt a(z) <xliff:g id="APP_NAME">%1$s</xliff:g>-médiavezérlőt?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Az aktuális média-munkamenet nem rejthető el."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Elrejtés"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Folytatás"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Beállítások"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> <xliff:g id="SONG_NAME">%1$s</xliff:g> című száma hallható itt: <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>/<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-hu/tiles_states_strings.xml b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
index c8f7b0f..168cd06 100644
--- a/packages/SystemUI/res/values-hu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hu/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Ki"</item>
     <item msgid="4875147066469902392">"Be"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nem áll rendelkezésre"</item>
+    <item msgid="8589336868985358191">"Ki"</item>
+    <item msgid="726072717827778234">"Be"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nem áll rendelkezésre"</item>
     <item msgid="5044688398303285224">"Ki"</item>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 6a7543f..eaff824 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Սեղմեք՝ նոր սարք զուգակցելու համար"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Չհաջողվեց թարմացնել կարգավորումների հավաքածուն"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Կարգավորումների հավաքածու"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Ընտրված է"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Շրջակայք"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ձախ"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Միացնել շրջակայքի ձայները"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Գործիքներ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Կենդանի ենթագրեր"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Կարգավորումներ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Նշում"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Արգելահանե՞լ սարքի խոսափողը"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Արգելահանե՞լ սարքի տեսախցիկը"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Երբ դուք որևէ հավելված եք հեռարձակում, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> հավելվածին տեսանելի կլինի այն ամենը, ինչ ցուցադրվում կամ նվագարկվում է այդ հավելվածում։ Ուստի ուշադիր եղեք այնպիսի բաների հետ, ինչպիսիք են գաղտնաբառերը, վճարային տվյալները, հաղորդագրությունները, լուսանկարները, աուդիո և վիդեո բովանդակությունը։"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ցուցադրել էկրանը"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>-ն անջատել է այս ընտրանքը"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Հավելվածի ընտրություն՝ կիսվելու համար"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Հեռարձակե՞լ ձեր էկրանը"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Հեռարձակել մեկ հավելված"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Միաց․ – Դիմաճանաչման հիման վրա"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Փակել"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Կիրառել"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Անջատել ծանուցումները"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Անձայն"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Կանխադրված"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Ավտոմատ"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Տրոհել էկրանը և տեղավորել այս հավելվածը աջ կողմում"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Տրոհել էկրանը և տեղավորել այս հավելվածը ձախ կողմում"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Օգտագործեք լիաէկրան ռեժիմը"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Օգտագործել համակարգչի պատուհանի ռեժիմը"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Անցեք աջ կողմի կամ ներքևի հավելվածին տրոհված էկրանի միջոցով"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Անցեք աջ կողմի կամ վերևի հավելվածին տրոհված էկրանի միջոցով"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Տրոհված էկրանի ռեժիմում մեկ հավելվածը փոխարինել մյուսով"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Քաշեք այստեղ՝ հեռացնելու համար"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Հարկավոր է առնվազն <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> սալիկ"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Փոփոխել"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Ժամ"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Ցույց տալ ժամերը, րոպեները և վայրկյանները"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Թաքցնե՞լ <xliff:g id="APP_NAME">%1$s</xliff:g>-ի մեդիա աշխատաշրջանի կառավարման տարրը։"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Չհաջողվեց թաքցնել ընթացիկ մուլտիմեդիա աշխատաշրջանը։"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Թաքցնել"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Շարունակել"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Կարգավորումներ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Այժմ նվագարկվում է <xliff:g id="SONG_NAME">%1$s</xliff:g> երգը <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-ի կատարմամբ <xliff:g id="APP_LABEL">%3$s</xliff:g> հավելվածից"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>՝ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>-ից"</string>
diff --git a/packages/SystemUI/res/values-hy/tiles_states_strings.xml b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
index e7eee79..c1b2d71 100644
--- a/packages/SystemUI/res/values-hy/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-hy/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Անջատված է"</item>
     <item msgid="4875147066469902392">"Միացված է"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Հասանելի չէ"</item>
+    <item msgid="8589336868985358191">"Անջատված է"</item>
+    <item msgid="726072717827778234">"Միացված է"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Հասանելի չէ"</item>
     <item msgid="5044688398303285224">"Անջատված է"</item>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index c09e03c..763f767 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menyambungkan perangkat baru"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat memperbarui preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Suara sekitar"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kiri"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kanan"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Suara sekitar"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Suara sekitar kiri"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Suara sekitar kanan"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Luaskan ke kontrol terpisah kiri dan kanan"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Ciutkan ke kontrol terpadu"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Bisukan suara sekitar"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Bunyikan suara sekitar"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alat"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Teks Otomatis"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Setelan"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Catatan"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Berhenti memblokir mikrofon perangkat?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Berhenti memblokir kamera perangkat?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Jika Anda membagikan aplikasi, semua hal yang ditampilkan atau diputar di aplikasi tersebut akan terlihat oleh <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Jadi, berhati-hatilah saat memasukkan sandi, detail pembayaran, pesan, foto, audio, dan video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Bagikan layar"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah menonaktifkan opsi ini"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Pilih aplikasi yang akan dibagikan"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmisikan layar?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmisikan satu aplikasi"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aktif - Berbasis deteksi wajah"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Selesai"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Terapkan"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Nonaktifkan notifikasi"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Senyap"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatis"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gunakan layar terpisah dengan aplikasi di sebelah kanan"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gunakan layar terpisah dengan aplikasi di sebelah kiri"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Gunakan layar penuh"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Gunakan mode jendela desktop"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Beralih ke aplikasi di bagian kanan atau bawah saat menggunakan layar terpisah"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Beralih ke aplikasi di bagian kiri atau atas saat menggunakan layar terpisah"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Dalam layar terpisah: ganti salah satu aplikasi dengan yang lain"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Tarik ke sini untuk menghapus"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Anda membutuhkan setidaknya <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kartu"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Waktu"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Tampilkan jam, menit, dan detik"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan ke posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisi tidak valid."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisi <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Kartu telah ditambahkan"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kartu ditambahkan"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kartu dihapus"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor setelan cepat."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Sembunyikan kontrol media untuk <xliff:g id="APP_NAME">%1$s</xliff:g> ini?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media aktif tidak dapat disembunyikan."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Lanjutkan"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Setelan"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sedang diputar dari <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> dari <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-in/tiles_states_strings.xml b/packages/SystemUI/res/values-in/tiles_states_strings.xml
index 182924d..a00d87d 100644
--- a/packages/SystemUI/res/values-in/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-in/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Nonaktif"</item>
     <item msgid="4875147066469902392">"Aktif"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Tidak tersedia"</item>
+    <item msgid="8589336868985358191">"Nonaktif"</item>
+    <item msgid="726072717827778234">"Aktif"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Tidak tersedia"</item>
     <item msgid="5044688398303285224">"Mati"</item>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index b853a55..970a913 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Smelltu til að para nýtt tæki"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tókst ekki að uppfæra forstillingu"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forstilling"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valið"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Umhverfi"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vinstri"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Kveikja á hljóði umhverfis"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verkfæri"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Skjátextar í rauntíma"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Stillingar"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Glósa"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Opna fyrir hljóðnema tækisins?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Opna fyrir myndavél tækisins?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Þegar þú deilir forriti er allt sem sést eða er spilað í því forriti sýnilegt <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Passaðu því upp á aðgangsorð, greiðsluupplýsingar, skilaboð, myndir, hljóð og myndskeið."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deila skjá"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> slökkti á þessum valkosti"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Velja forrit til að deila"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Varpa skjánum?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Varpa einu forriti"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Kveikt – út frá andliti"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Lokið"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Nota"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Slökkva á tilkynningum"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Hljóðlaust"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Sjálfgefið"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Sjálfvirk"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Notaðu skjáskiptingu fyrir forritið til hægri"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Notaðu skjáskiptingu fyrir forritið til vinstri"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Nota allan skjáinn"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Nota gluggastillingu í tölvu"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Skiptu í forrit til hægri eða fyrir neðan þegar skjáskipting er notuð"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Skiptu í forrit til vinstri eða fyrir ofan þegar skjáskipting er notuð"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Í skjáskiptingu: Skipta forriti út fyrir annað forrit"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Dragðu hingað til að fjarlægja"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Flísarnar mega ekki vera færri en <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Breyta"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Tími"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Sýna klukkustundir, mínútur og sekúndur"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Fela þessa efnisstýringu fyrir <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Ekki tókst að fela opna efnislotu."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fela"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Halda áfram"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Stillingar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> með <xliff:g id="ARTIST_NAME">%2$s</xliff:g> er í spilun á <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> af <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-is/tiles_states_strings.xml b/packages/SystemUI/res/values-is/tiles_states_strings.xml
index 58ce0ae..7790b11 100644
--- a/packages/SystemUI/res/values-is/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-is/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Slökkt"</item>
     <item msgid="4875147066469902392">"Kveikt"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Ekki í boði"</item>
+    <item msgid="8589336868985358191">"Slökkt"</item>
+    <item msgid="726072717827778234">"Kveikt"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Ekki í boði"</item>
     <item msgid="5044688398303285224">"Slökkt"</item>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ceb1ca1..7323037 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -138,7 +138,7 @@
     <string name="screenrecord_stop_dialog_button" msgid="2883812564938194350">"Interrompi registrazione"</string>
     <string name="share_to_app_chip_accessibility_label" msgid="4210256229976947065">"Condivisione dello schermo in corso"</string>
     <string name="share_to_app_chip_accessibility_label_generic" msgid="5517431657924536133">"Condivisione di contenuti in corso…"</string>
-    <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Vuoi interrompere la condivisione dello schermo?"</string>
+    <string name="share_to_app_stop_dialog_title" msgid="9212915050910250438">"Interrompere la condivisione dello schermo?"</string>
     <string name="share_to_app_stop_dialog_title_generic" msgid="9079161538135843648">"Interrompere la condivisione?"</string>
     <string name="share_to_app_stop_dialog_message_entire_screen_with_host_app" msgid="522823522115375414">"Al momento stai condividendo l\'intero schermo con <xliff:g id="HOST_APP_NAME">%1$s</xliff:g>"</string>
     <string name="share_to_app_stop_dialog_message_entire_screen" msgid="5090115386271179270">"Al momento stai condividendo l\'intero schermo con un\'app"</string>
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Fai clic per accoppiare un nuovo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Impossibile aggiornare preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selezionato"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Audio ambientale"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sinistra"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Riattiva audio ambientale"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Strumenti"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sottotitoli in tempo reale"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Impostazioni"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vuoi sbloccare il microfono del dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vuoi sbloccare la fotocamera del dispositivo?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quando condividi un\'app, tutto ciò che viene mostrato o riprodotto al suo interno è visibile a <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Presta quindi attenzione a password, dati di pagamento, messaggi, foto, audio e video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Condividi schermo"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ha disattivato questa opzione"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Scegli l\'app da condividere"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Trasmettere lo schermo?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Trasmetti un\'app"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"On - Rotazione basata sul viso"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Fine"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Applica"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Disattiva notifiche"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Modalità silenziosa"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Modalità predefinita"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatico"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Utilizza lo schermo diviso con l\'app a destra"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Utilizza lo schermo diviso con l\'app a sinistra"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Utilizza la modalità a schermo intero"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usa windowing del desktop"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Passa all\'app a destra o sotto mentre usi lo schermo diviso"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Passa all\'app a sinistra o sopra mentre usi lo schermo diviso"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Con lo schermo diviso: sostituisci un\'app con un\'altra"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Trascina qui per rimuovere"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Occorrono almeno <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> schede"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Modifica"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Ora"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Mostra ore, minuti e secondi"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Nascondere questo controllo multimediale per <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Imposs. nascondere sessione multimediale corrente."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Nascondi"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Riprendi"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Impostazioni"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> di <xliff:g id="ARTIST_NAME">%2$s</xliff:g> è in riproduzione da <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> di <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-it/tiles_states_strings.xml b/packages/SystemUI/res/values-it/tiles_states_strings.xml
index 5c56d08..2d3f553 100644
--- a/packages/SystemUI/res/values-it/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-it/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Off"</item>
     <item msgid="4875147066469902392">"On"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Non disponibile"</item>
+    <item msgid="8589336868985358191">"Off"</item>
+    <item msgid="726072717827778234">"On"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Non disponibile"</item>
     <item msgid="5044688398303285224">"Off"</item>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 8123c7e..3ee24a3 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"צריך ללחוץ כדי להתאים מכשיר חדש"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"לא ניתן לעדכן את ההגדרה הקבועה מראש"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"הגדרה קבועה מראש"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"נבחר"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"הרעשים בסביבה"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"שמאל"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ימין"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"הרעשים בסביבה"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"הרעשים בסביבה בצד שמאל"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"הרעשים בסביבה בצד ימין"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"הרחבה לאמצעי בקרה נפרדים לצד שמאל ולצד ימין"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"כיווץ לאמצעי בקרה מאוחד"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"השתקת הרעשים בסביבה"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ביטול השתקת הרעשים בסביבה"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"כלים"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"כתוביות מיידיות"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"הגדרות"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"פתק"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"לבטל את חסימת המיקרופון של המכשיר?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"לבטל את חסימת המצלמה של המכשיר?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"כשמשתפים אפליקציה, כל מה שרואים או מפעילים בה מופיע גם ב-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. מומלץ להיזהר ולא לחשוף פרטים אישיים כמו סיסמאות, פרטי תשלום, הודעות, תמונות, אודיו וסרטונים."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"שיתוף המסך"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> השביתה את האפשרות הזו"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"בחירת אפליקציה לשיתוף"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"‏להפעיל Cast של המסך?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"‏הפעלת Cast של אפליקציה אחת"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"פועל – מבוסס על זיהוי פנים"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"סיום"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"אישור"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"השבתת ההתראות"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"שקט"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ברירת מחדל"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"באופן אוטומטי"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"שימוש במסך מפוצל כשהאפליקציה בצד ימין"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"שימוש במסך מפוצל כשהאפליקציה בצד שמאל"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"שימוש במסך מלא"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"עיבוד החלק הנצפה בלבד במחשב"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"מעבר לאפליקציה משמאל או למטה בזמן שימוש במסך מפוצל"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"מעבר לאפליקציה מימין או למעלה בזמן שימוש במסך מפוצל"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"כשהמסך מפוצל: החלפה בין אפליקציה אחת לאחרת"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"אפשר לגרור לכאן כדי להסיר"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"יש צורך ב-<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> אריחים לפחות"</string>
     <string name="qs_edit" msgid="5583565172803472437">"עריכה"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"שעה"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"הצגת שעות, דקות ושניות"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"הוספה למיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"המיקום לא תקין."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"מיקום <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"כרטיס המידע כבר נוסף"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"הלחצן נוסף"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"הלחצן הוסר"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"עורך הגדרות מהירות."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"להסתיר את בקר המדיה הזה לאפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"לא ניתן להסתיר את סשן המדיה הנוכחי."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"הסתרה"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"המשך"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"הגדרות"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> של <xliff:g id="ARTIST_NAME">%2$s</xliff:g> מופעל מ-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> מתוך <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-iw/tiles_states_strings.xml b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
index d1bd612a..42aa531 100644
--- a/packages/SystemUI/res/values-iw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-iw/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"כבוי"</item>
     <item msgid="4875147066469902392">"פועל"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"לא זמין"</item>
     <item msgid="5044688398303285224">"כבוי"</item>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 2fc703c..1e85479 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"クリックすると、新しいデバイスをペア設定できます"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"プリセットを更新できませんでした"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"プリセット"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"選択中"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"周囲の音"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
@@ -582,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"アプリを共有すると、そのアプリで表示または再生される内容が <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> にすべて公開されます。パスワード、お支払い情報、メッセージ、写真、音声、動画などの情報にご注意ください。"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"画面を共有"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> がこのオプションを無効にしています"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"共有するアプリを選択"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"画面をキャストしますか?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"1 つのアプリをキャスト"</string>
@@ -794,7 +800,7 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ON - 顔ベース"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"完了"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"適用"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"通知を OFF にする"</string>
+    <string name="inline_turn_off_notifications" msgid="2653064779176881329">"OFF にする"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"サイレント"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"デフォルト"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
@@ -905,8 +911,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"分割画面の使用(アプリを右側に表示)"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"分割画面の使用(アプリを左側に表示)"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"全画面表示に切り替える"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"デスクトップ ウィンドウを使用する"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"分割画面の使用時に右側または下部のアプリに切り替える"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"分割画面の使用時に左側または上部のアプリに切り替える"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"分割画面中: アプリを順に置換する"</string>
@@ -980,6 +985,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"削除するにはここにドラッグ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"タイルは <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個以上必要です"</string>
     <string name="qs_edit" msgid="5583565172803472437">"編集"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"時間"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"時間、分、秒を表示"</item>
@@ -1203,7 +1210,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> のこのコントロールを非表示にしますか?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"現在のメディア セッションは非表示にできません。"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"非表示"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"再開"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>(アーティスト名: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>)が <xliff:g id="APP_LABEL">%3$s</xliff:g> で再生中"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ja/tiles_states_strings.xml b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
index cce5ceb..4a6b210 100644
--- a/packages/SystemUI/res/values-ja/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ja/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"OFF"</item>
     <item msgid="4875147066469902392">"ON"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"使用不可"</item>
+    <item msgid="8589336868985358191">"OFF"</item>
+    <item msgid="726072717827778234">"ON"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"使用不可"</item>
     <item msgid="5044688398303285224">"OFF"</item>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 86f8e33..0a25f83 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"დააწკაპუნეთ ახალი მოწყობილობის დასაწყვილებლად"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"წინასწარ დაყენებული პარამეტრების განახლება ვერ მოხერხდა"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"წინასწარ დაყენებული"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"არჩეულია"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"გარემოცვა"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"მარცხენა"</string>
@@ -582,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"აპის გაზიარებისას <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ხედავს ყველაფერს, რაც ჩანს ან უკრავს ამ აპში. ამიტომ სიფრთხილე გამოიჩინეთ ისეთ ინფორმაციასთან, როგორიცაა პაროლები, გადახდის დეტალები, შეტყობინებები, ფოტოები, აუდიო და ვიდეო."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ეკრანის გაზიარება"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>-მა გათიშა ეს ვარიანტი"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"გაზიარებისთვის აპის არჩევა"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"გსურთ თქვენი ეკრანის ტრანსლირება?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ერთი აპის ტრანსლირება"</string>
@@ -794,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ჩართული — სახის მიხედვით"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"მზადაა"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"მისადაგება"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"შეტყობინებების გამორთვა"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"ჩუმი"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ნაგულისხმევი"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ავტომატური"</string>
@@ -905,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ეკრანის გაყოფის გამოყენება აპზე მარჯვნივ"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ეკრანის გაყოფის გამოყენება აპზე მარცხნივ"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"სრული ეკრანის გამოყენება"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"დესკტოპის ფანჯრის რეჟიმის გამოყენება"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ეკრანის გაყოფის გამოყენებისას აპზე მარჯვნივ ან ქვემოთ გადართვა"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ეკრანის გაყოფის გამოყენებისას აპზე მარცხნივ ან ზემოთ გადართვა"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ეკრანის გაყოფის დროს: ერთი აპის მეორით ჩანაცვლება"</string>
@@ -980,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ამოსაშლელად, ჩავლებით გადმოიტანეთ აქ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"თქვენ გჭირდებათ მოზაიკის <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ფილა მაინც"</string>
     <string name="qs_edit" msgid="5583565172803472437">"რედაქტირება"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"დრო"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"საათების, წუთებისა და წამების ჩვენება"</item>
@@ -1203,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"დაიმალოს მედიის ეს კონტროლერი <xliff:g id="APP_NAME">%1$s</xliff:g> აპში?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"მედიის მიმდინარე სესიის დამალვა შეუძლებელია."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"დამალვა"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"გაგრძელება"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"პარამეტრები"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g>, <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, უკრავს <xliff:g id="APP_LABEL">%3$s</xliff:g>-დან"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-დან <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
@@ -1250,7 +1257,7 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ხელმისაწვდომი მოწყობილობები გამომავალი აუდიოსთვის."</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ხმა"</string>
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
-    <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"დინამიკები და დისპლეები"</string>
+    <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"დინამიკები და ეკრანები"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"შემოთავაზებული მოწყობილობები"</string>
     <string name="media_input_group_title" msgid="2057057473860783021">"შემავალი"</string>
     <string name="media_output_group_title" msgid="6789001895863332576">"გამომავალი"</string>
diff --git a/packages/SystemUI/res/values-ka/tiles_states_strings.xml b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
index 7a22981..6440b5f 100644
--- a/packages/SystemUI/res/values-ka/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ka/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"გამორთულია"</item>
     <item msgid="4875147066469902392">"ჩართულია"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"მიუწვდომელი"</item>
+    <item msgid="8589336868985358191">"გამორთული"</item>
+    <item msgid="726072717827778234">"ჩართული"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"მიუწვდომელია"</item>
     <item msgid="5044688398303285224">"გამორთულია"</item>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 1a7532b..c7e8d81 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Жаңа құрылғыны жұптау үшін басыңыз."</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Параметрлер жинағын жаңарту мүмкін болмады."</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Параметрлер жинағы"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Таңдалды"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Айнала"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Сол жақ"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Оң жақ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Қоршаған дыбыстар"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Сол жақтағы дыбыстар"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Оң жақтағы дыбыстар"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Сол жақ және оң жақ бөлек бақылау құралдарына жаю"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Біріктірілген бақылау құралына жию"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Айналаның дыбысын өшіру"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Айналаның дыбысын қосу"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Құралдар"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Параметрлер"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ескертпе"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Құрылғы микрофонын блоктан шығару керек пе?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Құрылғы камерасын блоктан шығару керек пе?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Қолданбаны бөліскен кезде, онда көрінетін не ойнатылатын барлық контент <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> қолданбасында көрсетіледі. Сондықтан құпия сөздерді, төлем туралы мәліметті, хабарларды, фотосуреттерді және аудио мен бейнені ашқанда сақ болыңыз."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Экранды бөлісу"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы осы опцияны өшірді."</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Бөлісетін қолданба экранын таңдау"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Экранды трансляциялау керек пе?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Бір қолданба экранын трансляциялау"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Қосулы – бет негізінде"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Дайын"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Қолдану"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Хабарландыруларды өшіру"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Үнсіз"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Әдепкі"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматты"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Қолданбаны бөлінген экранның оң жағынан пайдалану"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Қолданбаны бөлінген экранның сол жағынан пайдалану"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Толық экранды пайдалану"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Компьютер терезесін пайдалану"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлінген экранда оң не төмен жақтағы қолданбаға ауысу"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлінген экранда сол не жоғары жақтағы қолданбаға ауысу"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлу кезінде: бір қолданбаны басқасымен алмастыру"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Керексіздерін осы жерге сүйреңіз"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Кемінде <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> бөлшек қажет."</string>
     <string name="qs_edit" msgid="5583565172803472437">"Өзгерту"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Уақыт"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Сағаттарды, минуттарды және секундтарды көрсету"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> орнына қосу"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Орын жарамсыз."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> орны"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Бөлшек қосылып қойған."</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Бөлшек қосылды."</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Бөлшек өшірілді."</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Жылдам параметрлер өңдегіші."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> үшін медиа контроллері жасырылсын ба?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Ағымдағы мультимедиа сеансын жасыру мүмкін емес."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жасыру"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> қолданбасында <xliff:g id="ARTIST_NAME">%2$s</xliff:g> орындайтын \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" әні ойнатылуда."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>/<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-kk/tiles_states_strings.xml b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
index 2b839c8..a177ca2 100644
--- a/packages/SystemUI/res/values-kk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kk/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Өшірулі"</item>
     <item msgid="4875147066469902392">"Қосулы"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Қолжетімді емес"</item>
+    <item msgid="8589336868985358191">"Өшірулі"</item>
+    <item msgid="726072717827778234">"Қосулы"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Қолжетімсіз"</item>
     <item msgid="5044688398303285224">"Өшірулі"</item>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 43c5c70..349e34a 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ចុច ដើម្បីផ្គូផ្គងឧបករណ៍ថ្មី"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"មិនអាច​ប្ដូរ​ការកំណត់ជាមុន​បានទេ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"កំណត់ជាមុន"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"បានជ្រើសរើស"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"មជ្ឈដ្ឋានជុំវិញ"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ឆ្វេង"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ស្ដាំ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"មជ្ឈដ្ឋានជុំវិញ"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"មជ្ឈដ្ឋានជុំវិញខាងឆ្វេង"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"មជ្ឈដ្ឋានជុំវិញខាងស្ដាំ"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ពង្រីកទៅជាការគ្រប់គ្រងខាងឆ្វេង និងខាងស្ដាំដាច់ដោយឡែកពីគ្នា"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"បង្រួមទៅជាការគ្រប់គ្រងដែលបានរួមបញ្ចូលគ្នា"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"បិទសំឡេងមជ្ឈដ្ឋានជុំវិញ"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"បើកសំឡេងមជ្ឈដ្ឋានជុំវិញ"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ឧបករណ៍"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"អក្សររត់ក្នុងពេលជាក់ស្ដែង"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ការកំណត់"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"កំណត់ចំណាំ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ឈប់ទប់ស្កាត់​មីក្រូហ្វូន​របស់ឧបករណ៍ឬ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ឈប់ទប់ស្កាត់​កាមេរ៉ា​របស់ឧបករណ៍ឬ?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"នៅពេលអ្នកបង្ហាញកម្មវិធីណាមួយ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> មើលឃើញអ្វីគ្រប់យ៉ាងដែលបង្ហាញ ឬចាក់ក្នុងកម្មវិធីនោះ។ ដូច្នេះ សូមប្រុងប្រយ័ត្នចំពោះអ្វីៗដូចជា ពាក្យសម្ងាត់ ព័ត៌មានលម្អិតអំពីការទូទាត់ប្រាក់ សារ រូបថត ព្រមទាំងសំឡេង និងវីដេអូ។"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"បង្ហាញ​អេក្រង់"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> បានបិទជម្រើសនេះ"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ជ្រើសរើស​កម្មវិធី​ដើម្បី​ចែករំលែក"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"បញ្ជូនអេក្រង់របស់អ្នកឬ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"បញ្ជូនកម្មវិធីមួយ"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"បើក - ផ្អែកលើមុខ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"រួចរាល់"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ប្រើ"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"បិទ​ការជូន​ដំណឹង"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"ស្ងាត់"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"លំនាំដើម"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ស្វ័យប្រវត្តិ"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ប្រើមុខងារបំបែកអេក្រង់ជាមួយកម្មវិធីនៅខាងស្ដាំ"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ប្រើមុខងារបំបែកអេក្រង់ជាមួយកម្មវិធីនៅខាងឆ្វេង"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ប្រើអេក្រង់ពេញ"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ប្រើមុខងារវិនដូកុំព្យូទ័រ"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ប្ដូរទៅកម្មវិធីនៅខាងស្ដាំ ឬខាងក្រោម ពេលកំពុងប្រើមុខងារ​បំបែកអេក្រង់"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ប្ដូរទៅកម្មវិធីនៅខាងឆ្វេង ឬខាងលើ ពេលកំពុងប្រើមុខងារ​បំបែកអេក្រង់"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ក្នុងអំឡុងពេលប្រើមុខងារបំបែកអេក្រង់៖ ជំនួសកម្មវិធីពីមួយទៅមួយទៀត"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"អូសទីនេះដើម្បីយកចេញ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"អ្នក​ត្រូវការ​ប្រអប់​យ៉ាងតិច <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"កែ"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"ម៉ោង"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"បង្ហាញម៉ោង នាទី និងវិនាទី"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"បញ្ចូលទៅ​ទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ទីតាំងគ្មានសុពលភាព។"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ទីតាំងទី <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"បានបញ្ចូលប្រអប់រួចហើយ"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"បានបញ្ចូលប្រអប់"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"បាន​ផ្លាស់ទី​ប្រអប់"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"កម្មវិធីកែការកំណត់រហ័ស"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"លាក់ផ្ទាំង​គ្រប់គ្រង​មេឌៀនេះសម្រាប់ <xliff:g id="APP_NAME">%1$s</xliff:g> ឬ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"មិនអាចលាក់វគ្គមេឌៀបច្ចុប្បន្នបានទេ។"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"លាក់"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"បន្ត"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ការកំណត់"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ច្រៀងដោយ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> កំពុងចាក់ពី <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> នៃ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-km/tiles_states_strings.xml b/packages/SystemUI/res/values-km/tiles_states_strings.xml
index 7085509..49c549f 100644
--- a/packages/SystemUI/res/values-km/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-km/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"បិទ"</item>
     <item msgid="4875147066469902392">"បើក"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"មិនមានទេ"</item>
+    <item msgid="8589336868985358191">"បិទ"</item>
+    <item msgid="726072717827778234">"បើក"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"មិនមានទេ"</item>
     <item msgid="5044688398303285224">"បិទ"</item>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index 8de5281e..0fa4c24 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ಹೊಸ ಸಾಧನವನ್ನು ಜೋಡಿಸಲು ಕ್ಲಿಕ್ ಮಾಡಿ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ಪ್ರಿಸೆಟ್ ಅನ್ನು ಅಪ್‌ಡೇಟ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗಲಿಲ್ಲ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ಪ್ರಿಸೆಟ್‌"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"ಆ್ಯಂಬಿಯೆಂಟ್ ವಾಲ್ಯೂಮ್"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ಎಡ"</string>
@@ -582,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ನೀವು ಆ್ಯಪ್ ಅನ್ನು ಹಂಚಿಕೊಳ್ಳುತ್ತಿರುವಾಗ, ಆ ಆ್ಯಪ್‌ನಲ್ಲಿ ತೋರಿಸಿರುವ ಅಥವಾ ಪ್ಲೇ ಮಾಡಿದ ಏನಾದರೂ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ಗೆ ಗೋಚರಿಸುತ್ತದೆ. ಆದ್ದರಿಂದ ಪಾಸ್‌ವರ್ಡ್‌ಗಳು, ಪಾವತಿ ವಿವರಗಳು, ಸಂದೇಶಗಳು, ಫೋಟೋಗಳು ಮತ್ತು ಆಡಿಯೋ ಮತ್ತು ವೀಡಿಯೊದಂತಹ ವಿಷಯಗಳ ಬಗ್ಗೆ ಜಾಗರೂಕರಾಗಿರಿ."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ಸ್ಕ್ರೀನ್‌ ಹಂಚಿಕೊಳ್ಳಿ"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಈ ಆಯ್ಕೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿದೆ"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ಹಂಚಿಕೊಳ್ಳಲು ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಿತ್ತರಿಸಬೇಕೇ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ಒಂದು ಆ್ಯಪ್ ಅನ್ನು ಬಿತ್ತರಿಸಿ"</string>
@@ -794,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ಆನ್ ಆಗಿದೆ - ಮುಖ-ಆಧಾರಿತ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ಪೂರ್ಣಗೊಂಡಿದೆ"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ಅನ್ವಯಿಸಿ"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ಅಧಿಸೂಚನೆಗಳನ್ನು ಆಫ್ ಮಾಡಿ"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"ನಿಶ್ಶಬ್ದ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ಡೀಫಾಲ್ಟ್"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ಸ್ವಯಂಚಾಲಿತ"</string>
@@ -905,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ಬಲಭಾಗದಲ್ಲಿ ಆ್ಯಪ್ ಮೂಲಕ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಿ"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ಎಡಭಾಗದಲ್ಲಿ ಆ್ಯಪ್ ಮೂಲಕ ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಬಳಸಿ"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ಫುಲ್‌ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಳಸಿ"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ಡೆಸ್ಕ್‌ಟಾಪ್ ವಿಂಡೋಯಿಂಗ್ ಅನ್ನು ಬಳಸಿ"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಬಲಭಾಗ ಅಥವಾ ಕೆಳಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸಿ ಮೋಡ್ ಬಳಸುವಾಗ ಎಡಭಾಗ ಅಥವಾ ಮೇಲ್ಭಾಗದಲ್ಲಿರುವ ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ಸ್ಕ್ರೀನ್ ಬೇರ್ಪಡಿಸುವ ಸಮಯದಲ್ಲಿ: ಒಂದು ಆ್ಯಪ್‌ನಿಂದ ಮತ್ತೊಂದು ಆ್ಯಪ್‌ಗೆ ಬದಲಿಸಿ"</string>
@@ -980,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ತೆಗೆದುಹಾಕಲು ಇಲ್ಲಿ ಡ್ರ್ಯಾಗ್‌ ಮಾಡಿ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"ನಿಮಗೆ ಕನಿಷ್ಠ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ಟೈಲ್‌ಗಳ ಅಗತ್ಯವಿದೆ"</string>
     <string name="qs_edit" msgid="5583565172803472437">"ಎಡಿಟ್"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"ಸಮಯ"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ಗಂಟೆಗಳು, ನಿಮಿಷಗಳು, ಸೆಕೆಂಡುಗಳನ್ನು ತೋರಿಸು"</item>
@@ -1203,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ಗಾಗಿ ಈ ಮಾಧ್ಯಮ ಕಂಟ್ರೋಲ್‌ಗಳನ್ನು ಮರೆಮಾಡಬೇಕೆ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"ಪ್ರಸ್ತುತ ಮಾಧ್ಯಮ ಸೆಶನ್ ಅನ್ನು ಮರೆಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ಮರೆಮಾಡಿ"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"ಪುನರಾರಂಭಿಸಿ"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ಸೆಟ್ಟಿಂಗ್‌ಗಳು"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ಅವರ <xliff:g id="SONG_NAME">%1$s</xliff:g> ಹಾಡನ್ನು <xliff:g id="APP_LABEL">%3$s</xliff:g> ನಲ್ಲಿ ಪ್ಲೇ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ರಲ್ಲಿ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-kn/tiles_states_strings.xml b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
index 487be13..712936a 100644
--- a/packages/SystemUI/res/values-kn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-kn/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"ಆಫ್"</item>
     <item msgid="4875147066469902392">"ಆನ್"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"ಲಭ್ಯವಿಲ್ಲ"</item>
+    <item msgid="8589336868985358191">"ಆಫ್ ಆಗಿದೆ"</item>
+    <item msgid="726072717827778234">"ಆನ್ ಆಗಿದೆ"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"ಲಭ್ಯವಿಲ್ಲ"</item>
     <item msgid="5044688398303285224">"ಆಫ್"</item>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index c3a1a1a..2b9fc89 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"새 기기와 페어링하려면 클릭하세요"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"사전 설정을 업데이트할 수 없음"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"미리 설정"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"선택됨"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"주변 소리"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"왼쪽"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"오른쪽"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"주변 소리"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"왼쪽 주변 소리"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"오른쪽 주변 소리"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"왼쪽 및 오른쪽 개별 제어로 확장"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"통합 제어로 축소"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"주변 소리 음소거"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"주변 소리 음소거 해제"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"도구"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"실시간 자막"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"설정"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"메모"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"기기 마이크를 차단 해제하시겠습니까?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"기기 카메라를 차단 해제하시겠습니까?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"앱을 공유하면 앱에 표시되거나 앱에서 재생되는 모든 항목이 <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>에 표시됩니다. 따라서 비밀번호, 결제 세부정보, 메시지, 사진, 오디오 및 동영상 등이 노출되지 않도록 주의하세요."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"화면 공유"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 이 옵션을 사용 중지했습니다."</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"공유할 앱 선택"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"화면을 전송하시겠습니까?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"앱 1개 전송"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"켜짐 - 얼굴 기준"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"완료"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"적용"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"알림 사용 중지"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"무음"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"기본값"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"자동"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"앱이 오른쪽에 오도록 화면 분할 사용"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"앱이 왼쪽에 오도록 화면 분할 사용"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"전체 화면 사용"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"데스크톱 창 사용"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"화면 분할을 사용하는 중에 오른쪽 또는 아래쪽에 있는 앱으로 전환"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"화면 분할을 사용하는 중에 왼쪽 또는 위쪽에 있는 앱으로 전환하기"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"화면 분할 중: 다른 앱으로 바꾸기"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"여기로 드래그하여 삭제"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>개 이상의 타일이 필요합니다."</string>
     <string name="qs_edit" msgid="5583565172803472437">"수정"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"시간"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"시간, 분, 초 표시"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> 위치에 추가"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"위치가 잘못되었습니다."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> 위치"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"타일이 이미 추가되어 있음"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"타일 추가됨"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"타일 삭제됨"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"빠른 설정 편집기"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g>의 미디어 컨트롤을 숨길까요?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"현재 미디어 세션은 숨길 수 없습니다."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"숨기기"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"설정"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>에서 <xliff:g id="ARTIST_NAME">%2$s</xliff:g>의 <xliff:g id="SONG_NAME">%1$s</xliff:g> 재생 중"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ko/tiles_states_strings.xml b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
index dfdcefe..f31f810 100644
--- a/packages/SystemUI/res/values-ko/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ko/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"꺼짐"</item>
     <item msgid="4875147066469902392">"켜짐"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"사용할 수 없음"</item>
+    <item msgid="8589336868985358191">"사용 안함"</item>
+    <item msgid="726072717827778234">"사용"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"이용 불가"</item>
     <item msgid="5044688398303285224">"꺼짐"</item>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index 23cc8ee..b1f6f48 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Жаңы түзмөк кошуу үчүн басыңыз"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Алдын ала коюлган параметрлер жаңыртылган жок"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Алдын ала коюлган параметрлер"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Тандалды"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Айланадагы үндөр"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Сол"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Оң"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Айланадагы үндөр"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Сол жактагы үндөр"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Оң жактагы үндөр"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Cол жана оң жактагы өзүнчө башкаруу элементтерине жайып көрсөтүү"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Бирдиктүү башкаруу элементине жыйыштыруу"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Айланадагы үндөрдү басуу"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Айланадагы үндөрдү чыгаруу"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Куралдар"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Ыкчам коштомо жазуулар"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Параметрлер"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Учкай маалымат"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Түзмөктүн микрофонун бөгөттөн чыгарасызбы?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Түзмөктүн камерасын бөгөттөн чыгарасызбы?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Колдонмону бөлүшкөндө, андагы нерселер <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> колдонмосуна көрүнөт. Андыктан сырсөздөр, төлөмдүн чоо-жайы, билдирүүлөр, сүрөттөр, аудио жана видеолор менен этият болуңуз."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Экранды бөлүшүү"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> бул параметрди өчүрүп койду"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Бөлүшүү үчүн колдонмо тандоо"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Экранды башка түзмөккө чыгарасызбы?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Бир колдонмону чыгаруу"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Күйүк – Жүздүн негизинде"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Бүттү"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Колдонуу"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Билдирмелерди өчүрүү"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Үнсүз"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Демейки"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматтык"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Колдонмону оңго жылдырып, экранды бөлүү"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Колдонмону солго жылдырып, экранды бөлүү"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Толук экранды колдонуу"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Иш тактанын терезелерин колдонуу"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Бөлүнгөн экранда сол же төмөн жактагы колдонмого которулуу"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Бөлүнгөн экранды колдонуп жатканда сол же жогору жактагы колдонмого которулуңуз"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Экранды бөлүү режиминде бир колдонмону экинчисине алмаштыруу"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Өчүрүү үчүн бул жерге сүйрөңүз"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Сизге жок дегенде <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> мозаика керек"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Түзөтүү"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Убакыт"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Сааттар, мүнөттөр жана секунддар"</item>
@@ -1207,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> \'да ушул медиа башкарууну жашырасызбы?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Учурдагы медиа сеансын жашыруу мүмкүн эмес."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Жашыруу"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Улантуу"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ыры (аткаруучу: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) <xliff:g id="APP_LABEL">%3$s</xliff:g> колдонмосунан ойнотулуп жатат"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ичинен <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ky/tiles_states_strings.xml b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
index 6077f66..fe451fa 100644
--- a/packages/SystemUI/res/values-ky/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ky/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Өчүк"</item>
     <item msgid="4875147066469902392">"Күйүк"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Жеткиликсиз"</item>
+    <item msgid="8589336868985358191">"Өчүк"</item>
+    <item msgid="726072717827778234">"Күйүк"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Жеткиликсиз"</item>
     <item msgid="5044688398303285224">"Өчүк"</item>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 69b79b8..c2a4e8f 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ຄລິກເພື່ອຈັບຄູ່ອຸປະກອນໃໝ່"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ບໍ່ສາມາດອັບເດດການຕັ້ງຄ່າລ່ວງໜ້າໄດ້"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ຄ່າທີ່ກຳນົດລ່ວງໜ້າ"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ເລືອກແລ້ວ"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"ສຽງແວດລ້ອມ"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ຊ້າຍ"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ເຊົາປິດສຽງແວດລ້ອມ"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ເຄື່ອງມື"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ຄຳບັນຍາຍສົດ"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ການຕັ້ງຄ່າ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ບັນທຶກ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ປົດບລັອກໄມໂຄຣໂຟນອຸປະກອນບໍ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ປົດບລັອກກ້ອງຖ່າຍຮູບອຸ​ປະ​ກອນບໍ?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ເມື່ອທ່ານແບ່ງປັນແອັບຂອງທ່ານ, ຄົນອື່ນຈະເບິ່ງເຫັນທຸກຢ່າງທີ່ສະແດງ ຫຼື ຫຼິ້ນໃນແອັບໃນ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. ດັ່ງນັ້ນ, ໃຫ້ລະມັດລະວັງສິ່ງຕ່າງໆ ເຊັ່ນ: ລະຫັດຜ່ານ, ລາຍລະອຽດການຈ່າຍເງິນ, ຂໍ້ຄວາມ, ຮູບພາບ, ພ້ອມທັງສຽງ ແລະ ວິດີໂອ."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ແບ່ງປັນໜ້າຈໍ"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ປິດການນຳໃຊ້ຕົວເລືອກນີ້ແລ້ວ"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ເລືອກແອັບທີ່ຈະແບ່ງປັນ"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ສົ່ງສັນຍານໜ້າຈໍຂອງທ່ານບໍ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ສົ່ງສັນຍານແອັບ 1 ລາຍການ"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ເປີດ - ອ້າງອີງໃບໜ້າ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ແລ້ວໆ"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ນຳໃຊ້"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ປິດການແຈ້ງເຕືອນ"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"ປິດສຽງ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ຄ່າເລີ່ມຕົ້ນ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ອັດຕະໂນມັດ"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ໃຊ້ໂໝດແບ່ງໜ້າຈໍໂດຍໃຫ້ແອັບຢູ່ເບື້ອງຂວາ"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ໃຊ້ໂໝດແບ່ງໜ້າຈໍໂດຍໃຫ້ແອັບຢູ່ເບື້ອງຊ້າຍ"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ໃຊ້ແບບເຕັມຈໍ"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ໃຊ້ໜ້າຈໍເດັສທັອບ"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຂວາ ຫຼື ທາງລຸ່ມໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ສະຫຼັບໄປໃຊ້ແອັບຢູ່ຊ້າຍ ຫຼື ທາງເທິງໃນຂະນະທີ່ໃຊ້ແບ່ງໜ້າຈໍ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ໃນລະຫວ່າງແບ່ງໜ້າຈໍ: ໃຫ້ປ່ຽນຈາກແອັບໜຶ່ງເປັນອີກແອັບໜຶ່ງ"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ລາກມາບ່ອນນີ້ເພື່ອລຶບອອກ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"ທ່ານຍຕ້ອງໃຊ້ຢ່າງໜ້ອຍ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ຊ່ອງ"</string>
     <string name="qs_edit" msgid="5583565172803472437">"ແກ້ໄຂ"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"ເວລາ"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ສະແດງຊົ່ວໂມງ, ນາທີ ແລະ ວິນາທີ"</item>
@@ -1003,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"ເພີ່ມໃສ່ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ຕຳແໜ່ງບໍ່ຖືກຕ້ອງ."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ຕຳແໜ່ງ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ເພີ່ມແຜ່ນແລ້ວ"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ເພີ່ມແຜ່ນແລ້ວ"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ລຶບແຜ່ນແລ້ວ"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ຕົວແກ້ໄຂການຕັ້ງຄ່າດ່ວນ"</string>
@@ -1205,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"ເຊື່ອງຕົວຄວບຄຸມມີເດຍນີ້ສຳລັບ <xliff:g id="APP_NAME">%1$s</xliff:g> ບໍ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"ບໍ່ສາມາດເຊື່ອງເຊດຊັນມີເດຍປັດຈຸບັນໄດ້."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ເຊື່ອງ"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"ສືບຕໍ່"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ການຕັ້ງຄ່າ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ໂດຍ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ກຳລັງຫຼິ້ນຈາກ <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ຈາກ <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-lo/tiles_states_strings.xml b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
index 294d6af..72c57e6 100644
--- a/packages/SystemUI/res/values-lo/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lo/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"ປິດ"</item>
     <item msgid="4875147066469902392">"ເປີດ"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"ບໍ່ພ້ອມໃຫ້ນຳໃຊ້"</item>
+    <item msgid="8589336868985358191">"ປິດ"</item>
+    <item msgid="726072717827778234">"ເປີດ"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"ບໍ່ສາມາດໃຊ້ໄດ້"</item>
     <item msgid="5044688398303285224">"ປິດ"</item>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 1ed102d..48ab51b 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Spustelėkite, kad susietumėte naują įrenginį"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Išankstinių nustatymų atnaujinti nepavyko"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Išankstiniai nustatymai"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Pasirinkta"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Aplinka"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kairė"</string>
@@ -582,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kai bendrinate programą, „<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>“ matomas visas toje programoje rodomas ar leidžiamas turinys. Todėl būkite atsargūs naudodami slaptažodžius, išsamią mokėjimo metodo informaciją, pranešimus, nuotraukas ir garso bei vaizdo įrašus."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Bendrinti ekraną"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Programoje „<xliff:g id="APP_NAME">%1$s</xliff:g>“ ši parinktis išjungta"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Norimos bendrinti programos pasirinkimas"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Perduoti ekraną?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Perduoti vieną programą"</string>
@@ -794,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Įjungta – pagal veidą"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Atlikta"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Taikyti"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Išjungti pranešimus"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Tylūs"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Numatytasis"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatinis"</string>
@@ -905,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Naudokite išskaidyto ekrano režimą su programa dešinėje"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Naudokite išskaidyto ekrano režimą su programa kairėje"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Naudoti viso ekrano režimą"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Įjungti darbalaukio pateikimo lange režimą"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Perjunkite į programą dešinėje arba apačioje išskaidyto ekrano režimu"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Perjunkite į programą kairėje arba viršuje išskaidyto ekrano režimu"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Išskaidyto ekrano režimu: pakeisti iš vienos programos į kitą"</string>
@@ -980,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Vilkite čia, jei norite pašalinti"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Turi būti bent <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> išklotinės elem."</string>
     <string name="qs_edit" msgid="5583565172803472437">"Redaguoti"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Laikas"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Rodyti valandas, minutes ir sekundes"</item>
@@ -1203,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Slėpti šį programos „<xliff:g id="APP_NAME">%1$s</xliff:g>“ medijos valdiklį?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Dabartinio medijos seanso negalima paslėpti."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Slėpti"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Tęsti"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Nustatymai"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> – „<xliff:g id="SONG_NAME">%1$s</xliff:g>“ leidžiama iš „<xliff:g id="APP_LABEL">%3$s</xliff:g>“"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> iš <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-lt/tiles_states_strings.xml b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
index 46c6f69..4ed6bd9 100644
--- a/packages/SystemUI/res/values-lt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lt/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Išjungta"</item>
     <item msgid="4875147066469902392">"Įjungta"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nepasiekiama"</item>
+    <item msgid="8589336868985358191">"Išjungta"</item>
+    <item msgid="726072717827778234">"Įjungta"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nepasiekiama"</item>
     <item msgid="5044688398303285224">"Išjungta"</item>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 06bc601..e5c407f 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Noklikšķiniet, lai savienotu pārī jaunu ierīci"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nevarēja atjaunināt pirmsiestatījumu"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pirmsiestatījums"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Atlasīts"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Apkārtnes skaņas"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Pa kreisi"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Pa labi"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Apkārtnes skaņas"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Apkārtnes skaņas pa kreisi"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Apkārtnes skaņas pa labi"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Izvērst, lai rādītu atsevišķu kreiso un labo vadīklu"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Sakļaut, lai rādītu vienotu vadīklu"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Izslēgt apkārtnes skaņas"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ieslēgt apkārtnes skaņas"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Rīki"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitri reāllaikā"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Iestatījumi"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Piezīme"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vai atbloķēt ierīces mikrofonu?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vai vēlaties atbloķēt ierīces kameru?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kopīgojot lietotni, lietotnei <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ir pieejams viss kopīgotajā lietotnē parādītais vai atskaņotais saturs. Tāpēc piesardzīgi apejieties ar parolēm, maksājumu informāciju, ziņojumiem, fotoattēliem un audio un video saturu."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Kopīgot ekrānu"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Lietotnē <xliff:g id="APP_NAME">%1$s</xliff:g> tika atspējota šī opcija"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Lietotnes izvēlēšanās kopīgošanai"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vai apraidīt ekrānu?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Apraidīt vienu lietotni"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ieslēgta — ar sejas noteikšanu"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Gatavs"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Lietot"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Izslēgt paziņojumus"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Klusums"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Noklusējums"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automātiski"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Izmantot ekrāna sadalīšanu ar lietotni labajā pusē"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Izmantot ekrāna sadalīšanu ar lietotni kreisajā pusē"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Izmantot pilnekrāna režīmu"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Izmantot darbvirsmas logu režīmu"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Pāriet uz lietotni pa labi/lejā, kamēr izmantojat sadalīto ekrānu."</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Pāriet uz lietotni pa kreisi/augšā, kamēr izmantojat sadalīto ekrānu."</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ekrāna sadalīšanas režīmā: pārvietot lietotni no viena ekrāna uz otru"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Lai noņemtu vienumus, velciet tos šeit."</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Nepieciešami vismaz <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> elementi"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Rediģēt"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Laiks"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Rādīt stundas, minūtes un sekundes"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Pievienot elementu pozīcijā numur <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nederīga pozīcija."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozīcija numur <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Elements jau ir pievienots"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Elements ir pievienots"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Elements ir noņemts"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Ātro iestatījumu redaktors."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Vai paslēpt šo lietotnes <xliff:g id="APP_NAME">%1$s</xliff:g> multivides vadīklu?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Pašreizējo multivides sesiju nevar paslēpt."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Paslēpt"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Atsākt"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Iestatījumi"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tiek atskaņots fails “<xliff:g id="SONG_NAME">%1$s</xliff:g>” (izpildītājs: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) no lietotnes <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> no <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-lv/tiles_states_strings.xml b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
index 8e9268a..0c59186e 100644
--- a/packages/SystemUI/res/values-lv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-lv/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Izslēgts"</item>
     <item msgid="4875147066469902392">"Ieslēgts"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nav pieejams"</item>
+    <item msgid="8589336868985358191">"Izslēgts"</item>
+    <item msgid="726072717827778234">"Ieslēgts"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nav pieejams"</item>
     <item msgid="5044688398303285224">"Izslēgts"</item>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index c1a5d36..e546fb5 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликнете за да спарите нов уред"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не можеше да се ажурира зададената вредност"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Зададени вредности"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Избрано"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Опкружување"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Лево"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Десно"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Опкружување"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Опкружување одлево"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Опкружување оддесно"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Прошири на одвоените контроли одлево и оддесно"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Собери на унифицирана контрола"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Исклучи го звукот на опкружувањето"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Вклучи го звукот на опкружувањето"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатки"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматски титлови"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Поставки"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Да се одблокира пристапот до микрофонот на уредот?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Да се одблокира пристапот до камерата на уредот?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Додека споделувате апликација, сѐ што се прикажува или пушта на таа апликација е видливо за <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Затоа, бидете внимателни со работи како лозинки, детали за плаќање, пораки, фотографии и аудио и видео."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Сподели екран"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ја оневозможи опцијава"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Изберете апликација за споделување"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Да се емитува вашиот екран?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Емитувајте една апликација"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Вклучено - според лице"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Примени"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Исклучи известувања"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Безгласно"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Стандардно"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматски"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Користете поделен екран со апликацијата оддесно"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Користете поделен екран со апликацијата одлево"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Користете цел екран"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Користете „Режим со прозорци на работната површина“"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Префрлете се на апликацијата десно или долу при користењето поделен екран"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Префрлете се на апликацијата лево или горе при користењето поделен екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"При поделен екран: префрлете ги аплик. од едната на другата страна"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Повлечете тука за да се отстрани"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Потребни ви се најмалку <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> плочки"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Измени"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Време"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Прикажи часови, минути и секунди"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додавање на позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позицијата е погрешна."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиција <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Плочката е веќе додадена"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Додадена е плочка"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Отстранета е плочка"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уредник за брзи поставки."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Да се скријат контролите за <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Аудиовизуелнава сесија не може да се скрие."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скриј"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Продолжи"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Поставки"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> од <xliff:g id="ARTIST_NAME">%2$s</xliff:g> е пуштено на <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-mk/tiles_states_strings.xml b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
index 752c386..0f32b8e 100644
--- a/packages/SystemUI/res/values-mk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mk/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Исклучено"</item>
     <item msgid="4875147066469902392">"Вклучено"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Недостапно"</item>
+    <item msgid="8589336868985358191">"Исклучено"</item>
+    <item msgid="726072717827778234">"Вклучено"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Недостапно"</item>
     <item msgid="5044688398303285224">"Исклучено"</item>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index fc004c0..17b1c3d 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"പുതിയ ഉപകരണം ജോടിയാക്കാൻ ക്ലിക്ക് ചെയ്യുക"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"പ്രീസെറ്റ് അപ്ഡേറ്റ് ചെയ്യാനായില്ല"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"പ്രീസെറ്റ്"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"തിരഞ്ഞെടുത്തു"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"സറൗണ്ടിംഗ്‌സ്"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ഇടത്"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"വലത്"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"സറൗണ്ടിംഗ്‌സ്"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ഇടത് സറൗണ്ടിംഗ്‌സ്"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"വലത് സറൗണ്ടിംഗ്‌സ്"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"വേർതിരിച്ച ഇടത്, വലത് നിയന്ത്രണങ്ങളിലേക്ക് വികസിപ്പിക്കുക"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ഏകീകൃത നിയന്ത്രണത്തിലേക്ക് ചുരുക്കുക"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"സറൗണ്ടിംഗ്‌സ് മ്യൂട്ട് ചെയ്യുക"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"സറൗണ്ടിംഗ്‌സ് അൺമ്യൂട്ട് ചെയ്യുക"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ടൂളുകൾ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"തത്സമയ ക്യാപ്ഷൻ"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ക്രമീകരണം"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"കുറിപ്പ്"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ഉപകരണ മൈക്രോഫോൺ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ഉപകരണ ക്യാമറ അൺബ്ലോക്ക് ചെയ്യണോ?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"നിങ്ങളുടെ ആപ്പ് പങ്കിടുമ്പോൾ, ആ ആപ്പിൽ കാണിക്കുന്നതോ പ്ലേ ചെയ്യുന്നതോ ആയ എല്ലാ കാര്യങ്ങളും <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> എന്നതിന് ദൃശ്യമാകും. അതിനാൽ പാസ്‍വേഡുകൾ, പേയ്‌മെന്റ് വിശദാംശങ്ങൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ, ഓഡിയോ, വീഡിയോ എന്നിവ പോലുള്ള കാര്യങ്ങളിൽ ശ്രദ്ധ പുലർത്തുക."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"സ്‌ക്രീൻ പങ്കിടുക"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ഈ ഓപ്‌ഷൻ പ്രവർത്തനരഹിതമാക്കി"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"പങ്കിടാൻ ആപ്പ് തിരഞ്ഞെടുക്കുക"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"നിങ്ങളുടെ സ്ക്രീൻ കാസ്റ്റ് ചെയ്യണോ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ഒരു ആപ്പ് കാസ്റ്റ് ചെയ്യുക"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ഓണാണ് - ഫേസ് ബേസ്‌ഡ്"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"പൂർത്തിയായി"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ബാധകമാക്കുക"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"അറിയിപ്പുകൾ ഓഫാക്കുക"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"നിശബ്‌ദം"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ഡിഫോൾട്ട്"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"സ്വയമേവ"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"വലതുവശത്തുള്ള ആപ്പിനൊപ്പം സ്‌ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുക"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ഇടതുവശത്തുള്ള ആപ്പിനൊപ്പം സ്‌ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുക"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"പൂർണ സ്ക്രീൻ ഉപയോഗിക്കുക"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ഡെസ്ക്ടോപ്പ് വിൻഡോയിംഗ് ഉപയോഗിക്കുക"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ വലതുവശത്തെ/താഴത്തെ ആപ്പിലേക്ക് മാറുക"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"സ്ക്രീൻ വിഭജന മോഡ് ഉപയോഗിക്കുമ്പോൾ ഇടതുവശത്തെ/മുകളിലെ ആപ്പിലേക്ക് മാറൂ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"സ്‌ക്രീൻ വിഭജന മോഡിൽ: ഒരു ആപ്പിൽ നിന്ന് മറ്റൊന്നിലേക്ക് മാറുക"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"നീക്കംചെയ്യുന്നതിന് ഇവിടെ വലിച്ചിടുക"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"നിങ്ങൾക്ക് ചുരുങ്ങിയത് <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ടൈലുകളെങ്കിലും വേണം"</string>
     <string name="qs_edit" msgid="5583565172803472437">"എഡിറ്റ് ചെയ്യുക"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"സമയം"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"മണിക്കൂറും മിനിറ്റും സെക്കൻഡും കാണിക്കുക"</item>
@@ -1207,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ആപ്പിനുള്ള ഈ മീഡിയാ കൺട്രോൾ മറയ്ക്കണോ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"നിലവിലെ മീഡിയ സെഷൻ മറയ്ക്കാനാകില്ല."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"മറയ്‌ക്കുക"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"പുനരാരംഭിക്കുക"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ക്രമീകരണം"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> എന്ന ആർട്ടിസ്റ്റിന്റെ <xliff:g id="SONG_NAME">%1$s</xliff:g> എന്ന ഗാനം <xliff:g id="APP_LABEL">%3$s</xliff:g> ആപ്പിൽ പ്ലേ ചെയ്യുന്നു"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-ൽ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ml/tiles_states_strings.xml b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
index e197c92..c6ba7f1 100644
--- a/packages/SystemUI/res/values-ml/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ml/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"ഓഫാണ്"</item>
     <item msgid="4875147066469902392">"ഓണാണ്"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"ലഭ്യമല്ല"</item>
+    <item msgid="8589336868985358191">"ഓഫാണ്"</item>
+    <item msgid="726072717827778234">"ഓണാണ്"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"ലഭ്യമല്ല"</item>
     <item msgid="5044688398303285224">"ഓഫാണ്"</item>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 7d53c47..ba7baf4 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Шинэ төхөөрөмж хослуулахын тулд товшино уу"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Урьдчилсан тохируулгыг шинэчилж чадсангүй"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Урьдчилсан тохируулга"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Сонгосон"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Орчин тойрон"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Зүүн"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Баруун"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Орчин тойрон"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Зүүн талын орчин тойрны дуу"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Баруун талын орчин тойрны дуу"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Зүүн, баруун талын тусдаа тохиргоо руу дэлгэх"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Нэгдсэн тохиргоо руу хураах"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Орчин тойрны дууг хаах"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Орчин тойрны дууг нээх"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Хэрэгсэл"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Шууд тайлбар"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Тохиргоо"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Тэмдэглэл"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Төхөөрөмжийн микрофоныг блокоос гаргах уу?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Төхөөрөмжийн камерыг блокоос гаргах уу?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Таныг апп хуваалцаж байхад тухайн аппад харуулж эсвэл тоглуулж буй аливаа зүйл <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>-д харагдана. Тиймээс нууц үг, төлбөрийн дэлгэрэнгүй, мессеж, зураг, аудио, видео зэрэг зүйлд болгоомжтой хандаарай."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Дэлгэцийг хуваалцах"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> энэ сонголтыг идэвхгүй болгосон"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Хуваалцах апп сонгох"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Дэлгэцээ дамжуулах уу?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Нэг апп дамжуулах"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Асаалттай - Царайнд суурилсан"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Болсон"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Ашиглах"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Мэдэгдлийг унтраах"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Чимээгүй"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Өгөгдмөл"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автомат"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Аппыг баруун талд байгаагаар дэлгэцийг хуваахыг ашиглах"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Аппыг зүүн талд байгаагаар дэлгэцийг хуваахыг ашиглах"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Бүтэн дэлгэцийг ашиглах"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Дэлгэцийн цонх үүсгэх онцлогийг ашиглах"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Дэлгэц хуваахыг ашиглаж байхдаа баруун талд эсвэл доор байх апп руу сэлгэ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Дэлгэц хуваахыг ашиглаж байхдаа зүүн талд эсвэл дээр байх апп руу сэлгэ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Дэлгэц хуваах үеэр: аппыг нэгээс нөгөөгөөр солих"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Устгахын тулд энд зөөнө үү"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Танд хамгийн багадаа <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> хавтан шаардлагатай"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Засах"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Цаг"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Цаг, минут, секундийг харуулах"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> байрлалд нэмнэ үү"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Байрлал буруу байна."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> байрлал"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Хавтан аль хэдийн нэмсэн"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Хавтан нэмсэн"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Хавтанг хассан"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Шуурхай тохиргоо засварлагч."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Энэ медиа хяналтыг <xliff:g id="APP_NAME">%1$s</xliff:g>-д нуух уу?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Одоогийн медиа харилцан үйлдлийг нуух боломжгүй."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Нуух"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Үргэлжлүүлэх"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Тохиргоо"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> дээр тоглуулж буй <xliff:g id="ARTIST_NAME">%2$s</xliff:g>-н <xliff:g id="SONG_NAME">%1$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>-н <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-mn/tiles_states_strings.xml b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
index 7ca88e9..394c42e 100644
--- a/packages/SystemUI/res/values-mn/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mn/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Унтраалттай"</item>
     <item msgid="4875147066469902392">"Асаалттай"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Боломжгүй"</item>
+    <item msgid="8589336868985358191">"Унтраалттай"</item>
+    <item msgid="726072717827778234">"Асаалттай"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Боломжгүй"</item>
     <item msgid="5044688398303285224">"Унтраалттай"</item>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 9eca378..d6d8e1c 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नवीन डिव्हाइस पेअर करण्यासाठी क्लिक करा"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रीसेट अपडेट करता आले नाही"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"प्रीसेट"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"निवडला आहे"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"जवळपासचे"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"डावे"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"उजवे"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"सभोवताली"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"डाव्या बाजूचा आवाज"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"उजव्या बाजूचा आवाज"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"डाव्या आणि उजव्या स्वतंत्र नियंत्रणांचा विस्तार करा"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"युनिफाइड नियंत्रणासाठी कोलॅप्स करा"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"जवळपासचे आवाज म्यूट करा"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"जवळपासचे आवाज अनम्यूट करा"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टूल"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइव्ह कॅप्शन"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"सेटिंग्ज"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"टीप"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिव्हाइसचा मायक्रोफोन अनब्लॉक करायचा आहे का?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिव्हाइसचा कॅमेरा अनब्लॉक करायचा आहे का?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"तुम्ही अ‍ॅप शेअर करता, तेव्हा त्या अ‍ॅपमध्ये दाखवल्या किंवा प्ले होणाऱ्या कोणत्याही गोष्टी <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> साठी दृश्यमान असतात. त्यामुळे पासवर्ड, पेमेंट तपशील, मेसेज, फोटो आणि ऑडिओ व व्हिडिओ यांसारख्या गोष्टींबाबत सावधगिरी बाळगा."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"स्क्रीन शेअर करा"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> हा पर्याय बंद केला आहे"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"शेअर करण्यासाठी अ‍ॅप निवडा"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"तुमची स्क्रीन कास्ट करायची आहे का?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"एक अ‍ॅप कास्ट करा"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"सुरू - चेहऱ्यावर आधारित"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"पूर्ण झाले"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"लागू करा"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"सूचना बंद करा"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"सायलंट"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"डीफॉल्ट"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ऑटोमॅटिक"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ॲप उजवीकडे ठेवून स्प्लिट स्क्रीन वापरा"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ॲप डावीकडे ठेवून स्प्लिट स्क्रीन वापरा"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"फुल स्क्रीन वापरा"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"डेस्कटॉप विंडोइंग वापरा"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रीन वापरताना उजवीकडील किंवा खालील अ‍ॅपवर स्विच करा"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रीन वापरताना डावीकडील किंवा वरील अ‍ॅपवर स्विच करा"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रीनदरम्यान: एक अ‍ॅप दुसऱ्या अ‍ॅपने बदला"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"काढण्यासाठी येथे ड्रॅग करा"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"तुम्हाला किमान <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> टाइलची गरज आहे"</string>
     <string name="qs_edit" msgid="5583565172803472437">"संपादित करा"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"वेळ"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"तास, मिनिटे आणि सेकंद दर्शवा"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> स्थानावर जोडा"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"स्थान चुकीचे आहे."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"स्थान <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"टाइल आधीपासून जोडली आहे"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल जोडली"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल काढून टाकली"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिंग्ज संपादक."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> साठी हा मीडिया नियंत्रक लपवायचा आहे का?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"सध्याचे मीडिया सेशन लपवू शकत नाही."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लपवा"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"पुन्हा सुरू करा"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग्ज"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> मध्ये <xliff:g id="ARTIST_NAME">%2$s</xliff:g> चे <xliff:g id="SONG_NAME">%1$s</xliff:g> प्ले होत आहे"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> पैकी <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-mr/tiles_states_strings.xml b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
index 58c4d06..4809c74 100644
--- a/packages/SystemUI/res/values-mr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-mr/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"बंद आहे"</item>
     <item msgid="4875147066469902392">"सुरू आहे"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"उपलब्ध नाही"</item>
+    <item msgid="8589336868985358191">"बंद आहे"</item>
+    <item msgid="726072717827778234">"सुरू आहे"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"उपलब्ध नाही"</item>
     <item msgid="5044688398303285224">"बंद आहे"</item>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 7f7c777..2aa5068 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik untuk menggandingkan peranti baharu"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Tidak dapat mengemaskinikan pratetapan"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Pratetapan"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Dipilih"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Persekitaran"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kiri"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Nyahredam persekitaran"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Alatan"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Sari Kata Langsung"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Tetapan"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Nota"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Nyahsekat mikrofon peranti?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Nyahsekat kamera peranti?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Apabila anda berkongsi apl, apa-apa sahaja kandungan yang dipaparkan atau dimainkan dalam apl tersebut boleh dilihat oleh <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Oleh hal yang demikian, berhati-hati dengan perkara seperti kata laluan, butiran pembayaran, mesej, foto dan audio serta video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Kongsi skrin"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> telah melumpuhkan pilihan ini"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Pilih apl untuk dikongsi"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Hantar skrin anda?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Hantar satu apl"</string>
@@ -795,7 +800,7 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Hidup - Berasaskan wajah"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Selesai"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Guna"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Matikan pemberitahuan"</string>
+    <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Matikan"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Senyap"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Lalai"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatik"</string>
@@ -906,8 +911,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gunakan skrin pisah dengan apl pada sebelah kanan"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gunakan skrin pisah dengan apl pada sebelah kiri"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Gunakan skrin penuh"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Gunakan tetingkap desktop"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Tukar kepada apl di sebelah kanan/bawah semasa menggunakan skrin pisah"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Tukar kepada apl di sebelah kiri/atas semasa menggunakan skrin pisah"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Semasa skrin pisah: gantikan apl daripada satu apl kepada apl lain"</string>
@@ -981,6 +985,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Seret ke sini untuk mengalih keluar"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Anda memerlukan sekurang-kurangnya <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> jubin"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Edit"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Masa"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Tunjukkan jam, minit dan saat"</item>
@@ -1003,8 +1009,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Tambahkan pada kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Kedudukan tidak sah."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Kedudukan <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Jubin sudah ditambahkan"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Jubin ditambah"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Jubin dialih keluar"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor tetapan pantas."</string>
@@ -1205,7 +1210,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Sembunyikan kawalan media ini untuk <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Sesi media semasa tidak dapat disembunyikan."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Sembunyikan"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Sambung semula"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Tetapan"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> oleh <xliff:g id="ARTIST_NAME">%2$s</xliff:g> dimainkan daripada <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> daripada <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ms/tiles_states_strings.xml b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
index 5a55b76..8854443 100644
--- a/packages/SystemUI/res/values-ms/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ms/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Mati"</item>
     <item msgid="4875147066469902392">"Hidup"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Tidak tersedia"</item>
+    <item msgid="8589336868985358191">"Mati"</item>
+    <item msgid="726072717827778234">"Hidup"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Tidak tersedia"</item>
     <item msgid="5044688398303285224">"Mati"</item>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 42cfe5e..70f8259 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"စက်အသစ် တွဲချိတ်ရန် နှိပ်ပါ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"အသင့်သုံးကို အပ်ဒိတ်လုပ်၍မရပါ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ကြိုတင်သတ်မှတ်ချက်"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ရွေးထားသည်"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"ဝန်းကျင်အသံ"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ဘယ်"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ညာ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"ဝန်းကျင်အသံ"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ဘယ်ဘက် ဝန်းကျင်အသံ"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"ညာဘက် ဝန်းကျင်အသံ"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ဘယ်ညာခွဲထားသော ထိန်းချုပ်မှုများအဖြစ် ပိုပြပါ"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ပေါင်းစည်းထားသော ထိန်းချုပ်မှုအဖြစ် လျှော့ပြပါ"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ဝန်းကျင်အသံ ပိတ်ရန်"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ဝန်းကျင်အသံ ပြန်ဖွင့်ရန်"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"တူးလ်များ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"တိုက်ရိုက်စာတန်း"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ဆက်တင်များ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"မှတ်စု"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"စက်၏မိုက်ခရိုဖုန်းကို ပြန်ဖွင့်မလား။"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"စက်၏ကင်မရာကို ပြန်ဖွင့်မလား။"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"အက်ပ်ကို မျှဝေနေချိန်တွင် ယင်းအက်ပ်တွင် ပြထားသော (သို့) ဖွင့်ထားသော အရာအားလုံးကို <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> က မြင်နိုင်သည်။ စကားဝှက်၊ ငွေပေးချေမှု အချက်အလက်၊ မက်ဆေ့ဂျ်၊ ဓာတ်ပုံ၊ အသံနှင့် ဗီဒီယိုကဲ့သို့ အရာများကို ဂရုစိုက်ပါ။"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"စခရင် မျှဝေရန်"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် ဤရွေးစရာကို ပိတ်ထားသည်"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"မျှဝေရန် အက်ပ်ရွေးခြင်း"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"သင့်ဖန်သားပြင်ကို ကာစ်လုပ်မလား။"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"အက်ပ်တစ်ခုကို ကာစ်လုပ်ရန်"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ဖွင့် - မျက်နှာအခြေခံ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ပြီးပြီ"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"အသုံးပြုရန်"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"အကြောင်းကြားချက်များ ပိတ်ရန်"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"အသံပိတ်ရန်"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"မူလ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"အလိုအလျောက်"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"အက်ပ်ကို ညာ၌ထားကာ မျက်နှာပြင် ခွဲ၍ပြသခြင်း သုံးရန်"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"အက်ပ်ကို ဘယ်၌ထားကာ မျက်နှာပြင် ခွဲ၍ပြသခြင်း သုံးရန်"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ဖန်သားပြင်အပြည့် သုံးရန်"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ဒက်စ်တော့ဝင်းဒိုးမုဒ် သုံးရန်"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"မျက်နှာပြင်ခွဲ၍ပြသခြင်း သုံးစဉ် ညာ (သို့) အောက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"မျက်နှာပြင် ခွဲ၍ပြသခြင်းသုံးစဉ် ဘယ် (သို့) အထက်ရှိအက်ပ်သို့ ပြောင်းရန်"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"မျက်နှာပြင် ခွဲ၍ပြသစဉ်- အက်ပ်တစ်ခုကို နောက်တစ်ခုနှင့် အစားထိုးရန်"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ဖယ်ရှားရန် ဤနေရာသို့ဖိဆွဲပါ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"အနည်းဆုံး <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ကွက် ရှိရမည်"</string>
     <string name="qs_edit" msgid="5583565172803472437">"တည်းဖြတ်ရန်"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"အချိန်"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"နာရီ၊ မိနစ်နှင့် စက္ကန့်ကိုပြပါ"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထားသို့ ပေါင်းထည့်ရန်"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"နေရာ မမှန်ပါ။"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g> အနေအထား"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"အကွက်ငယ် ထည့်ပြီးဖြစ်သည်"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"အကွက်ငယ်ကို ထည့်ပြီးပါပြီ"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"အကွက်ငယ်ကို ဖယ်ရှားပြီးပါပြီ"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"မြန်ဆန်သည့် ဆက်တင်တည်းဖြတ်စနစ်"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> အတွက် ဤမီဒီယာထိန်းချုပ်မှု ဖျောက်ထားမလား။"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"လက်ရှိ မီဒီယာစက်ရှင်ကို ဝှက်၍မရပါ။"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ဖျောက်ထားမည်"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"ဆက်လုပ်ရန်"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ဆက်တင်များ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> ၏ <xliff:g id="SONG_NAME">%1$s</xliff:g> ကို <xliff:g id="APP_LABEL">%3$s</xliff:g> တွင် ဖွင့်ထားသည်"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> အနက် <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-my/tiles_states_strings.xml b/packages/SystemUI/res/values-my/tiles_states_strings.xml
index 7789205..7522123 100644
--- a/packages/SystemUI/res/values-my/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-my/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"ပိတ်"</item>
     <item msgid="4875147066469902392">"ဖွင့်"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"မရနိုင်ပါ"</item>
+    <item msgid="8589336868985358191">"ပိတ်"</item>
+    <item msgid="726072717827778234">"ဖွင့်"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"မရနိုင်ပါ"</item>
     <item msgid="5044688398303285224">"ပိတ်"</item>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 3b6e891..82aeb65 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klikk for å koble til en ny enhet"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kunne ikke oppdatere forhåndsinnstillingen"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Forhåndsinnstilling"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Valgt"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivelser"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Venstre"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Høyre"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Omgivelser"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Omgivelser til venstre"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Omgivelser til høyre"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Utvid til separate kontroller for venstre og høyre"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Skjul til samlet kontroll"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Kutt lyden for omgivelsene"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Slå på lyden for omgivelsene"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktøy"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Direkteteksting"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Innstillinger"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Merknad"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vil du oppheve blokkeringen av enhetsmikrofonen?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vil du oppheve blokkeringen av enhetskameraet?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Når du deler en app, er alt som vises eller spilles av i appen, synlig for <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Derfor bør du være forsiktig med for eksempel passord, betalingsopplysninger, meldinger, bilder, lyd og video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Del skjermen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har deaktivert dette alternativet"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Velg app å dele"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vil du caste skjermen?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Cast én app"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"På – ansiktsbasert"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Ferdig"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Bruk"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Slå av varsler"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Lydløs"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisk"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Bruk delt skjerm med appen til høyre"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Bruk delt skjerm med appen til venstre"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Bruk fullskjerm"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Bruk datamaskinvinduer"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bytt til appen til høyre eller under mens du bruker delt skjerm"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bytt til appen til venstre eller over mens du bruker delt skjerm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"I delt skjerm: Bytt ut en app"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Dra hit for å fjerne"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Du trenger minst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> infobrikker"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Endre"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Tid"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Vis timer, minutter og sekunder"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Legg til posisjonen <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posisjonen er ugyldig."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posisjon <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Brikken er lagt til allerede"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"En infobrikke er lagt til"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"En infobrikke er fjernet"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redigeringsvindu for hurtiginnstillinger."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Vil du skjule denne mediekontrollen for <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Den nåværende medieøkten kan ikke skjules."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skjul"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> av <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spilles av fra <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-nb/tiles_states_strings.xml b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
index 25b2205..975c1c1 100644
--- a/packages/SystemUI/res/values-nb/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nb/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Av"</item>
     <item msgid="4875147066469902392">"På"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Utilgjengelig"</item>
+    <item msgid="8589336868985358191">"Av"</item>
+    <item msgid="726072717827778234">"På"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Utilgjengelig"</item>
     <item msgid="5044688398303285224">"Av"</item>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 936a0a6..78164a2 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"नयाँ डिभाइसमा कनेक्ट गर्न क्लिक गर्नुहोस्"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"प्रिसेट अपडेट गर्न सकिएन"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"पूर्वनिर्धारित"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"चयन गरिएको छ"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"वरपरका आवाज"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"बायाँ"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"दायाँ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"सराउन्डिङ साउन्ड"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"बायाँतिरको सराउन्डिङ साउन्ड"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"दायाँतिरको सराउन्डिङ साउन्ड"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"दायाँ र बायाँतर्फको भोल्युम छुट्टाछुट्टै व्यवस्थापन गर्न भोल्युम प्यानल छुट्ट्याउनुहोस्"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"कोल्याप्स गरी एउटै कन्ट्रोल बनाउनुहोस्"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"वरपरका आवाज म्युट गर्नुहोस्"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"वरपरका आवाज अनम्युट गर्नुहोस्"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"टुलहरू"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"लाइभ क्याप्सन"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"सेटिङ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"नोट"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"डिभाइसको माइक्रोफोन अनब्लक गर्ने हो?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"डिभाइसको क्यामेरा अनब्लक गर्ने हो?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"तपाईंले यो एप सेयर गरिरहेका बेला यो एपमा देखाइने वा प्ले गरिने सबै सामग्री <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> मा देखिन्छ। त्यसैले पासवर्ड, भुक्तानीसम्बन्धी विवरण, म्यासेज, फोटो र अडियो तथा भिडियो जस्ता कुरा हेर्दा वा प्ले गर्दा सावधानी अपनाउनुहोला।"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"स्क्रिन सेयर गर्नुहोस्"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले यो विकल्प अफ गर्नुभएको छ"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"सेयर गर्न छनौट गर्नुहोस्"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"स्क्रिन कास्ट गर्ने हो?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"एउटा एप कास्ट गर्नुहोस्"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"अन छ - अनुहारमा आधारित"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"सम्पन्न भयो"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"लागू गर्नुहोस्"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"सूचनाहरू अफ गर्नुहोस्"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"साइलेन्ट"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"डिफल्ट"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"स्वचालित"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"हालको एप दायाँ भागमा पारेर स्प्लिट स्क्रिन प्रयोग गर्नुहोस्"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"हालको एप बायाँ भागमा पारेर स्प्लिट स्क्रिन प्रयोग गर्नुहोस्"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"फुल स्क्रिन प्रयोग गर्नुहोस्"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"डेस्कटप विन्डोइङ प्रयोग गर्नुहोस्"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा दायाँ वा तलको एप चलाउनुहोस्"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"स्प्लिट स्क्रिन प्रयोग गर्दै गर्दा बायाँ वा माथिको एप चलाउनुहोस्"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"स्प्लिट स्क्रिन प्रयोग गरिएका बेला: एउटा स्क्रिनमा भएको एप अर्कोमा लैजानुहोस्"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"हटाउनका लागि यहाँ तान्नुहोस्"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"तपाईंलाई कम्तीमा <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> वटा टाइल चाहिन्छ"</string>
     <string name="qs_edit" msgid="5583565172803472437">"सम्पादन गर्नुहोस्"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"समय"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"घन्टा, मिनेट, र सेकेन्ड देखाउनुहोस्"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"टाइल यो अवस्था <xliff:g id="POSITION">%1$d</xliff:g> मा हाल्नुहोस्"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"पोजिसन अवैध छ।"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"टाइल हालिसकिएको छ"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"टाइल हालियो"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"टाइल हटाइयो"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"द्रुत सेटिङ सम्पादक।"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> का हकमा यो मिडिया कन्ट्रोल लुकाउने हो?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"हालको मिडिया सत्र लुकाउन मिल्दैन।"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"लुकाउनुहोस्"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"सुचारु गर्नुहोस्"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिङ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> को <xliff:g id="SONG_NAME">%1$s</xliff:g> बोलको गीत <xliff:g id="APP_LABEL">%3$s</xliff:g> मा बज्दै छ"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> मध्ये <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ne/tiles_states_strings.xml b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
index fe812f8..f48daa3 100644
--- a/packages/SystemUI/res/values-ne/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ne/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"अफ छ"</item>
     <item msgid="4875147066469902392">"अन छ"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"उपलब्ध छैन"</item>
+    <item msgid="8589336868985358191">"अफ छ"</item>
+    <item msgid="726072717827778234">"अन छ"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"उपलब्ध छैन"</item>
     <item msgid="5044688398303285224">"अफ छ"</item>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 2a81bb4..fe6f348 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klik om nieuw apparaat te koppelen"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Kan voorinstelling niet updaten"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Voorinstelling"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Geselecteerd"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgevingsgeluid"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Links"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Omgevingsgeluid aanzetten"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Tools"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live ondertiteling"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Instellingen"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notitie"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Microfoon van apparaat niet meer blokkeren?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Apparaatcamera niet meer blokkeren?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Als je een app deelt, is alles dat wordt getoond of afgespeeld in die app zichtbaar voor <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Wees daarom voorzichtig met bijvoorbeeld wachtwoorden, betalingsgegevens, berichten, foto\'s, en audio en video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Scherm delen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Voor <xliff:g id="APP_NAME">%1$s</xliff:g> staat deze optie uit"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"App kiezen om te delen"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Je scherm casten?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Eén app casten"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aan: op basis van gezicht"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Klaar"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Toepassen"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Meldingen uitzetten"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Stil"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standaard"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatisch"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gesplitst scherm gebruiken met de app aan de rechterkant"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gesplitst scherm gebruiken met de app aan de linkerkant"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Volledig scherm gebruiken"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Desktopvensterfuncties gebruiken"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Naar de app rechts of onderaan gaan als je een gesplitst scherm gebruikt"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Naar de app links of bovenaan gaan als je een gesplitst scherm gebruikt"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Tijdens gesplitst scherm: een app vervangen door een andere"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Sleep hier naartoe om te verwijderen"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Je hebt minimaal <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> tegels nodig"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Bewerken"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Tijd"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Uren, minuten en seconden tonen"</item>
@@ -1003,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Toevoegen aan positie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Positie ongeldig."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Positie <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Tegel is al toegevoegd"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Tegel toegevoegd"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Tegel verwijderd"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor voor \'Snelle instellingen\'."</string>
@@ -1205,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Deze mediabediening verbergen voor <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"De huidige mediasessie kan niet worden verborgen."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Verbergen"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Hervatten"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Instellingen"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> van <xliff:g id="ARTIST_NAME">%2$s</xliff:g> wordt afgespeeld via <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> van <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-nl/tiles_states_strings.xml b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
index bb8fbe0..b739fa2 100644
--- a/packages/SystemUI/res/values-nl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-nl/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Uit"</item>
     <item msgid="4875147066469902392">"Aan"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Niet beschikbaar"</item>
+    <item msgid="8589336868985358191">"Uit"</item>
+    <item msgid="726072717827778234">"Aan"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Niet beschikbaar"</item>
     <item msgid="5044688398303285224">"Uit"</item>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index e12fe7e..fa16f28 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"ନୂଆ ଡିଭାଇସ ପେୟାର କରିବାକୁ କ୍ଲିକ କରନ୍ତୁ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ପ୍ରିସେଟକୁ ଅପଡେଟ କରାଯାଇପାରିଲା ନାହିଁ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ପ୍ରିସେଟ"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ଚୟନ କରାଯାଇଛି"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"ପରିପାର୍ଶ୍ୱ"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ବାମ"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ଡାହାଣ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"ପରିପାର୍ଶ୍ୱ"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ବାମ ପରିପାର୍ଶ୍ୱ"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"ଡାହାଣ ପରିପାର୍ଶ୍ୱ"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ବାମ ଏବଂ ଡାହାଣ ଅଲଗା ନିୟନ୍ତ୍ରଣକୁ ବିସ୍ତାର କରନ୍ତୁ"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ଏକତ୍ରିତ ନିୟନ୍ତ୍ରଣକୁ ସଙ୍କୁଚିତ କରନ୍ତୁ"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ପରିପାର୍ଶ୍ୱକୁ ମ୍ୟୁଟ କରନ୍ତୁ"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ପରିପାର୍ଶ୍ୱକୁ ଅନମ୍ୟୁଟ କରନ୍ତୁ"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ଟୁଲ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ଲାଇଭ କେପ୍ସନ"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ସେଟିଂସ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ନୋଟ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ଡିଭାଇସର ମାଇକ୍ରୋଫୋନକୁ ଅନବ୍ଲକ କରିବେ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ଡିଭାଇସର କେମେରାକୁ ଅନବ୍ଲକ କରିବେ?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ଆପଣ ଏକ ଆପ ସେୟାର କରିବା ସମୟରେ, ସେହି ଆପରେ ଦେଖାଯାଉଥିବା କିମ୍ବା ପ୍ଲେ ହେଉଥିବା ସବୁକିଛି <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>କୁ ଦେଖାଯାଏ। ତେଣୁ ପାସୱାର୍ଡ, ପେମେଣ୍ଟ ବିବରଣୀ, ମେସେଜ, ଫଟୋ ଏବଂ ଅଡିଓ ଓ ଭିଡିଓ ପରି ବିଷୟଗୁଡ଼ିକ ପ୍ରତି ସତର୍କ ରୁହନ୍ତୁ।"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ସ୍କ୍ରିନ ସେୟାର କରନ୍ତୁ"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ଏହି ବିକଳ୍ପକୁ ଅକ୍ଷମ କରିଛି"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ସେୟାର କରିବାକୁ ଆପ ବାଛନ୍ତୁ"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ କାଷ୍ଟ କରିବେ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ଗୋଟିଏ ଆପକୁ କାଷ୍ଟ କରନ୍ତୁ"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ଚାଲୁ ଅଛି - ଫେସ-ଆଧାରିତ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ହୋଇଗଲା"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ଲାଗୁ କରନ୍ତୁ"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ବିଜ୍ଞପ୍ତି ବନ୍ଦ କରନ୍ତୁ"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"ନୀରବ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ଡିଫଲ୍ଟ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ସ୍ୱଚାଳିତ"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ଡାହାଣରେ ଆପ ସହିତ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ବାମରେ ଆପ ସହିତ ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନକୁ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ଡେସ୍କଟପ ୱିଣ୍ଡୋଇଂ ବ୍ୟବହାର କରନ୍ତୁ"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ଡାହାଣପଟର ବା ତଳର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବା ସମୟରେ ବାମପଟର ବା ଉପରର ଆପକୁ ସୁଇଚ କରନ୍ତୁ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ସମୟରେ: କୌଣସି ଆପକୁ ଗୋଟିଏରୁ ଅନ୍ୟ ଏକ ଆପରେ ବଦଳାନ୍ତୁ"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ବାହାର କରିବାକୁ ଏଠାକୁ ଡ୍ରାଗ୍‍ କରନ୍ତୁ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"ଆପଣଙ୍କର ଅତିକମ୍‌ରେ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>ଟି ଟାଇଲ୍ ଆବଶ୍ୟକ"</string>
     <string name="qs_edit" msgid="5583565172803472437">"ଏଡିଟ କରନ୍ତୁ"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"ସମୟ"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ଘଣ୍ଟା, ମିନିଟ୍‍ ଏବଂ ସେକେଣ୍ଡ ଦେଖାନ୍ତୁ"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ଅବସ୍ଥିତିରେ ଯୋଗ କରନ୍ତୁ"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ଅବସ୍ଥିତି ଅବୈଧ ଅଟେ।"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ଅବସ୍ଥିତି <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ପୂର୍ବରୁ ଟାଇଲକୁ ଯୋଗ କରାଯାଇଛି"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ଟାଇଲ୍ ଯୋଗ କରାଯାଇଛି"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ଟାଇଲ୍ କାଢ଼ି ଦିଆଯାଇଛି"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ଦ୍ରୁତ ସେଟିଙ୍ଗ ଏଡିଟର୍।"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ପାଇଁ ଏହି ମିଡିଆ ନିୟନ୍ତ୍ରଣକୁ ଲୁଚାଇବେ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"ବର୍ତ୍ତମାନର ମିଡିଆ ସେସନକୁ ଲୁଚାଯାଇପାରିବ ନାହିଁ।"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ଲୁଚାନ୍ତୁ"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ସେଟିଂସ୍"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g>ରୁ <xliff:g id="ARTIST_NAME">%2$s</xliff:g>ଙ୍କ <xliff:g id="SONG_NAME">%1$s</xliff:g> ଚାଲୁଛି"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>ରୁ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
@@ -1255,7 +1257,7 @@
     <string name="media_output_dialog_accessibility_title" msgid="4681741064190167888">"ଅଡିଓ ଆଉଟପୁଟ ପାଇଁ ଉପଲବ୍ଧ ଡିଭାଇସଗୁଡ଼ିକ।"</string>
     <string name="media_output_dialog_accessibility_seekbar" msgid="5332843993805568978">"ଭଲ୍ୟୁମ"</string>
     <string name="media_output_dialog_volume_percentage" msgid="1613984910585111798">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
-    <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେଗୁଡ଼ିକ"</string>
+    <string name="media_output_group_title_speakers_and_displays" msgid="7169712332365659820">"ସ୍ପିକର ଏବଂ ଡିସପ୍ଲେ"</string>
     <string name="media_output_group_title_suggested_device" msgid="4157186235837903826">"ପ୍ରସ୍ତାବିତ ଡିଭାଇସଗୁଡ଼ିକ"</string>
     <string name="media_input_group_title" msgid="2057057473860783021">"ଇନପୁଟ"</string>
     <string name="media_output_group_title" msgid="6789001895863332576">"ଆଉଟପୁଟ"</string>
diff --git a/packages/SystemUI/res/values-or/tiles_states_strings.xml b/packages/SystemUI/res/values-or/tiles_states_strings.xml
index eae984b..37d3c95 100644
--- a/packages/SystemUI/res/values-or/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-or/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"ବନ୍ଦ ଅଛି"</item>
     <item msgid="4875147066469902392">"ଚାଲୁ ଅଛି"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"ଉପଲବ୍ଧ ନାହିଁ"</item>
     <item msgid="5044688398303285224">"ବନ୍ଦ ଅଛି"</item>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 26d26dc..98d56e3 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"\'ਨਵਾਂ ਡੀਵਾਈਸ ਜੋੜਾਬੱਧ ਕਰੋ\' \'ਤੇ ਕਲਿੱਕ ਕਰੋ"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ਪ੍ਰੀਸੈੱਟ ਨੂੰ ਅੱਪਡੇਟ ਨਹੀਂ ਕੀਤਾ ਜਾ ਸਕਿਆ"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ਪ੍ਰੀਸੈੱਟ"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ਚੁਣਿਆ ਗਿਆ"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"ਆਲੇ-ਦੁਆਲੇ"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ਖੱਬੇ"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"ਸੱਜੇ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"ਸਰਾਊਂਡ ਸਾਊਂਡ"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"ਖੱਬੇ ਪਾਸੇ ਦਾ ਸਰਾਊਂਡ ਸਾਊਂਡ"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"ਸੱਜੇ ਪਾਸੇ ਦਾ ਸਰਾਊਂਡ ਸਾਊਂਡ"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"ਖੱਬੇ ਅਤੇ ਸੱਜੇ ਪਾਸੇ ਦੇ ਸ਼ੋਰ ਨੂੰ ਵੱਖ-ਵੱਖ ਕੰਟਰੋਲ ਕਰਨ ਲਈ ਵਿਸਤਾਰ ਕਰੋ"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ਏਕੀਕ੍ਰਿਤ ਕੰਟਰੋਲ \'ਤੇ ਜਾਣ ਲਈ ਸਮੇਟੋ"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"ਆਲੇ-ਦੁਆਲੇ ਦੇ ਸ਼ੋਰ ਨੂੰ ਮਿਊਟ ਕਰੋ"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"ਆਲੇ-ਦੁਆਲੇ ਦੇ ਸ਼ੋਰ ਨੂੰ ਅਣਮਿਊਟ ਕਰੋ"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ਟੂਲ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"ਲਾਈਵ ਸੁਰਖੀਆਂ"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"ਨੋਟ-ਕਥਨ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"ਕੀ ਡੀਵਾਈਸ ਦੇ ਕੈਮਰੇ ਨੂੰ ਅਣਬਲਾਕ ਕਰਨਾ ਹੈ?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ਕਿਸੇ ਐਪ ਨੂੰ ਸਾਂਝਾ ਕਰਨ ਦੌਰਾਨ, ਉਸ ਐਪ \'ਤੇ ਦਿਖ ਰਹੀ ਜਾਂ ਚਲਾਈ ਗਈ ਹਰੇਕ ਚੀਜ਼ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ਨੂੰ ਦਿਖਣਯੋਗ ਹੁੰਦੀ ਹੈ। ਇਸ ਲਈ ਪਾਸਵਰਡਾਂ, ਭੁਗਤਾਨ ਵੇਰਵਿਆਂ, ਸੁਨੇਹਿਆਂ, ਫ਼ੋਟੋਆਂ ਅਤੇ ਆਡੀਓ ਅਤੇ ਵੀਡੀਓ ਵਰਗੀਆਂ ਚੀਜ਼ਾਂ ਵਾਸਤੇ ਸਾਵਧਾਨ ਰਹੋ।"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"ਸਕ੍ਰੀਨ ਸਾਂਝੀ ਕਰੋ"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਨੇ ਇਸ ਵਿਕਲਪ ਨੂੰ ਬੰਦ ਕਰ ਦਿੱਤਾ ਹੈ"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"ਸਾਂਝਾ ਕਰਨ ਲਈ ਐਪ ਚੁਣੋ"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ਕੀ ਸਕ੍ਰੀਨ ਨੂੰ ਕਾਸਟ ਕਰਨਾ ਹੈ?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ਇੱਕ ਐਪ ਨੂੰ ਕਾਸਟ ਕਰੋ"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ਚਾਲੂ ਹੈ - ਚਿਹਰਾ-ਆਧਾਰਿਤ"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ਹੋ ਗਿਆ"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ਲਾਗੂ ਕਰੋ"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ਸੂਚਨਾਵਾਂ ਬੰਦ ਕਰੋ"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"ਸ਼ਾਂਤ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ਸਵੈਚਲਿਤ"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ਸੱਜੇ ਪਾਸੇ ਵਾਲੀ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ਖੱਬੇ ਪਾਸੇ ਵਾਲੀ ਐਪ ਨਾਲ ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰੋ"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ਡੈਸਕਟਾਪ \'ਤੇ ਇੱਕ ਤੋਂ ਵੱਧ ਵਿੰਡੋਆਂ ਦਿਖਾਉਣ ਵਾਲੀ ਸੁਵਿਧਾ ਵਰਤੋ"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਸੱਜੇ ਜਾਂ ਹੇਠਾਂ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੀ ਵਰਤੋਂ ਕਰਨ ਵੇਲੇ ਖੱਬੇ ਜਾਂ ਉੱਪਰ ਮੌਜੂਦ ਐਪ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਦੌਰਾਨ: ਇੱਕ ਐਪ ਨਾਲ ਦੂਜੀ ਐਪ ਨੂੰ ਬਦਲੋ"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ਹਟਾਉਣ ਲਈ ਇੱਥੇ ਘਸੀਟੋ"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"ਤੁਹਾਨੂੰ ਘੱਟੋ-ਘੱਟ <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ਟਾਇਲਾਂ ਦੀ ਲੋੜ ਪਵੇਗੀ"</string>
     <string name="qs_edit" msgid="5583565172803472437">"ਸੰਪਾਦਨ ਕਰੋ"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"ਸਮਾਂ"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"ਘੰਟੇ, ਮਿੰਟ, ਅਤੇ ਸਕਿੰਟ  ਦਿਖਾਓ"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ਸਥਾਨ \'ਤੇ ਸ਼ਾਮਲ ਕਰੋ"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ਮੌਜੂਦਾ ਥਾਂ ਅਵੈਧ ਹੈ।"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ਸਥਾਨ <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ਟਾਇਲ ਨੂੰ ਪਹਿਲਾਂ ਹੀ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ਟਾਇਲ ਨੂੰ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ਟਾਇਲ ਨੂੰ ਹਟਾ ਦਿੱਤਾ ਗਿਆ"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ ਸੰਪਾਦਕ।"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"ਕੀ <xliff:g id="APP_NAME">%1$s</xliff:g> ਲਈ ਇਹ ਮੀਡੀਆ ਕੰਟਰੋਲ ਲੁਕਾਉਣਾ ਹੈ?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"ਮੌਜੂਦਾ ਮੀਡੀਆ ਸੈਸ਼ਨ ਲੁਕਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ਲੁਕਾਓ"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ਤੋਂ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> ਦਾ <xliff:g id="SONG_NAME">%1$s</xliff:g> ਚੱਲ ਰਿਹਾ ਹੈ"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g> ਵਿੱਚੋਂ <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pa/tiles_states_strings.xml b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
index 2baff30..d0f5103 100644
--- a/packages/SystemUI/res/values-pa/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pa/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"ਬੰਦ ਹੈ"</item>
     <item msgid="4875147066469902392">"ਚਾਲੂ ਹੈ"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"ਉਪਲਬਧ ਨਹੀਂ"</item>
+    <item msgid="8589336868985358191">"ਬੰਦ"</item>
+    <item msgid="726072717827778234">"ਚਾਲੂ"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"ਅਣਉਪਲਬਧ ਹੈ"</item>
     <item msgid="5044688398303285224">"ਬੰਦ ਹੈ"</item>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 6b526f2..cdf30a9 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknij, aby sparować nowe urządzenie"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nie udało się zaktualizować gotowego ustawienia"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Gotowe ustawienie"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Wybrano"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Otoczenie"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Po lewej"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Po prawej"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Otoczenie"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Otoczenie z lewej strony"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Otoczenie z prawej strony"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Rozwiń, aby oddzielić elementy sterujące po lewej i po prawej stronie"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Zwiń do ujednoliconego sterowania"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Wycisz otoczenie"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Wyłącz wyciszenie otoczenia"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Narzędzia"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Napisy na żywo"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ustawienia"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notatka"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Odblokować mikrofon urządzenia?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Odblokować aparat urządzenia?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kiedy udostępniasz obraz z aplikacji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, widoczne jest wszystko to, co jest w niej wyświetlane lub odtwarzane. Dlatego zachowaj ostrożność w zakresie haseł, danych do płatności, wiadomości, zdjęć, audio i filmów."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Udostępnij ekran"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ma wyłączoną tę opcję"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Wybierz aplikację do udostępniania"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Włączyć przesyłanie treści z ekranu?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Przesyłanie obrazu z 1 aplikacji"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Włączono – na podstawie twarzy"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Gotowe"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Zastosuj"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Wyłącz powiadomienia"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Ciche"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Domyślne"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatycznie"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Podziel ekran z aplikacją widoczną po prawej"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Podziel ekran z aplikacją widoczną po lewej"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Użyj trybu pełnoekranowego"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Używaj trybu okien na pulpicie"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Przełącz się na aplikację po prawej lub poniżej na podzielonym ekranie"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Przełącz się na aplikację po lewej lub powyżej na podzielonym ekranie"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Podczas podzielonego ekranu: zastępowanie aplikacji"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Przeciągnij tutaj, by usunąć"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimalna liczba kafelków to <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Edytuj"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Godzina"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Pokazuj godziny, minuty i sekundy"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Dodaj w pozycji <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nieprawidłowa pozycja."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozycja <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Kafelek został już dodany"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Dodano kartę"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Usunięto kartę"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Edytor szybkich ustawień."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Ukryć sterowanie multimediami w aplikacji <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Nie można ukryć tej sesji multimediów."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ukryj"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Wznów"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ustawienia"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Aplikacja <xliff:g id="APP_LABEL">%3$s</xliff:g> odtwarza utwór <xliff:g id="SONG_NAME">%1$s</xliff:g> (<xliff:g id="ARTIST_NAME">%2$s</xliff:g>)"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pl/tiles_states_strings.xml b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
index bd3a828..abc1867 100644
--- a/packages/SystemUI/res/values-pl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pl/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"Wyłączone"</item>
     <item msgid="4875147066469902392">"Włączone"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Niedostępny"</item>
     <item msgid="5044688398303285224">"Wyłączona"</item>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 07f87ee..d9bbaf0 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Som ambiente"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lado esquerdo"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Lado direito"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Som ambiente"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ambiente à esquerda"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ambiente à direita"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Abrir para controles separados da esquerda e da direita"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Fechar para controle unificado"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar som ambiente"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ativar som ambiente"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Configurações"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quando você compartilha um aplicativo, todas as informações mostradas ou abertas nele ficam visíveis para o app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartilhar tela"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou essa opção"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Escolha um app para compartilhar"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir a tela?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir um app"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ativada (reconhecimento facial)"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Concluído"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desativar notificações"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silenciosas"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Padrão"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar a tela dividida com o app à direita"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar a tela dividida com o app à esquerda"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar tela cheia"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar modo de janela para computador"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arraste aqui para remover"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"É preciso haver pelo menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> blocos"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Horas"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Mostrar horas, minutos e segundos"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"O bloco já foi adicionado"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloco adicionado"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloco removido"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar este controle de mídia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Não é possível ocultar a sessão de mídia atual."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
index 0233a36..30e45fe 100644
--- a/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"Desativado"</item>
     <item msgid="4875147066469902392">"Ativado"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Indisponível"</item>
     <item msgid="5044688398303285224">"Apagada"</item>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index de1057d..913f5b3 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para sincronizar um novo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambiente"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Esquerda"</string>
@@ -582,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quando está a partilhar uma app, tudo o que é mostrado ou reproduzido nessa app é visível para a app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Por isso, tenha cuidado com, por exemplo, palavras-passe, detalhes de pagamento, mensagens, fotos, áudio e vídeo."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Partilhar ecrã"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou esta opção"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Escolha uma app para partilhar"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir o ecrã?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir uma app"</string>
@@ -794,7 +800,7 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ativada – Com base no rosto"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Concluído"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desativar notificações"</string>
+    <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Desativar"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Silencioso"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predefinição"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
@@ -905,8 +911,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Use o ecrã dividido com a app à direita"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Use o ecrã dividido com a app à esquerda"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Use o ecrã inteiro"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Use janelas de computador"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para a app à direita ou abaixo enquanto usa o ecrã dividido"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mude para a app à esquerda ou acima enquanto usa o ecrã dividido"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Durante o ecrã dividido: substituir uma app por outra"</string>
@@ -980,6 +985,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arrastar para aqui para remover"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Necessita de, pelo menos, <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> cartões"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Hora"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Mostrar horas, minutos e segundos"</item>
@@ -1203,7 +1210,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar controlo de multimédia para a app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Não pode ocultar a sessão de multimédia atual."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Definições"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> em reprodução a partir da app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
index 3beca27..bedcab0 100644
--- a/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Desligado"</item>
     <item msgid="4875147066469902392">"Ligado"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Indisponível"</item>
+    <item msgid="8589336868985358191">"Desativado"</item>
+    <item msgid="726072717827778234">"Ativado"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Indisponível"</item>
     <item msgid="5044688398303285224">"Desligada"</item>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 07f87ee..d9bbaf0 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Clique para parear o novo dispositivo"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Não foi possível atualizar a predefinição"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predefinição"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selecionado"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Som ambiente"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Lado esquerdo"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Lado direito"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Som ambiente"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ambiente à esquerda"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ambiente à direita"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Abrir para controles separados da esquerda e da direita"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Fechar para controle unificado"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Silenciar som ambiente"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Ativar som ambiente"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Ferramentas"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Legenda instantânea"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Configurações"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Observação"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Desbloquear o microfone do dispositivo?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Desbloquear a câmera do dispositivo?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Quando você compartilha um aplicativo, todas as informações mostradas ou abertas nele ficam visíveis para o app <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Tenha cuidado com senhas, detalhes de pagamento, mensagens, fotos, áudios e vídeos."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Compartilhar tela"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> desativou essa opção"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Escolha um app para compartilhar"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Transmitir a tela?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmitir um app"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Ativada (reconhecimento facial)"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Concluído"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplicar"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Desativar notificações"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silenciosas"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Padrão"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automática"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Usar a tela dividida com o app à direita"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Usar a tela dividida com o app à esquerda"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Usar tela cheia"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Usar modo de janela para computador"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Mudar para o app à direita ou abaixo ao usar a tela dividida"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Mudar para o app à esquerda ou acima ao usar a tela dividida"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Com a tela dividida: substituir um app por outro"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Arraste aqui para remover"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"É preciso haver pelo menos <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> blocos"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editar"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Horas"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Mostrar horas, minutos e segundos"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adicionar à posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Posição inválida."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Posição <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"O bloco já foi adicionado"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Bloco adicionado"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Bloco removido"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editor de configurações rápidas."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Ocultar este controle de mídia para <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Não é possível ocultar a sessão de mídia atual."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ocultar"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Tocando <xliff:g id="SONG_NAME">%1$s</xliff:g> de <xliff:g id="ARTIST_NAME">%2$s</xliff:g> no app <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> de <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pt/tiles_states_strings.xml b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
index 0233a36..30e45fe 100644
--- a/packages/SystemUI/res/values-pt/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-pt/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"Desativado"</item>
     <item msgid="4875147066469902392">"Ativado"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Indisponível"</item>
     <item msgid="5044688398303285224">"Apagada"</item>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index a6b4983..906ee09 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Dă clic pentru a asocia un nou dispozitiv"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Nu s-a putut actualiza presetarea"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Presetare"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Selectat"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Împrejurimi"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Stânga"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Dreapta"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Împrejurimi"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Împrejurimi din stânga"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Împrejurimi din dreapta"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Extinde comenzile separate la stânga și la dreapta"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Restrânge la comanda unificată"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Dezactivează sunetul ambiental"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Activează sunetul ambiental"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Instrumente"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Subtitrări live"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Setări"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Notă"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Deblochezi microfonul dispozitivului?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Deblochezi camera dispozitivului?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Când permiți accesul la o aplicație, orice conținut se afișează sau se redă în aplicație este vizibil pentru <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Prin urmare, ai grijă cu parolele, detaliile de plată, mesajele, fotografiile și conținutul audio și video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Permite accesul la ecran"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> a dezactivat această opțiune"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Alege aplicația de trimis"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Proiectezi ecranul?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Proiectează o aplicație"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Activată – În funcție de chip"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Gata"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Aplică"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Dezactivează notificările"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Silențios"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Prestabilite"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automat"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Folosește ecranul împărțit cu aplicația în dreapta"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Folosește ecranul împărțit cu aplicația în stânga"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Folosește ecranul complet"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Folosește funcția de windowing pe desktop"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Treci la aplicația din dreapta sau de mai jos cu ecranul împărțit"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Treci la aplicația din stânga sau de mai sus cu ecranul împărțit"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"În modul ecran împărțit: înlocuiește o aplicație cu alta"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Trage aici pentru a elimina"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Ai nevoie de cel puțin <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> carduri"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Editează"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Oră"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Afișează orele, minutele și secundele"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Adaugă pe poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Poziție nevalidă."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Poziția <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Cardul a fost adăugat deja"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Cardul a fost adăugat"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Cardul a fost eliminat"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Editorul pentru setări rapide."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Ascunzi comanda media pentru <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Sesiunea media actuală nu se poate ascunde."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ascunde"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Reia"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Setări"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> de la <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se redă în <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> din <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ro/tiles_states_strings.xml b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
index b555987..3f893fa 100644
--- a/packages/SystemUI/res/values-ro/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ro/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Dezactivată"</item>
     <item msgid="4875147066469902392">"Activată"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Indisponibil"</item>
+    <item msgid="8589336868985358191">"Dezactivat"</item>
+    <item msgid="726072717827778234">"Activat"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Indisponibilă"</item>
     <item msgid="5044688398303285224">"Dezactivată"</item>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 693024b..ee9d755 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Нажмите, чтобы подключить новое устройство"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не удалось обновить набор настроек."</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набор настроек"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Выбрано"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Окружающие звуки"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Левый"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Не заглушать окружающие звуки"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Инструменты"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Автоматические субтитры"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Настройки"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Заметка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Разблокировать микрофон устройства?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Разблокировать камеру устройства?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"При показе приложения все, что в нем происходит, будет видно в приложении \"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>\". Поэтому будьте осторожны с паролями, сведениями о способах оплаты, сообщениями, фотографиями, аудио- и видеозаписями."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Показать экран"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" отключило эту возможность"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Выбор приложения для демонстрации"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Начать трансляцию экрана?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Транслировать одно приложение"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Включить (на основе распознавания лиц)"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Применить"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Выключить уведомления"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Без звука"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"По умолчанию"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматически"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Разделить экран и поместить открытое приложение справа"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Разделить экран и поместить открытое приложение слева"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Полноэкранный режим"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Использовать компьютерные окна"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти к приложению справа или внизу на разделенном экране"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Перейти к приложению слева или вверху на разделенном экране"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"В режиме разделения экрана заменить одно приложение другим"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Чтобы удалить, перетащите сюда"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Должно остаться не менее <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> элементов"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Изменить"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Время"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Часы, минуты и секунды"</item>
@@ -1003,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Добавить на позицию <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Недопустимое расположение."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиция <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Параметр уже добавлен"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Панель добавлена"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Панель удалена"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор быстрых настроек."</string>
@@ -1205,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Скрыть этот элемент в приложении \"<xliff:g id="APP_NAME">%1$s</xliff:g>\"?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Этот мультимедийный сеанс невозможно скрыть."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Скрыть"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Возобновить"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Воспроизводится медиафайл \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\" (исполнитель: <xliff:g id="ARTIST_NAME">%2$s</xliff:g>) из приложения \"<xliff:g id="APP_LABEL">%3$s</xliff:g>\"."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> из <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ru/tiles_states_strings.xml b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
index 8279183..d20f5e2 100644
--- a/packages/SystemUI/res/values-ru/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ru/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Откл."</item>
     <item msgid="4875147066469902392">"Вкл."</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Недоступно"</item>
+    <item msgid="8589336868985358191">"Отключено"</item>
+    <item msgid="726072717827778234">"Включено"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Функция недоступна"</item>
     <item msgid="5044688398303285224">"Откл."</item>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 8632e13..583d884 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"නව උපාංගය යුගල කිරීමට ක්ලික් කරන්න"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"පෙර සැකසීම යාවත්කාලීන කළ නොහැකි විය"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"පෙරසැකසුම"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"තෝරන ලදි"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"වටපිටාව"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"වම"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"දකුණ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"වටපිටාව"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"වම් වටපිටාව"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"දකුණු වටපිටාව"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"වමට සහ දකුණට වෙන් වූ පාලන වෙත පුළුල් කරන්න"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ඒකාබද්ධ පාලනයට හකුළන්න"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"අවට පරිසරය නිහඬ කරන්න"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"අවට නිහඬ නොකරන්න"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"මෙවලම්"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"සජීවී සිරස්තල"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"සැකසීම්"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"සටහන"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"උපාංග මයික්‍රෆෝනය අවහිර කිරීම ඉවත් කරන්නද?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"උපාංග කැමරාව අවහිර කිරීම ඉවත් කරන්නද?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ඔබ යෙදුමක් බෙදා ගන්නා විට, එම යෙදුමේ පෙන්වන හෝ වාදනය කරන ඕනෑම දෙයක් <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> වෙත දෘශ්‍යමාන වේ. ඒ නිසා මුරපද, ගෙවීම් විස්තර, පණිවිඩ, ඡායාරූප, සහ ශ්‍රව්‍ය සහ දෘශ්‍ය වැනි දේවල් පිළිබඳ ප්‍රවේශම් වන්න."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"තිරය බෙදා ගන්න"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> මෙම විකල්පය අබල කර ඇත"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"බෙදා ගැනීමට යෙදුම තෝරන්න"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"ඔබේ තිරය විකාශය කරන්න ද?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"එක් යෙදුමක් විකාශය කරන්න"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ක්‍රියාත්මකයි - මුහුණ-පදනම්ව"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"නිමයි"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"යොදන්න"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"දැනුම්දීම් අක්‍රිය කරන්න"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"නිහඬ"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"පෙරනිමි"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ස්වයංක්‍රිය"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"දකුණේ යෙදුම සමග බෙදීම් තිරය භාවිතා කරන්න"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"වම් පැත්තේ යෙදුම සමග බෙදීම් තිරය භාවිතා කරන්න"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"පූර්ණ තිරය භාවිතා කරන්න"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ඩෙස්ක්ටොප් කවුළුකරණය භාවිතා කරන්න"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"බෙදුම් තිරය භාවිත කරන අතරතුර දකුණේ හෝ පහළින් ඇති යෙදුමට මාරු වන්න"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"බෙදුම් තිරය භාවිත කරන අතරතුර වමේ හෝ ඉහළ ඇති යෙදුමට මාරු වන්න"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"බෙදුම් තිරය අතරතුර: යෙදුමක් එකකින් තවත් එකක් ප්‍රතිස්ථාපනය කරන්න"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ඉවත් කිරීමට මෙතැනට අදින්න"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"ඔබ අවම වශයෙන් ටයිල් <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ක් අවශ්‍ය වෙයි"</string>
     <string name="qs_edit" msgid="5583565172803472437">"සංස්කරණය"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"වේලාව"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"පැය, මිනිත්තු, සහ තත්පර පෙන්වන්න"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> ස්ථානයට එක් කරන්න"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"ස්ථානය අවලංගුයි."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"ස්ථානය <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"ටයිලය දැනටමත් එක් කර ඇත"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"ටයිල් එක එක් කරන ලදි"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"ටයිල් ඉවත් කරන ලදි"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"ඉක්මන් සැකසුම් සංස්කාරකය."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> සඳහා මෙම මාධ්‍ය පාලනය වසන්නද?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"වත්මන් මාධ්‍ය සැසිය සැඟවිය නොහැකිය."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"සඟවන්න"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"නැවත පටන් ගන්න"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"සැකසීම්"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g>ගේ <xliff:g id="SONG_NAME">%1$s</xliff:g> ගීතය <xliff:g id="APP_LABEL">%3$s</xliff:g> වෙතින් ධාවනය වෙමින් පවතී"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>කින් <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-si/tiles_states_strings.xml b/packages/SystemUI/res/values-si/tiles_states_strings.xml
index 9397ca7..7eeaefd 100644
--- a/packages/SystemUI/res/values-si/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-si/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"අක්‍රියයි"</item>
     <item msgid="4875147066469902392">"සක්‍රියයි"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"නොමැත"</item>
     <item msgid="5044688398303285224">"අක්‍රියයි"</item>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 03509f3..206e10c 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknutím spárujete nové zariadenie"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Predvoľbu sa nepodarilo aktualizovať"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Predvoľba"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Vybrané"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolie"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vľavo"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Zapnúť zvuk okolia"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Nástroje"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Živý prepis"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Nastavenia"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Poznámka"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Chcete odblokovať mikrofón zariadenia?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Chcete odblokovať kameru zariadenia?"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Pri zdieľaní aplikácie vidí aplikácia <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> všetko, čo sa v zdieľanej aplikácii zobrazuje alebo prehráva. Preto zvýšte pozornosť v prípade položiek, ako sú heslá, platobné údaje, správy, fotky a zvuk či video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Zdieľať obrazovku"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> túto možnosť zakázala"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Vyberte aplikáciu, do ktorej chcete zdieľať"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Chcete prenášať obrazovku?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Prenášať jednu aplikáciu"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Zapnuté – podľa tváre"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Hotovo"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Použiť"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Vypnúť upozornenia"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Tiché"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Predvolené"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automaticky"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Rozdelenie obrazovky, aktuálna aplikácia vpravo"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Rozdelenie obrazovky, aktuálna aplikácia vľavo"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Používať celú obrazovku"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Používať windowing na pracovnej ploche"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Prechod na aplikáciu vpravo alebo dole pri rozdelenej obrazovke"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Prechod na aplikáciu vľavo alebo hore pri rozdelenej obrazovke"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Počas rozdelenej obrazovky: nahradenie aplikácie inou"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Presunutím sem odstránite"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Minimálny počet vyžadovaných dlaždíc: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Upraviť"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Čas"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Zobrazovať hodiny, minúty a sekundy"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Chcete tento ovládač médií pre <xliff:g id="APP_NAME">%1$s</xliff:g> skryť?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Aktuálna relácia média sa nedá skryť."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skryť"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavenia"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> od interpreta <xliff:g id="ARTIST_NAME">%2$s</xliff:g> sa prehráva z aplikácie <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> z <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sk/tiles_states_strings.xml b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
index 3e61884..1b82be8 100644
--- a/packages/SystemUI/res/values-sk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sk/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Vypnuté"</item>
     <item msgid="4875147066469902392">"Zapnuté"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nedostupné"</item>
+    <item msgid="8589336868985358191">"Vypnutý"</item>
+    <item msgid="726072717827778234">"Zapnutý"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nie je k dispozícii"</item>
     <item msgid="5044688398303285224">"Vypnuté"</item>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 10a236c..1c1ff03 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliknite za seznanitev nove naprave"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Prednastavljenih vrednosti ni bilo mogoče posodobiti"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Prednastavljeno"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Izbrano"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Okolica"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Levo"</string>
@@ -582,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Pri deljenju aplikacije je aplikaciji <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> vidno vse, kar je prikazano ali predvajano v tej aplikaciji. Zato bodite previdni z gesli, podatki za plačilo, sporočili, fotografijami ter z zvokom in videom."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Deli zaslon"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> je onemogočila to možnost"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Izbira aplikacije za deljenje"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Želite predvajati vsebino zaslona?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Predvajanje ene aplikacije"</string>
@@ -794,7 +800,7 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Vklopljeno – na podlagi obraza"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Končano"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Uporabi"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Izklopi obvestila"</string>
+    <string name="inline_turn_off_notifications" msgid="2653064779176881329">"Izklopi"</string>
     <string name="notification_silence_title" msgid="8608090968400832335">"Tiho"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Privzeto"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Samodejno"</string>
@@ -905,8 +911,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Uporaba razdeljenega zaslona z aplikacijo na desni"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Uporaba razdeljenega zaslona z aplikacijo na levi"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Uporaba celozaslonskega načina"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Uporaba namiznega načina prikaza več oken hkrati"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Preklop na aplikacijo desno ali spodaj med uporabo razdeljenega zaslona"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Preklop na aplikacijo levo ali zgoraj med uporabo razdeljenega zaslona"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Pri razdeljenem zaslonu: medsebojna zamenjava aplikacij"</string>
@@ -980,6 +985,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Če želite odstraniti, povlecite sem"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Imeti morate vsaj toliko ploščic: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Uredi"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Ura"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Prikaži ure, minute in sekunde"</item>
@@ -1203,7 +1210,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Želite skriti ta nadzor predstavnosti za <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Trenutne seje predstavnosti ni mogoče skriti."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Skrij"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Nadaljuj"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavitve"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Skladba <xliff:g id="SONG_NAME">%1$s</xliff:g> izvajalca <xliff:g id="ARTIST_NAME">%2$s</xliff:g> se predvaja iz aplikacije <xliff:g id="APP_LABEL">%3$s</xliff:g>."</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> od <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sl/tiles_states_strings.xml b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
index 8146802..e0db4f1 100644
--- a/packages/SystemUI/res/values-sl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sl/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Izklopljeno"</item>
     <item msgid="4875147066469902392">"Vklopljeno"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Ni na voljo"</item>
+    <item msgid="8589336868985358191">"Izklopljeno"</item>
+    <item msgid="726072717827778234">"Vklopljeno"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Ni na voljo"</item>
     <item msgid="5044688398303285224">"Izklopljeno"</item>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index a32fc8a..c68e7a8 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Kliko për të çiftuar një pajisje të re"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Paravendosja nuk mund të përditësohej"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Paravendosja"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Zgjedhur"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Ambienti rrethues"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Majtas"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Djathtas"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Ambienti rrethues"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Ambienti rrethues majtas"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Ambienti rrethues djathtas"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Zgjero te kontrollet e veçuara majtas dhe djathtas"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Palos te kontrolli i unifikuar"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Vendos në heshtje ambientin rrethues"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Anulo vendosjen në heshtje të ambientit rrethues"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Veglat"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Titrat në çast"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Cilësimet"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Shënim"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Të zhbllokohet mikrofoni i pajisjes?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Të zhbllokohet kamera e pajisjes?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kur ti ndan një aplikacion, çdo gjë që shfaqet ose luhet në atë aplikacion është e dukshme për <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Prandaj, ki kujdes me gjërat si fjalëkalimet, detajet e pagesave, mesazhet, fotografitë, si dhe audion dhe videon."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ndaj ekranin"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> e ka çaktivizuar këtë opsion"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Zgjidh aplikacionin për të ndarë"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Të transmetohet ekrani yt?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Transmeto një aplikacion"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Aktiv - Në bazë të fytyrës"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"U krye"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Zbato"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Çaktivizo njoftimet"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Në heshtje"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"E parazgjedhur"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatike"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Përdor ekranin e ndarë me aplikacionin në të djathtë"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Përdor ekranin e ndarë me aplikacionin në të majtë"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Përdor ekranin e plotë"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Përdor ndërfaqen me dritare në desktop"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Kalo tek aplikacioni djathtas ose poshtë kur përdor ekranin e ndarë"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Kalo tek aplikacioni në të majtë ose sipër kur përdor ekranin e ndarë"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Gjatë ekranit të ndarë: zëvendëso një aplikacion me një tjetër"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Zvarrit këtu për ta hequr"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Të duhen të paktën <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> pllakëza"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Redakto"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Ora"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Shfaq orët, minutat dhe sekondat"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Shto te pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozicion i pavlefshëm."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Pozicioni <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Pllakëza është shtuar tashmë"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Pllakëza u shtua"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Pllakëza u hoq"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Redaktori i cilësimeve të shpejta."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Të fshihet kontrolluesi i medias për <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Seanca aktuale e medias nuk mund të fshihet."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fshih"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Vazhdo"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Cilësimet"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> nga <xliff:g id="ARTIST_NAME">%2$s</xliff:g> po luhet nga <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> nga <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sq/tiles_states_strings.xml b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
index 7ee5631..9bbb0f9 100644
--- a/packages/SystemUI/res/values-sq/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sq/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Joaktiv"</item>
     <item msgid="4875147066469902392">"Aktiv"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Nuk ofrohet"</item>
+    <item msgid="8589336868985358191">"Çaktivizuar"</item>
+    <item msgid="726072717827778234">"Aktivizuar"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Nuk ofrohet"</item>
     <item msgid="5044688398303285224">"Joaktiv"</item>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f99301c..46d8352 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Кликните да бисте упарили нов уређај"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ажурирање задатих подешавања није успело"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Унапред одређена подешавања"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Изабрано"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Окружење"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Лево"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Десно"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Окружење"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Лево окружење"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Десно окружење"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Прошири на контроле раздвојене на леву и десну страну"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Скупи у јединствену контролу"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Искључи звук окружења"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Укључи звук окружења"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Алатке"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Титл уживо"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Подешавања"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Белешка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Желите да одблокирате микрофон уређаја?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Желите да одблокирате камеру уређаја?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Када делите апликацију, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> види сав садржај који се приказује или пушта у њој. Зато пазите на лозинке, информације о плаћању, поруке, слике, аудио и видео садржај."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Дели екран"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> је онемогућила ову опцију"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Одаберите апликацију за дељење"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Желите да пребаците екран?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Пребаци једну апликацију"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Укључено – на основу лица"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Примени"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Искључи обавештења"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Нечујно"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Подразумевано"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Аутоматска"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Користи подељени екран са апликацијом с десне стране"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Користи подељени екран са апликацијом с леве стране"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Користи приказ преко целог екрана"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Користи прозорски приказ на рачунару"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Пређи у апликацију здесна или испод док је подељен екран"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Пређите у апликацију слева или изнад док користите подељени екран"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"У режиму подељеног екрана: замена једне апликације другом"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Превуците овде да бисте уклонили"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Минималан број плочица је <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Измени"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Време"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Прикажи сате, минуте и секунде"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додајте на <xliff:g id="POSITION">%1$d</xliff:g>. позицију"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позиција је неважећа."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"<xliff:g id="POSITION">%1$d</xliff:g>. позиција"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Плочица је већ додата"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Плочица је додата"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Плочица је уклоњена"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Уређивач за Брза подешавања."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Желите да сакријете ову контролу за медије за: <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Актуелна сесија медија не може да буде сакривена."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Сакриј"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> извођача <xliff:g id="ARTIST_NAME">%2$s</xliff:g> се пушта из апликације <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> од <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sr/tiles_states_strings.xml b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
index df9e574..14a8d94 100644
--- a/packages/SystemUI/res/values-sr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sr/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Искључено"</item>
     <item msgid="4875147066469902392">"Укључено"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Недоступно"</item>
+    <item msgid="8589336868985358191">"Искључено"</item>
+    <item msgid="726072717827778234">"Укључено"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Недоступно"</item>
     <item msgid="5044688398303285224">"Искључено"</item>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 0085ed2..ed0daf9 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Klicka för att parkoppla en ny enhet"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Det gick inte att uppdatera förinställningen"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Förinställning"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Markerad"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Omgivningsläge"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Vänster"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Höger"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Omgivningsljud"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Omgivningsljud till vänster"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Omgivningsljud till höger"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Utöka till kontroller till vänster och höger"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Komprimera till enhetlig kontroll"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Stäng av omgivningsljudet"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Slå på omgivningsljudet"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Verktyg"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Live Caption"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Inställningar"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Anteckning"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vill du återaktivera enhetens mikrofon?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vill du återaktivera enhetens kamera?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"När du delar en app är allt som visas eller spelas upp i appen synligt för <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Var försiktig med sådant som lösenord, betalningsuppgifter, meddelanden, foton, ljud och video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Dela skärmen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> har inaktiverat alternativet"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Välj en app att dela"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Vill du casta skärmen?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Casta en app"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"På – ansiktsbaserad"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Klart"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Tillämpa"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Inaktivera aviseringar"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Tyst"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standard"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Automatiskt"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Använd delad skärm med appen till höger"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Använd delad skärm med appen till vänster"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Använd helskärm"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Använd fönsterplacering på datorn"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Byt till appen till höger eller nedanför när du använder delad skärm"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Byt till appen till vänster eller ovanför när du använder delad skärm"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Med delad skärm: ersätt en app med en annan"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Ta bort genom att dra här"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Minst <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> rutor måste finnas kvar"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Redigera"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Tid"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Visa timmar, minuter och sekunder"</item>
@@ -1207,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Vill du dölja denna mediastyrning för <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Den aktuella mediesessionen kan inte döljas."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Dölj"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Inställningar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> med <xliff:g id="ARTIST_NAME">%2$s</xliff:g> spelas upp från <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> av <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sv/tiles_states_strings.xml b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
index 76822d0..f042697 100644
--- a/packages/SystemUI/res/values-sv/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sv/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Av"</item>
     <item msgid="4875147066469902392">"På"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Inte tillgängligt"</item>
+    <item msgid="8589336868985358191">"Av"</item>
+    <item msgid="726072717827778234">"På"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Inte tillgängligt"</item>
     <item msgid="5044688398303285224">"Av"</item>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index b7d208a..da390fb 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Bofya ili uunganishe kifaa kipya"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Imeshindwa kusasisha mipangilio iliyowekwa mapema"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Mipangilio iliyowekwa mapema"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Umechagua"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Mazingira"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kushoto"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kulia"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Mandhari"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Mandhari ya kushoto"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Mandhari ya kulia"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Panua iwe vidhibiti vilivyotenganishwa kushoto na kulia"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Kunja iwe kidhibiti cha pamoja"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Zima sauti ya mazingira"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Rejesha sauti ya mazingira"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Zana"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Manukuu Papo Hapo"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Mipangilio"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Dokezo"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Ungependa kuwacha kuzuia maikrofoni ya kifaa?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Ungependa kuacha kuzuia kamera ya kifaa?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Unaporuhusu ufikiaji wa programu, chochote kinachoonyeshwa au kuchezwa katika programu hiyo kitaonekana kwa <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Kwa hivyo kuwa mwangalifu na vitu kama vile manenosiri, maelezo ya malipo, ujumbe, picha, sauti na video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ruhusu ufikiaji wa skrini"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> imezima chaguo hili"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Chagua programu utakayoruhusu ifikiwe"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ungependa kutuma maudhui yaliyo katika skrini yako?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Tuma maudhui ya programu moja"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Imewashwa - Inayolenga nyuso"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Nimemaliza"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Tumia"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Zima arifa"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Kimya"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Chaguomsingi"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatiki"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Tumia hali ya kugawa skrini na programu ya sasa iwe upande wa kulia"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Tumia hali ya kugawa skrini na programu ya sasa iwe upande wa kushoto"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Tumia skrini nzima"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Tumia hali ya madirisha ya kompyuta ya mezani"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Badilisha ili uende kwenye programu iliyo kulia au chini unapotumia hali ya kugawa skrini"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Badilisha uende kwenye programu iliyo kushoto au juu unapotumia hali ya kugawa skrini"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ukigawanya skrini: badilisha kutoka programu moja hadi nyingine"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Buruta hapa ili uondoe"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Unahitaji angalau vigae <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Badilisha"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Wakati"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Onyesha saa, dakika na sekunde"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Ongeza kwenye nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Nafasi si sahihi."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Nafasi ya <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Tayari umeweka kigae"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kigae kimewekwa"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kigae kimeondolewa"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Kihariri cha Mipangilio ya haraka."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Ungependa kuficha kidhibiti hiki kwenye <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Kipindi cha sasa cha maudhui hakiwezi kufichwa."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ficha"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Mipangilio"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="SONG_NAME">%1$s</xliff:g> ulioimbwa na <xliff:g id="ARTIST_NAME">%2$s</xliff:g> unacheza katika <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> kati ya <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-sw/tiles_states_strings.xml b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
index a16a7b7..e08ed3a 100644
--- a/packages/SystemUI/res/values-sw/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-sw/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Kimezimwa"</item>
     <item msgid="4875147066469902392">"Kimewashwa"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Haipatikani"</item>
+    <item msgid="8589336868985358191">"Imezimwa"</item>
+    <item msgid="726072717827778234">"Imewashwa"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Hakipatikani"</item>
     <item msgid="5044688398303285224">"Imezimwa"</item>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index 473be6f..0c7aa40 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"புதிய சாதனத்தை இணைக்க கிளிக் செய்யலாம்"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"முன்னமைவைப் புதுப்பிக்க முடியவில்லை"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"முன்னமைவு"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"தேர்ந்தெடுக்கப்பட்டது"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"சுற்றுப்புறங்கள்"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"இடது"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"வலது"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"சுற்றுப்புறங்கள்"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"இடதுபுறச் சுற்றுப்புறங்கள்"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"வலதுபுறச் சுற்றுப்புறங்கள்"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"இடது மற்றும் வலதுபுறம் உள்ள கட்டுப்பாடுகளை விரிவாக்கும்"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"ஒருங்கிணைந்த கட்டுப்பாட்டுக்குச் சுருக்கும்"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"சுற்றுப்புறங்களின் ஒலியை அடக்கும்"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"சுற்றுப்புறங்களின் ஒலியை இயக்கும்"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"கருவிகள்"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"உடனடி வசனம்"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"அமைப்புகள்"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"குறிப்பு"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"சாதனத்தின் மைக்ரோஃபோனுக்கான தடுப்பை நீக்கவா?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"சாதனத்தின் கேமராவுக்கான தடுப்பை நீக்கவா?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"ஓர் ஆப்ஸைப் பகிரும்போது, அதில் காட்டப்படும்/பிளே செய்யப்படும் அனைத்தும் <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> இல் தெரியும். எனவே கடவுச்சொற்கள், பேமெண்ட் விவரங்கள், மெசேஜ்கள், படங்கள், ஆடியோ, வீடியோ போன்றவை குறித்துக் கவனத்துடன் இருங்கள்."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"திரையைப் பகிர்"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் இந்த விருப்பத்தை முடக்கியுள்ளது"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"பகிர ஆப்ஸைத் தேர்வுசெய்க"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"உங்கள் திரையை அலைபரப்ப வேண்டுமா?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ஓர் ஆப்ஸை அலைபரப்பு"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"ஆன் - முகம் அடிப்படையிலானது"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"முடிந்தது"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"பயன்படுத்து"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"அறிவிப்புகளை முடக்கு"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"சைலன்ட்"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"இயல்புநிலை"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"தானியங்கு"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ஆப்ஸ் வலதுபுறம் வரும்படி திரைப் பிரிப்பைப் பயன்படுத்துதல்"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ஆப்ஸ் இடதுபுறம் வரும்படி திரைப் பிரிப்பைப் பயன்படுத்துதல்"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"முழுத்திரையைப் பயன்படுத்து"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"டெஸ்க்டாப் சாளரமாக்குதலைப் பயன்படுத்துதல்"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது வலது/கீழ் உள்ள ஆப்ஸுக்கு மாறுதல்"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"திரைப் பிரிப்பைப் பயன்படுத்தும்போது இடது/மேலே உள்ள ஆப்ஸுக்கு மாறுதல்"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"திரைப் பிரிப்பின்போது: ஓர் ஆப்ஸுக்குப் பதிலாக மற்றொன்றை மாற்றுதல்"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"அகற்ற, இங்கே இழுக்கவும்"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"குறைந்தது <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> கட்டங்கள் தேவை"</string>
     <string name="qs_edit" msgid="5583565172803472437">"மாற்று"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"நேரம்"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"மணிநேரம், நிமிடங்கள், வினாடிகளைக் காட்டு"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g>ல் சேர்க்கும்"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"நிலை தவறானது."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"இடம்: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"கட்டம் ஏற்கெனவே சேர்க்கப்பட்டது"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"கட்டம் சேர்க்கப்பட்டது"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"கட்டம் அகற்றப்பட்டது"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"விரைவு அமைப்புகள் திருத்தி."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸுக்கான இந்த மீடியா கட்டுப்பாடுகளை மறைக்கவா?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"தற்போதைய மீடியா அமர்வை மறைக்க முடியாது."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"மறை"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"தொடர்க"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"அமைப்புகள்"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> இன் <xliff:g id="SONG_NAME">%1$s</xliff:g> பாடல் <xliff:g id="APP_LABEL">%3$s</xliff:g> ஆப்ஸில் பிளேயாகிறது"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ta/tiles_states_strings.xml b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
index dc1c514..8280da4 100644
--- a/packages/SystemUI/res/values-ta/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ta/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"முடக்கப்பட்டுள்ளது"</item>
     <item msgid="4875147066469902392">"இயக்கப்பட்டுள்ளது"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"கிடைக்கவில்லை"</item>
+    <item msgid="8589336868985358191">"ஆஃப்"</item>
+    <item msgid="726072717827778234">"ஆன்"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"கிடைக்கவில்லை"</item>
     <item msgid="5044688398303285224">"முடக்கப்பட்டுள்ளது"</item>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index a75dd22..972c64a 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"కొత్త పరికరాన్ని పెయిర్ చేయడానికి క్లిక్ చేయండి"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ప్రీసెట్‌ను అప్‌డేట్ చేయడం సాధ్యపడలేదు"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ప్రీసెట్"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"ఎంచుకోబడింది"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"పరిసరాలు"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ఎడమ వైపునకు"</string>
@@ -582,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"మీరు యాప్‌ను షేర్ చేసేటప్పుడు, సంబంధిత యాప్‌లో కనిపించేవి లేదా ప్లే అయ్యేవన్నీ <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>‌కు కనిపిస్తాయి. కాబట్టి పాస్‌వర్డ్‌లు, పేమెంట్ వివరాలు, మెసేజ్‌లు, ఫోటోలు, ఆడియో, ఇంకా వీడియో వంటి విషయాల్లో జాగ్రత్త వహించండి."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"స్క్రీన్‌ను షేర్ చేయండి"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ఈ ఆప్షన్‌ను డిజేబుల్ చేసింది"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"షేర్ చేయడానికి యాప్‌ను ఎంచుకోండి"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"మీ స్క్రీన్‌ను ప్రసారం చేయాలా?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ఒక యాప్‌ను ప్రసారం చేయండి"</string>
@@ -794,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"\'ముఖం ఆధారం\'ను - ఆన్ చేయండి"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"పూర్తయింది"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"అప్లయి చేయి"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"నోటిఫికేషన్‌లను ఆఫ్ చేయి"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"నిశ్శబ్దం"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ఆటోమేటిక్ సెట్టింగ్"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"ఆటోమేటిక్"</string>
@@ -905,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"కుడి వైపు ప్రస్తుత యాప్‌తో స్ప్లిట్ స్క్రీన్‌ను ఉపయోగించండి"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ఎడమ వైపు ప్రస్తుత యాప్‌తో స్ప్లిట్ స్క్రీన్‌ను ఉపయోగించండి"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ఫుల్ స్క్రీన్‌ను ఉపయోగించండి"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"డెస్క్‌టాప్ విండోయింగ్‌ను ఉపయోగించండి"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు కుడి లేదా కింద యాప్‌నకు మారండి"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"స్ప్లిట్ స్క్రీన్ ఉపయోగిస్తున్నప్పుడు ఎడమ లేదా పైన యాప్‌నకు మారండి"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"స్ప్లిట్ స్క్రీన్ సమయంలో: ఒక దాన్నుండి మరో దానికి యాప్ రీప్లేస్ చేయండి"</string>
@@ -980,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"తీసివేయడానికి ఇక్కడికి లాగండి"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"మీ వద్ద కనీసం <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> టైల్‌లు ఉండాలి"</string>
     <string name="qs_edit" msgid="5583565172803472437">"ఎడిట్ చేయండి"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"సమయం"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"గంటలు, నిమిషాలు మరియు సెకన్లను చూపు"</item>
@@ -993,8 +1001,7 @@
   </string-array>
     <string name="tuner_low_priority" msgid="8412666814123009820">"తక్కువ ప్రాధాన్యత నోటిఫికేషన్ చిహ్నాలను చూపించు"</string>
     <string name="other" msgid="429768510980739978">"ఇతరం"</string>
-    <!-- no translation found for accessibility_qs_edit_toggle_tile_size_action (1485194410119733586) -->
-    <skip />
+    <string name="accessibility_qs_edit_toggle_tile_size_action" msgid="1485194410119733586">"టైల్ సైజ్‌ను టోగుల్ చేయండి"</string>
     <string name="accessibility_qs_edit_remove_tile_action" msgid="775511891457193480">"టైల్‌ను తీసివేయండి"</string>
     <string name="accessibility_qs_edit_tile_add_action" msgid="8311378984458545661">"చివరి పొజిషన్‌కు టైల్‌ను జోడించండి"</string>
     <string name="accessibility_qs_edit_tile_start_move" msgid="2009373939914517817">"టైల్‌ను తరలించండి"</string>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> కోసం ఈ మీడియా కంట్రోల్‌ను దాచి ఉంచాలా?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"ప్రస్తుత మీడియా సెషన్‌ను దాచడం సాధ్యం కాదు."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"దాచండి"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్‌లు"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="ARTIST_NAME">%2$s</xliff:g> పాడిన <xliff:g id="SONG_NAME">%1$s</xliff:g> <xliff:g id="APP_LABEL">%3$s</xliff:g> నుండి ప్లే అవుతోంది"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="TOTAL_TIME">%2$s</xliff:g>లో <xliff:g id="ELAPSED_TIME">%1$s</xliff:g>"</string>
@@ -1548,10 +1554,8 @@
     <string name="overview_edu_toast_content" msgid="5797030644017804518">"ఇటీవలి యాప్‌లను చూడటానికి, టచ్‌ప్యాడ్‌లో మూడు వేళ్లతో పైకి స్వైప్ చేసి, హోల్డ్ చేయండి"</string>
     <string name="all_apps_edu_toast_content" msgid="8807496014667211562">"మీ యాప్‌లన్నింటినీ చూడటానికి, మీ కీబోర్డ్‌లో యాక్షన్ కీని నొక్కండి"</string>
     <string name="redacted_notification_single_line_title" msgid="212019960919261670">"దాచిపెట్టినది"</string>
-    <!-- no translation found for public_notification_single_line_text (3576190291791654933) -->
-    <skip />
-    <!-- no translation found for redacted_otp_notification_single_line_text (5179964116354454118) -->
-    <skip />
+    <string name="public_notification_single_line_text" msgid="3576190291791654933">"చూడటానికి అన్‌లాక్ చేయండి"</string>
+    <string name="redacted_otp_notification_single_line_text" msgid="5179964116354454118">"కోడ్‌ను చూడటానికి అన్‌లాక్ చేయండి"</string>
     <string name="contextual_education_dialog_title" msgid="4630392552837487324">"సందర్భోచిత విద్య"</string>
     <string name="back_edu_notification_title" msgid="5624780717751357278">"వెనుకకు వెళ్లడానికి మీ టచ్‌ప్యాడ్‌ను ఉపయోగించండి"</string>
     <string name="back_edu_notification_content" msgid="2497557451540954068">"మూడు వేళ్లతో ఎడమ / కుడి వైపునకు స్వైప్ చేయండి. మరిన్ని సంజ్ఞల గురించి తెలుసుకోవడానికి ట్యాప్ చేయండి."</string>
diff --git a/packages/SystemUI/res/values-te/tiles_states_strings.xml b/packages/SystemUI/res/values-te/tiles_states_strings.xml
index d118429..60a91f8 100644
--- a/packages/SystemUI/res/values-te/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-te/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"ఆఫ్‌లో ఉంది"</item>
     <item msgid="4875147066469902392">"ఆన్‌లో ఉంది"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"అందుబాటులో లేదు"</item>
+    <item msgid="8589336868985358191">"ఆఫ్‌లో ఉంది"</item>
+    <item msgid="726072717827778234">"ఆన్‌లో ఉంది"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"అందుబాటులో లేదు"</item>
     <item msgid="5044688398303285224">"ఆఫ్‌లో ఉంది"</item>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index e1413f2..a4f1447 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -419,6 +419,10 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"คลิกเพื่อจับคู่อุปกรณ์ใหม่"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"ไม่สามารถอัปเดตค่าที่กำหนดล่วงหน้า"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"ค่าที่กำหนดล่วงหน้า"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"เลือกแล้ว"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"เสียงแวดล้อม"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"ซ้าย"</string>
@@ -432,8 +436,7 @@
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"เปิดเสียงแวดล้อม"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"เครื่องมือ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"คำบรรยายสด"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"การตั้งค่า"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"จดบันทึก"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"เลิกบล็อกไมโครโฟนของอุปกรณ์ใช่ไหม"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"เลิกบล็อกกล้องของอุปกรณ์ใช่ไหม"</string>
@@ -583,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"เมื่อกำลังแชร์แอป <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> จะมองเห็นทุกสิ่งที่แสดงหรือเล่นอยู่ในแอปดังกล่าว ดังนั้นโปรดระวังสิ่งต่างๆ อย่างเช่นรหัสผ่าน รายละเอียดการชำระเงิน ข้อความ รูปภาพ รวมถึงเสียงและวิดีโอ"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"แชร์หน้าจอ"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ปิดใช้ตัวเลือกนี้"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"เลือกแอปที่จะแชร์"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"แคสต์หน้าจอของคุณไหม"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"แคสต์แอปเดียว"</string>
@@ -795,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"เปิด - ตามใบหน้า"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"เสร็จสิ้น"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"ใช้"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"ปิดการแจ้งเตือน"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"ปิดเสียง"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ค่าเริ่มต้น"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"อัตโนมัติ"</string>
@@ -906,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"ใช้โหมดแยกหน้าจอโดยให้แอปอยู่ด้านขวา"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"ใช้โหมดแยกหน้าจอโดยให้แอปอยู่ด้านซ้าย"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"ใช้โหมดเต็มหน้าจอ"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ใช้หน้าต่างเดสก์ท็อป"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"เปลี่ยนไปใช้แอปทางด้านขวาหรือด้านล่างขณะใช้โหมดแยกหน้าจอ"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"เปลี่ยนไปใช้แอปทางด้านซ้ายหรือด้านบนขณะใช้โหมดแยกหน้าจอ"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"ระหว่างใช้โหมดแยกหน้าจอ: เปลี่ยนแอปหนึ่งเป็นอีกแอปหนึ่ง"</string>
@@ -981,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ลากมาที่นี่เพื่อนำออก"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"คุณต้องมีการ์ดอย่างน้อย <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> รายการ"</string>
     <string name="qs_edit" msgid="5583565172803472437">"แก้ไข"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"เวลา"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"แสดงชั่วโมง นาที และวินาที"</item>
@@ -1204,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"ซ่อนตัวควบคุมสื่อนี้สำหรับ <xliff:g id="APP_NAME">%1$s</xliff:g> ไหม"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"ซ่อนเซสชันสื่อในปัจจุบันไม่ได้"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"ซ่อน"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"เล่นต่อ"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"การตั้งค่า"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"กำลังเปิดเพลง <xliff:g id="SONG_NAME">%1$s</xliff:g> ของ <xliff:g id="ARTIST_NAME">%2$s</xliff:g> จาก <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> จาก <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-th/tiles_states_strings.xml b/packages/SystemUI/res/values-th/tiles_states_strings.xml
index 9fba3bd..b969056 100644
--- a/packages/SystemUI/res/values-th/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-th/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"ปิด"</item>
     <item msgid="4875147066469902392">"เปิด"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"ไม่พร้อมใช้งาน"</item>
     <item msgid="5044688398303285224">"ปิด"</item>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index aff1621..1f25175 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -419,16 +419,17 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"I-click para magpares ng bagong device"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hindi ma-update ang preset"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Preset"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Napili"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Paligid"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kaliwa"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kanan"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Paligid"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Kaliwang bahagi ng paligid"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Kanang bahagi ng paligid"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"I-expand sa kaliwa at kanang magkahiwalay na mga kontrol"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"I-collapse sa pinag-isang kontrol"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"I-mute ang paligid"</string>
@@ -585,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Kapag nagshe-share ka ng app, makikita ng <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> ang kahit anong ipinapakita o pine-play sa app na iyon. Kaya mag-ingat sa mga bagay-bagay tulad ng mga password, detalye ng pagbabayad, mensahe, larawan, at audio at video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ibahagi ang screen"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Na-disable ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang opsyong ito"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Pumili ng app na ishe-share"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"I-cast ang iyong screen?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Mag-cast ng isang app"</string>
@@ -797,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Naka-on - Batay sa mukha"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Tapos na"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Ilapat"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"I-off ang mga notification"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Naka-silent"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Default"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Awtomatiko"</string>
@@ -908,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Gumamit ng split screen nang nasa kanan ang app"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Gumamit ng split screen nang nasa kaliwa ang app"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Gamitin ang full screen"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Gamitin ang desktop windowing"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Lumipat sa app sa kanan o ibaba habang ginagamit ang split screen"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Lumipat sa app sa kaliwa o itaas habang ginagamit ang split screen"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Habang nasa split screen: magpalit-palit ng app"</string>
@@ -983,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"I-drag dito upang alisin"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Kailangan mo ng kahit <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> (na) tile"</string>
     <string name="qs_edit" msgid="5583565172803472437">"I-edit"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Oras"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Ipakita ang oras, minuto at segundo"</item>
@@ -1206,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"itago ang kontrol sa media na ito para sa <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Hindi maitatago ang kasalukuyang session ng media."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Itago"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Ituloy"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Mga Setting"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Nagpe-play ang <xliff:g id="SONG_NAME">%1$s</xliff:g> ni/ng <xliff:g id="ARTIST_NAME">%2$s</xliff:g> mula sa <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> sa <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-tl/tiles_states_strings.xml b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
index 03cca6d..84213d5 100644
--- a/packages/SystemUI/res/values-tl/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tl/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Naka-off"</item>
     <item msgid="4875147066469902392">"Naka-on"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Hindi available"</item>
+    <item msgid="8589336868985358191">"Naka-off"</item>
+    <item msgid="726072717827778234">"Naka-on"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Hindi available"</item>
     <item msgid="5044688398303285224">"Naka-off"</item>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index eb5b951..4748cc4d 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yeni cihaz eşlemek için tıklayın"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Hazır ayar güncellenemedi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Hazır Ayar"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Seçili"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Çevredeki sesler"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Sol"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Sağ"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Çevredeki sesler"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Sol çevredeki sesler"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Sağ çevredeki sesler"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Sol ve sağ kontrolleri ayırarak genişlet"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Kontrolleri birleştirerek daralt"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Çevredeki sesleri kapat"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Çevredeki sesleri aç"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Araçlar"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Canlı Altyazı"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Ayarlar"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Not"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Cihaz mikrofonunun engellemesi kaldırılsın mı?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Cihaz kamerasının engellemesi kaldırılsın mı?"</string>
@@ -517,7 +517,7 @@
     <string name="communal_tutorial_indicator_text" msgid="4503010353591430123">"Ortak eğitimi başlatmak için sola kaydırın"</string>
     <string name="cta_tile_button_to_open_widget_editor" msgid="3871562362382963878">"Özelleştir"</string>
     <string name="cta_tile_button_to_dismiss" msgid="3377597875997861754">"Kapat"</string>
-    <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Burada widget\'larınızı ekleyin, kaldırın ve düzenleyin"</string>
+    <string name="cta_label_to_edit_widget" msgid="6496885074209203756">"Widget ekleyin, kaldırın ve düzenleyin"</string>
     <string name="cta_label_to_open_widget_picker" msgid="3874946756976360699">"Daha fazla widget ekle"</string>
     <string name="popup_on_dismiss_cta_tile_text" msgid="8292501780996070019">"Widget\'ları özelleştirmek için uzun basın"</string>
     <string name="button_to_configure_widgets_text" msgid="4191862850185256901">"Widget\'ları özelleştir"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>, bir uygulamayı paylaştığınızda o uygulamada gösterilen veya oynatılan her şeyi görebilir. Bu nedenle şifre, ödeme ayrıntıları, mesaj, fotoğraf, ses ve video gibi öğeler konusunda dikkatli olun."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ekranı paylaş"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu seçeneği devre dışı bıraktı"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Paylaşılacak uygulamayı seçin"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ekranınız yayınlansın mı?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"1 uygulamayı yayınla"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Açık - Yüze göre"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Bitti"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Uygula"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Bildirimleri kapat"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Sessiz"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Varsayılan"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Otomatik"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Sağdaki uygulamayla birlikte bölünmüş ekranı kullan"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Soldaki uygulamayla birlikte bölünmüş ekranı kullan"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Tam ekran kullanın"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Masaüstü pencere sistemini kullan"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Bölünmüş ekran kullanırken sağdaki veya alttaki uygulamaya geçiş yap"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Bölünmüş ekran kullanırken soldaki veya üstteki uygulamaya geçiş yapın"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Bölünmüş ekran etkinken: Bir uygulamayı başkasıyla değiştir"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Kaldırmak için buraya sürükleyin"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"En az <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> kutu gerekiyor"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Düzenle"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Saat"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Saati, dakikayı ve saniyeyi göster"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"<xliff:g id="POSITION">%1$d</xliff:g> konumuna ekle"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Konum geçersiz."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Konum: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Hızlı ayar kutusu daha önce eklendi"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Kutu eklendi"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Kutu kaldırıldı"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Hızlı ayar düzenleyicisi."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> için bu medya kontrolü gizlensin mi?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Geçerli medya oturumu gizlenemez."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Gizle"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Devam ettir"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> uygulamasından <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, <xliff:g id="SONG_NAME">%1$s</xliff:g> şarkısı çalıyor"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-tr/tiles_states_strings.xml b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
index 7c17ace..3efa8ea 100644
--- a/packages/SystemUI/res/values-tr/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-tr/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Kapalı"</item>
     <item msgid="4875147066469902392">"Açık"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Kullanılamıyor"</item>
+    <item msgid="8589336868985358191">"Kapalı"</item>
+    <item msgid="726072717827778234">"Açık"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Kullanılamıyor"</item>
     <item msgid="5044688398303285224">"Kapalı"</item>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 1f5d0aa..d89467c 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Натисніть, щоб підключити новий пристрій"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Не вдалось оновити набір налаштувань"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Набір налаштувань"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Вибрано"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Звуки оточення"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Ліворуч"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Праворуч"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Звуки оточення"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Звуки оточення ліворуч"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Звуки оточення праворуч"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Розгорнути в окремі елементи керування ліворуч і праворуч"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Згорнути в єдиний елемент керування"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Вимкнути звуки оточення"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Увімкнути звуки оточення"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Інструменти"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Живі субтитри"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Налаштування"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Нотатка"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Надати доступ до мікрофона?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Надати доступ до камери пристрою?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Коли ви показуєте вікно додатка, увесь контент, що відображається або відтворюється в ньому, стає видимим у додатку <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Тому будьте обережні з паролями, повідомленнями, фотографіями, аудіо, відео, платіжною інформацією тощо."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Показати екран"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> вимкнув цю опцію"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Виберіть додаток для показу"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Транслювати екран?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Транслювати один додаток"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Увімкнути (за обличчям)"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Готово"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Застосувати"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Вимкнути сповіщення"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Без звуку"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"За умовчанням"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Автоматично"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Розділити екран і показувати додаток праворуч"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Розділити екран і показувати додаток ліворуч"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Використовувати повноекранний режим"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Використовувати режим вікон для комп’ютера"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Перейти до додатка праворуч або внизу на розділеному екрані"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Під час розділення екрана перемикатися на додаток ліворуч або вгорі"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Під час розділення екрана: замінити додаток іншим"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Перетягніть сюди, щоб видалити"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Мінімальна кількість фрагментів: <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Редагувати"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Час"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Показувати години, хвилини та секунди"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Додати на позицію <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Позиція недійсна."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Позиція <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Плитку вже додано"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Опцію додано"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Опцію вилучено"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Редактор швидких налаштувань."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Приховати цей елемент керування для <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Поточний медіасеанс не можна приховати."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Приховати"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Відновити"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Налаштування"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Пісня \"<xliff:g id="SONG_NAME">%1$s</xliff:g>\", яку виконує <xliff:g id="ARTIST_NAME">%2$s</xliff:g>, грає в додатку <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> з <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-uk/tiles_states_strings.xml b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
index 8b50c085..a31e858 100644
--- a/packages/SystemUI/res/values-uk/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uk/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"Вимкнено"</item>
     <item msgid="4875147066469902392">"Увімкнено"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Недоступно"</item>
     <item msgid="5044688398303285224">"Вимкнено"</item>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index bcaa912..51950e0 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"نئے آلے کا جوڑا بنانے کے لیے کلک کریں"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"پہلے سے ترتیب شدہ کو اپ ڈیٹ نہیں کیا جا سکا"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"پہلے سے ترتیب شدہ"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"منتخب کردہ"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"اطراف"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"دائیں"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"بائیں"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"سراؤنڈنگ ساؤنڈ"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"بایاں سراؤنڈنگ ساؤنڈ"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"دایاں سراؤنڈنگ ساؤنڈ"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"بائیں اور دائیں علیحدہ کردہ کنٹرولز کو پھیلائیں"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"یونیفائیڈ کنٹرول کیلئے سکیڑیں"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"اطراف کو خاموش کریں"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"اطراف کی آواز چالو کریں"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"ٹولز"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"لائیو کیپشن"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"ترتیبات"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"نوٹ"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"آلے کا مائیکروفون غیر مسدود کریں؟"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"آلے کا کیمرا غیر مسدود کریں؟"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"آپ کے کسی ایپ کا اشتراک کرنے پر اس ایپ میں دکھائی گئی یا چلائی گئی ہر چیز <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> کیلئے مرئی ہو جاتی ہے۔ لہذا، پاس ورڈز، ادائیگی کی تفصیلات، پیغامات، تصاویر، ساتھ ہی آڈیو اور ویڈیو جیسی چیزوں کے سلسلے میں محتاط رہیں۔"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"اسکرین کا اشتراک کریں"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> نے اس اختیار کو غیر فعال کر دیا ہے"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"اشتراک کرنے کیلئے ایپ منتخب کریں"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"اپنی اسکرین کاسٹ کریں؟"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"ایک ایپ کاسٹ کریں"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"آن - چہرے پر مبنی"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"ہو گیا"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"لاگو کریں"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"اطلاعات کو آف کریں"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"خاموش"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"ڈیفالٹ"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"خودکار"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"بائیں جانب ایپ کے ساتھ اسپلٹ اسکرین کا استعمال کریں"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"دائیں جانب ایپ کے ساتھ اسپلٹ اسکرین کا استعمال کریں"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"فُل اسکرین استعمال کریں"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"ڈیسک ٹاپ ونڈو موڈ استعمال کریں"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"اسپلٹ اسکرین کا استعمال کرتے ہوئے دائیں یا نیچے ایپ پر سوئچ کریں"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"اسپلٹ اسکرین کا استعمال کرتے ہوئے بائیں یا اوپر ایپ پر سوئچ کریں"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"اسپلٹ اسکرین کے دوران: ایک ایپ کو دوسرے سے تبدیل کریں"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"ہٹانے کیلئے یہاں گھسیٹیں؟"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"آپ کو کم از کم <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ٹائلز کی ضرورت ہے"</string>
     <string name="qs_edit" msgid="5583565172803472437">"ترمیم کریں"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"وقت"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"گھنٹے، منٹ اور سیکنڈ دکھائیں"</item>
@@ -1207,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"‫<xliff:g id="APP_NAME">%1$s</xliff:g> کے لیے اس میڈیا کنٹرول کو چھپائیں؟"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"میڈیا کے موجودہ سیشن کو چھپایا نہیں جا سکتا۔"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"چھپائیں"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> سے <xliff:g id="ARTIST_NAME">%2$s</xliff:g> کا <xliff:g id="SONG_NAME">%1$s</xliff:g> چل رہا ہے"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> از <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ur/tiles_states_strings.xml b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
index fea0533..88698b5 100644
--- a/packages/SystemUI/res/values-ur/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-ur/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"آف ہے"</item>
     <item msgid="4875147066469902392">"آن ہے"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"دستیاب نہیں ہے"</item>
+    <item msgid="8589336868985358191">"آف"</item>
+    <item msgid="726072717827778234">"آن"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"دستیاب نہیں ہے"</item>
     <item msgid="5044688398303285224">"آف ہے"</item>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index bf070b5..8d750dd 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Yangi qurilmani ulash uchun bosing"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Andoza yangilanmadi"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Andoza"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Tanlangan"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Atrof-muhit"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Chap"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Oʻng"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Atrof tovushlari"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Chap tomondan tovushlar"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Oʻng tomondan tovushlar"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Chap va oʻngga ajratilgan boshqaruv elementlariga yoyish"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Yagona boshqaruvga yigʻish"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Atrof-muhitni ovozsiz qilish"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Atrof-muhitni sukutdan chiqarish"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Vositalar"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Jonli izoh"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Sozlamalar"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Qayd"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Qurilma mikrofoni blokdan chiqarilsinmi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Qurilma kamerasi blokdan chiqarilsinmi?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Ilovani namoyish qilayotganingizda oʻsha ilova ichida koʻrsatilayotgan yoki ijro qilinayotganlar <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>ga koʻrinadi. Shu sababli parollar, toʻlov tafsilotlari, xabarlar, suratlar, audio va video chiqmasligi uchun ehtiyot boʻling."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Ekranni namoyish qilish"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> bu sozlamani faolsizlantirgan"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Ulashiladigan ilovani tanlash"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Ekraningiz uzatilsinmi?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Bitta ilovani uzatish"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Yoqish - Yuz asosida"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Tayyor"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Tatbiq etish"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Bildirishnoma kelmasin"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Sokin"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Standart"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Avtomatik"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Ekranni ajratib, joriy ilovani oʻngga joylash"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Ekranni ajratib, joriy ilovani chapga joylash"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Butun ekrandan foydalanish"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Oynalarni desktop rejimda chiqarish"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Ajratilgan ekranda oʻngdagi yoki pastdagi ilovaga almashish"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Ajratilgan ekranda chapdagi yoki yuqoridagi ilovaga almashish"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ajratilgan rejimda ilovalarni oʻzaro almashtirish"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"O‘chirish uchun bu yerga torting"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Kamida <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ta katakcha lozim"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Tahrirlash"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Vaqt"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Soat, daqiqa va soniyalar ko‘rsatilsin"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Bu joyga kiritish: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Pozitsiya yaroqsiz."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Joylashuv: <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Katakcha allaqachon kiritilgan"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Katakcha kiritildi"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Katakcha olib tashlandi"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Tezkor sozlamalar muharriri"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"<xliff:g id="APP_NAME">%1$s</xliff:g> uchun media boshqaruvi berkitilsinmi?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Joriy media seansi berkitilmadi."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Berkitish"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Sozlamalar"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"<xliff:g id="APP_LABEL">%3$s</xliff:g> ilovasida ijro etilmoqda: <xliff:g id="SONG_NAME">%1$s</xliff:g> – <xliff:g id="ARTIST_NAME">%2$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-uz/tiles_states_strings.xml b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
index 9b8ca80..7afb9bd 100644
--- a/packages/SystemUI/res/values-uz/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-uz/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Oʻchiq"</item>
     <item msgid="4875147066469902392">"Yoniq"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Mavjud emas"</item>
+    <item msgid="8589336868985358191">"Yoqilmagan"</item>
+    <item msgid="726072717827778234">"Yoniq"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Ishlamaydi"</item>
     <item msgid="5044688398303285224">"Oʻchiq"</item>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 9e11f38..300dea9 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Nhấp để ghép nối thiết bị mới"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Không cập nhật được giá trị đặt trước"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Chế độ đặt sẵn"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Đã chọn"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Âm lượng xung quanh"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Trái"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Phải"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Môi trường xung quanh"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Môi trường xung quanh bên trái"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Môi trường xung quanh bên phải"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Mở rộng thành các nút điều khiển tách biệt bên trái và bên phải"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Thu gọn thành nút điều khiển hợp nhất"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Tắt tiếng xung quanh"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Bật tiếng xung quanh"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Công cụ"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Phụ đề trực tiếp"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Cài đặt"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Ghi chú"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Bỏ chặn micrô của thiết bị?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Bỏ chặn camera của thiết bị?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Khi bạn chia sẻ một ứng dụng, <xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> sẽ thấy được mọi nội dung hiển thị hoặc phát trong ứng dụng đó. Vì vậy, hãy thận trọng để không làm lộ thông tin như mật khẩu, thông tin thanh toán, tin nhắn, ảnh, âm thanh và video."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Chia sẻ màn hình"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> đã tắt lựa chọn này"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Chọn ứng dụng để chia sẻ"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Truyền màn hình?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Truyền một ứng dụng"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Đang bật – Dựa trên khuôn mặt"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Xong"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Áp dụng"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Tắt thông báo"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Im lặng"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Mặc định"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Tự động"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Dùng tính năng chia đôi màn hình với ứng dụng ở bên phải"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Dùng tính năng chia đôi màn hình với ứng dụng ở bên trái"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Dùng chế độ toàn màn hình"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Sử dụng chế độ cửa sổ trên máy tính"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Chuyển sang ứng dụng bên phải hoặc ở dưới khi đang chia đôi màn hình"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Chuyển sang ứng dụng bên trái hoặc ở trên khi đang chia đôi màn hình"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Trong chế độ chia đôi màn hình: thay một ứng dụng bằng ứng dụng khác"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Kéo vào đây để xóa"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Bạn cần ít nhất <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> ô"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Chỉnh sửa"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Thời gian"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Hiển thị giờ, phút và giây"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Thêm vào vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Vị trí không hợp lệ."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Vị trí <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Đã thêm ô"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Đã thêm thẻ thông tin"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Đã xóa thẻ thông tin"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Trình chỉnh sửa cài đặt nhanh."</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Ẩn tính năng điều khiển này cho <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Không thể ẩn phiên phát nội dung nghe nhìn hiện tại."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Ẩn"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Cài đặt"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"Đang phát <xliff:g id="SONG_NAME">%1$s</xliff:g> của <xliff:g id="ARTIST_NAME">%2$s</xliff:g> trên <xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-vi/tiles_states_strings.xml b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
index afbf477..78e39a7 100644
--- a/packages/SystemUI/res/values-vi/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-vi/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Đang tắt"</item>
     <item msgid="4875147066469902392">"Đang bật"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Không có"</item>
+    <item msgid="8589336868985358191">"Đang tắt"</item>
+    <item msgid="726072717827778234">"Đang bật"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Không hoạt động"</item>
     <item msgid="5044688398303285224">"Đang tắt"</item>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index cbc4e51..dacca69 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"点击即可与新设备配对"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"无法更新预设"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"预设"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已选择"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"周围声音"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左侧"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右侧"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"环境音"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"左侧环境音"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"右侧环境音"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"展开为左侧和右侧的单独控件"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收起为统一控件"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"将周围声音静音"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"取消周围声音静音"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"实时字幕"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"设置"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"记事"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解锁设备麦克风吗?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解锁设备摄像头吗?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"当您共享一个应用时,该应用中显示或播放的所有内容均对“<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>”可见。因此,请务必小心操作,谨防泄露密码、付款信息、消息、照片、音频、视频等。"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"共享屏幕"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”已停用此选项"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"选择要分享的应用"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"投放您的屏幕?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"投放单个应用"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"已开启 - 基于人脸"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"完成"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"应用"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"关闭通知"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"静音"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"默认"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自动"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"使用分屏模式,并将应用置于右侧"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"使用分屏模式,并将应用置于左侧"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"使用全屏"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"使用桌面设备窗口化模式"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分屏模式时,切换到右侧或下方的应用"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分屏模式时,切换到左侧或上方的应用"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"在分屏期间:将一个应用替换为另一个应用"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"拖动到此处即可移除"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"您至少需要 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 个卡片"</string>
     <string name="qs_edit" msgid="5583565172803472437">"编辑"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"时间"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"显示小时、分钟和秒"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"添加到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置无效。"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"功能块已添加"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已添加功能块"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除功能块"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快捷设置编辑器。"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"要针对“<xliff:g id="APP_NAME">%1$s</xliff:g>”隐藏此媒体控件吗?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"无法隐藏当前的媒体会话。"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隐藏"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"继续播放"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"设置"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在通过<xliff:g id="APP_LABEL">%3$s</xliff:g>播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> / <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
index a3922e5..5980c31 100644
--- a/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/tiles_states_strings.xml
@@ -56,6 +56,9 @@
     <item msgid="5376619709702103243">"已关闭"</item>
     <item msgid="4875147066469902392">"已开启"</item>
   </string-array>
+    <!-- no translation found for tile_states_modes_dnd:0 (6509540227356524582) -->
+    <!-- no translation found for tile_states_modes_dnd:1 (8589336868985358191) -->
+    <!-- no translation found for tile_states_modes_dnd:2 (726072717827778234) -->
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"不可用"</item>
     <item msgid="5044688398303285224">"已关闭"</item>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 0e1de31..afc33d9 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"㩒一下就可以配對新裝置"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"揀咗"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"環境聲音"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"環境"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"左邊環境"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"右邊環境"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"打開就可以分開左右控制"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收埋就可以統一控制"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"環境聲音靜音"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"取消環境聲音靜音"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"設定"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"要解除封鎖裝置相機嗎?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"當你分享應用程式時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可看到該應用程式中顯示或播放的任何內容。因此,請謹慎處理密碼、付款資料、訊息、相片、音訊和影片等。"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"分享螢幕畫面"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用此選項"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"選擇要分享的應用程式"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"要投放螢幕嗎?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"投放一個應用程式"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"已開啟 - 根據面孔偵測"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"完成"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"套用"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"關閉通知"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"靜音"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"預設"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"使用分割螢幕,並在右側顯示應用程式"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"使用分割螢幕,並在左側顯示應用程式"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"使用全螢幕"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"使用桌面電腦視窗模式"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割螢幕時,切換至右邊或下方的應用程式"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割螢幕時,切換至左邊或上方的應用程式"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割螢幕期間:更換應用程式"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"拖曳這裡即可移除"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"你需要有至少 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個資訊方塊"</string>
     <string name="qs_edit" msgid="5583565172803472437">"編輯"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"時間"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"顯示小時、分鐘和秒"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"加去位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置冇效。"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"已新增資訊方塊"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"加咗圖塊"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"移除咗圖塊"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯工具。"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"要隱藏此「<xliff:g id="APP_NAME">%1$s</xliff:g>」媒體控制嗎?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"正在透過 <xliff:g id="APP_LABEL">%3$s</xliff:g> 播放 <xliff:g id="ARTIST_NAME">%2$s</xliff:g> 的《<xliff:g id="SONG_NAME">%1$s</xliff:g>》"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>/<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
index 26bec2c..2dcb0cd 100644
--- a/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"已關閉"</item>
     <item msgid="4875147066469902392">"已開啟"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"無法使用"</item>
+    <item msgid="8589336868985358191">"已關閉"</item>
+    <item msgid="726072717827778234">"已開啟"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"無法使用"</item>
     <item msgid="5044688398303285224">"已關閉"</item>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index a34333b..3ea590a1 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -419,24 +419,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"按一下即可配對新裝置"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"無法更新預設設定"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"預設"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"已選取"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"環境"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"左"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"右"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"環境"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"左側環境"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"右側環境"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"展開為左右獨立控制選項"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"收合為統合控制選項"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"將環境靜音"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"取消環境靜音"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"工具"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"即時字幕"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"設定"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"筆記"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"要解除封鎖裝置麥克風嗎?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"解除封鎖裝置相機?"</string>
@@ -586,6 +586,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"當你分享應用程式畫面時,「<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>」可存取該應用程式顯示或播放的所有內容。因此,請謹慎處理密碼、付款資料、訊息、相片和影音內容等資訊。"</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"分享畫面"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」已停用此選項"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"選擇要分享的應用程式"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"要投放畫面嗎?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"投放一個應用程式"</string>
@@ -798,7 +800,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"已開啟 - 依臉部方向旋轉"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"完成"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"套用"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"關閉通知"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"靜音"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"預設"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"自動"</string>
@@ -909,8 +912,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"使用分割畫面,並在右側顯示應用程式"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"使用分割畫面,並在左側顯示應用程式"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"使用全螢幕模式"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"使用電腦視窗化模式"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"使用分割畫面時,切換到右邊或上方的應用程式"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"使用分割畫面時,切換到左邊或上方的應用程式"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"使用分割畫面期間:更換應用程式"</string>
@@ -984,6 +986,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"拖曳到這裡即可移除"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"你至少必須要有 <xliff:g id="MIN_NUM_TILES">%1$d</xliff:g> 個設定方塊"</string>
     <string name="qs_edit" msgid="5583565172803472437">"編輯"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"時間"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"顯示小時、分鐘和秒"</item>
@@ -1006,8 +1010,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"新增到位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"位置無效。"</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"位置 <xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"已新增過該設定方塊"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"已新增設定方塊"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"已移除設定方塊"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"快速設定編輯器。"</string>
@@ -1208,7 +1211,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"要隱藏「<xliff:g id="APP_NAME">%1$s</xliff:g>」的媒體控制選項嗎?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"無法隱藏目前的媒體工作階段。"</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"隱藏"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"系統正透過「<xliff:g id="APP_LABEL">%3$s</xliff:g>」播放<xliff:g id="ARTIST_NAME">%2$s</xliff:g>的〈<xliff:g id="SONG_NAME">%1$s</xliff:g>〉"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g>,共 <xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
index 6e272f2..33313ac 100644
--- a/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"已關閉"</item>
     <item msgid="4875147066469902392">"已開啟"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"無法使用"</item>
+    <item msgid="8589336868985358191">"已關閉"</item>
+    <item msgid="726072717827778234">"已開啟"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"無法使用"</item>
     <item msgid="5044688398303285224">"已關閉"</item>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 7d43adc..767adbb 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -421,24 +421,24 @@
     <string name="accessibility_hearing_device_pair_new_device" msgid="8440082580186130090">"Chofoza ukuze ubhangqe idivayisi entsha"</string>
     <string name="hearing_devices_presets_error" msgid="350363093458408536">"Ayikwazanga ukubuyekeza ukusetha ngaphambilini"</string>
     <string name="hearing_devices_preset_label" msgid="7878267405046232358">"Ukusetha ngaphambilini"</string>
+    <!-- no translation found for hearing_devices_input_routing_label (730396728151232306) -->
+    <skip />
+    <!-- no translation found for hearing_device_input_routing_options:0 (4582190415045337003) -->
+    <!-- no translation found for hearing_device_input_routing_options:1 (8501466270452446450) -->
     <string name="hearing_devices_spinner_item_selected" msgid="3137083889662762383">"Okukhethiwe"</string>
     <string name="hearing_devices_ambient_label" msgid="629440938614895797">"Izindawo ezizungezile"</string>
     <string name="hearing_devices_ambient_control_left" msgid="3586965448230412600">"Kwesokunxele"</string>
     <string name="hearing_devices_ambient_control_right" msgid="6192137602448918383">"Kwesokudla"</string>
-    <!-- no translation found for hearing_devices_ambient_control_description (3663947879732939509) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_left_description (4440988622896213511) -->
-    <skip />
-    <!-- no translation found for hearing_devices_ambient_control_right_description (2230461103493378003) -->
-    <skip />
+    <string name="hearing_devices_ambient_control_description" msgid="3663947879732939509">"Izindawo ezizungezile"</string>
+    <string name="hearing_devices_ambient_control_left_description" msgid="4440988622896213511">"Indawo ezungezile engakwesokunxele"</string>
+    <string name="hearing_devices_ambient_control_right_description" msgid="2230461103493378003">"Indawo ezungezile engakwesokudla"</string>
     <string name="hearing_devices_ambient_expand_controls" msgid="2131816068187709200">"Nwebela ezilawulini ezihlukanisiwe zakwesokunxele nakwesokudla"</string>
     <string name="hearing_devices_ambient_collapse_controls" msgid="2261097656446201581">"Goqa ezilawulini ezihlanganisiwe"</string>
     <string name="hearing_devices_ambient_mute" msgid="1836882837647429416">"Thulisa izindawo ezizungezile"</string>
     <string name="hearing_devices_ambient_unmute" msgid="2187938085943876814">"Susa ukuthula ezindaweni ezizungezile"</string>
     <string name="hearing_devices_tools_label" msgid="1929081464316074476">"Amathuluzi"</string>
     <string name="quick_settings_hearing_devices_live_caption_title" msgid="1054814050932225451">"Okushuthwe Bukhoma"</string>
-    <!-- no translation found for hearing_devices_settings_button (999474385481812222) -->
-    <skip />
+    <string name="hearing_devices_settings_button" msgid="999474385481812222">"Amasethingi"</string>
     <string name="quick_settings_notes_label" msgid="1028004078001002623">"Inothi"</string>
     <string name="sensor_privacy_start_use_mic_dialog_title" msgid="563796653825944944">"Vulela imakrofoni yedivayisi?"</string>
     <string name="sensor_privacy_start_use_camera_dialog_title" msgid="8807639852654305227">"Vulela ikhamera yedivayisi?"</string>
@@ -588,6 +588,8 @@
     <string name="media_projection_entry_app_permission_dialog_warning_single_app" msgid="7094417930857938876">"Uma wabelana nge-app, noma yini eboniswayo noma edlalwayo kuleyo app ibonakala ku-<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>. Ngakho-ke qaphela ngezinto ezifana namaphasiwedi, imininingwane yenkokhelo, imilayezo, izithombe, nomsindo nevidiyo."</string>
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen" msgid="1850848182344377579">"Yabelana ngesikrini"</string>
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled" msgid="8999903044874669995">"<xliff:g id="APP_NAME">%1$s</xliff:g> ivale le nketho"</string>
+    <!-- no translation found for media_projection_entry_app_permission_dialog_single_app_not_supported (4860247304058870233) -->
+    <skip />
     <string name="media_projection_entry_share_app_selector_title" msgid="1419515119767501822">"Khetha i-app yokwabelana"</string>
     <string name="media_projection_entry_cast_permission_dialog_title" msgid="752756942658159416">"Sakaza isikrini sakho?"</string>
     <string name="media_projection_entry_cast_permission_dialog_option_text_single_app" msgid="6073353940838561981">"Sakaza i-app eyodwa"</string>
@@ -800,7 +802,8 @@
     <string name="rotation_lock_camera_rotation_on" msgid="789434807790534274">"Vuliwe - Kususelwe kubuso"</string>
     <string name="inline_done_button" msgid="6043094985588909584">"Kwenziwe"</string>
     <string name="inline_ok_button" msgid="603075490581280343">"Faka"</string>
-    <string name="inline_turn_off_notifications" msgid="8543989584403106071">"Vala izaziso"</string>
+    <!-- no translation found for inline_turn_off_notifications (2653064779176881329) -->
+    <skip />
     <string name="notification_silence_title" msgid="8608090968400832335">"Kuthulile"</string>
     <string name="notification_alert_title" msgid="3656229781017543655">"Okuzenzekelayo"</string>
     <string name="notification_automatic_title" msgid="3745465364578762652">"Okuzenzekelayo"</string>
@@ -911,8 +914,7 @@
     <string name="system_multitasking_rhs" msgid="8779289852395243004">"Sebenzisa ukuhlukanisa isikrini nge-app kwesokudla"</string>
     <string name="system_multitasking_lhs" msgid="7348595296208696452">"Sebenzisa ukuhlukanisa isikrini nge-app kwesokunxele"</string>
     <string name="system_multitasking_full_screen" msgid="4221409316059910349">"Sebenzisa isikrini esigcwele"</string>
-    <!-- no translation found for system_multitasking_desktop_view (8871367687089347180) -->
-    <skip />
+    <string name="system_multitasking_desktop_view" msgid="8871367687089347180">"Sebenzisa iwindi ledeskithophu"</string>
     <string name="system_multitasking_splitscreen_focus_rhs" msgid="3838578650313318508">"Shintshela ku-app ngakwesokudla noma ngezansi ngenkathi usebenzisa uhlukanisa isikrini"</string>
     <string name="system_multitasking_splitscreen_focus_lhs" msgid="3164261844398662518">"Shintshela ku-app ngakwesokunxele noma ngaphezulu ngenkathi usebenzisa ukuhlukanisa isikrini"</string>
     <string name="system_multitasking_replace" msgid="7410071959803642125">"Ngesikhathi sokuhlukaniswa kwesikrini: shintsha i-app ngenye"</string>
@@ -986,6 +988,8 @@
     <string name="drag_to_remove_tiles" msgid="4682194717573850385">"Hudulela lapha ukuze ususe"</string>
     <string name="drag_to_remove_disabled" msgid="933046987838658850">"Udinga okungenani amathayela angu-<xliff:g id="MIN_NUM_TILES">%1$d</xliff:g>"</string>
     <string name="qs_edit" msgid="5583565172803472437">"Hlela"</string>
+    <!-- no translation found for qs_edit_tiles (2105215324060865035) -->
+    <skip />
     <string name="tuner_time" msgid="2450785840990529997">"Isikhathi"</string>
   <string-array name="clock_options">
     <item msgid="3986445361435142273">"Bonisa amahora, amaminithi, namasekhondi"</item>
@@ -1008,8 +1012,7 @@
     <string name="accessibility_qs_edit_tile_add_to_position" msgid="9029163095148274690">"Engeza kusikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string>
     <string name="accessibilit_qs_edit_tile_add_move_invalid_position" msgid="2858467994472624487">"Indawo ayivumelekile."</string>
     <string name="accessibility_qs_edit_position" msgid="4509277359815711830">"Isikhundla se-<xliff:g id="POSITION">%1$d</xliff:g>"</string>
-    <!-- no translation found for accessibility_qs_edit_tile_already_added (5900071201690226752) -->
-    <skip />
+    <string name="accessibility_qs_edit_tile_already_added" msgid="5900071201690226752">"Ithayela lifakiwe kakade"</string>
     <string name="accessibility_qs_edit_tile_added" msgid="9067146040380836334">"Ithayela lingeziwe"</string>
     <string name="accessibility_qs_edit_tile_removed" msgid="1175925632436612036">"Ithayela likhishiwe"</string>
     <string name="accessibility_desc_quick_settings_edit" msgid="741658939453595297">"Isihleli sezilungiselelo ezisheshayo."</string>
@@ -1210,7 +1213,6 @@
     <string name="controls_media_close_session" msgid="4780485355795635052">"Fihlela i-<xliff:g id="APP_NAME">%1$s</xliff:g> lesi silawuli semidiya?"</string>
     <string name="controls_media_active_session" msgid="3146882316024153337">"Iseshini yamanje yemidiya ayikwazi ukufihlwa."</string>
     <string name="controls_media_dismiss_button" msgid="4485675693008031646">"Fihla"</string>
-    <string name="controls_media_resume" msgid="1933520684481586053">"Qalisa kabusha"</string>
     <string name="controls_media_settings_button" msgid="5815790345117172504">"Izilungiselelo"</string>
     <string name="controls_media_playing_item_description" msgid="4531853311504359098">"I-<xliff:g id="SONG_NAME">%1$s</xliff:g> ka-<xliff:g id="ARTIST_NAME">%2$s</xliff:g> idlala kusuka ku-<xliff:g id="APP_LABEL">%3$s</xliff:g>"</string>
     <string name="controls_media_seekbar_description" msgid="4389621713616214611">"<xliff:g id="ELAPSED_TIME">%1$s</xliff:g> ku-<xliff:g id="TOTAL_TIME">%2$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-zu/tiles_states_strings.xml b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
index 13ffe04..10b26fc 100644
--- a/packages/SystemUI/res/values-zu/tiles_states_strings.xml
+++ b/packages/SystemUI/res/values-zu/tiles_states_strings.xml
@@ -56,6 +56,11 @@
     <item msgid="5376619709702103243">"Valiwe"</item>
     <item msgid="4875147066469902392">"Vuliwe"</item>
   </string-array>
+  <string-array name="tile_states_modes_dnd">
+    <item msgid="6509540227356524582">"Ayitholakali"</item>
+    <item msgid="8589336868985358191">"Valiwe"</item>
+    <item msgid="726072717827778234">"Vuliwe"</item>
+  </string-array>
   <string-array name="tile_states_flashlight">
     <item msgid="3465257127433353857">"Akutholakali"</item>
     <item msgid="5044688398303285224">"Valiwe"</item>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index f4c6904..7c6a1b1 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -34,7 +34,7 @@
 
     <!-- Base colors for notification shade/scrim, the alpha component is adjusted programmatically
     to match the spec -->
-    <color name="shade_panel_base">@android:color/system_accent1_900</color>
+    <color name="shade_panel_base">@android:color/system_accent1_100</color>
     <color name="notification_scrim_base">@android:color/system_accent1_100</color>
 
     <!-- Fallback colors for notification shade/scrim -->
@@ -146,7 +146,8 @@
     <color name="smart_reply_button_stroke">@*android:color/accent_device_default</color>
 
     <!-- Magic Action colors -->
-    <color name="magic_action_button_text_color">@androidprv:color/materialColorOnSurfaceVariant</color>
+    <color name="magic_action_button_text_color">@androidprv:color/materialColorOnSurface</color>
+    <color name="magic_action_button_stroke_color">@androidprv:color/materialColorOnSurface</color>
 
     <!-- Biometric dialog colors -->
     <color name="biometric_dialog_gray">#ff757575</color>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index cd94a26..b627bdf 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1016,6 +1016,13 @@
     <string name="hearing_devices_presets_error">Couldn\'t update preset</string>
     <!-- QuickSettings: Title for hearing aids presets. Preset is a set of hearing aid settings. User can apply different settings in different environments (e.g. Outdoor, Restaurant, Home) [CHAR LIMIT=40]-->
     <string name="hearing_devices_preset_label">Preset</string>
+    <!-- QuickSettings: Title for hearing aids input routing control in hearing device dialog. [CHAR LIMIT=40]-->
+    <string name="hearing_devices_input_routing_label">Default microphone for calls</string>
+    <!-- QuickSettings: Option for hearing aids input routing control in hearing device dialog. It will alter input routing for calls for hearing aid. [CHAR LIMIT=40]-->
+    <string-array name="hearing_device_input_routing_options">
+        <item>Hearing aid microphone</item>
+        <item>This phone\'s microphone</item>
+    </string-array>
     <!-- QuickSettings: Content description for the icon that indicates the item is selected [CHAR LIMIT=NONE]-->
     <string name="hearing_devices_spinner_item_selected">Selected</string>
     <!-- QuickSettings: Title for ambient controls. [CHAR LIMIT=40]-->
@@ -1476,6 +1483,8 @@
     <string name="media_projection_entry_app_permission_dialog_continue_entire_screen">Share screen</string>
     <!-- 1P/3P apps disabled the single app projection option. [CHAR LIMIT=NONE] -->
     <string name="media_projection_entry_app_permission_dialog_single_app_disabled"><xliff:g id="app_name" example="Meet">%1$s</xliff:g> has disabled this option</string>
+    <!-- Explanation that the app requesting the projection does not support single app sharing[CHAR LIMIT=70] -->
+    <string name="media_projection_entry_app_permission_dialog_single_app_not_supported">Not supported by the app</string>
     <!-- Title of the activity that allows users to select an app to share to a 1P/3P app [CHAR LIMIT=70] -->
     <string name="media_projection_entry_share_app_selector_title">Choose app to share</string>
 
@@ -2056,7 +2065,7 @@
     <string name="inline_ok_button">Apply</string>
 
     <!-- Notification inline controls: button to show block screen [CHAR_LIMIT=35] -->
-    <string name="inline_turn_off_notifications">Turn off notifications</string>
+    <string name="inline_turn_off_notifications">Turn off</string>
 
     <!-- [CHAR LIMIT=100] Notification Importance title -->
     <string name="notification_silence_title">Silent</string>
@@ -2551,6 +2560,9 @@
     <!-- Button to edit the tile ordering of quick settings [CHAR LIMIT=60] -->
     <string name="qs_edit">Edit</string>
 
+    <!-- Title for QS Edit mode screen [CHAR LIMIT=30] -->
+    <string name="qs_edit_tiles">Edit tiles</string>
+
     <!-- SysUI Tuner: Options for how clock is displayed [CHAR LIMIT=NONE] -->
     <string name="tuner_time">Time</string>
 
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 7895ff7..a479f18 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -19,7 +19,8 @@
 
     <style name="TextAppearance.StatusBar.Clock" parent="@*android:style/TextAppearance.StatusBar.Icon">
         <item name="android:textSize">@dimen/status_bar_clock_size</item>
-        <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
+        <item name="android:fontFamily" android:featureFlag="!com.android.systemui.status_bar_font_updates">@*android:string/config_headlineFontFamilyMedium</item>
+        <item name="android:fontFamily" android:featureFlag="com.android.systemui.status_bar_font_updates">"variable-label-large-emphasized"</item>
         <item name="android:textColor">@color/status_bar_clock_color</item>
         <item name="android:fontFeatureSettings">tnum</item>
     </style>
diff --git a/packages/SystemUI/shared/res/values/bools.xml b/packages/SystemUI/shared/res/values/bools.xml
index 98e5cea..a7ad48d 100644
--- a/packages/SystemUI/shared/res/values/bools.xml
+++ b/packages/SystemUI/shared/res/values/bools.xml
@@ -22,7 +22,4 @@
 <resources>
     <!-- Whether to add padding at the bottom of the complication clock -->
     <bool name="dream_overlay_complication_clock_bottom_padding">false</bool>
-
-    <!-- Whether to mark tasks that are present in the UI as perceptible tasks. -->
-    <bool name="config_usePerceptibleTasks">false</bool>
 </resources>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt
index f276a82..c30580f 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/CombinedCondition.kt
@@ -37,51 +37,43 @@
  * @param operand The [Evaluator.ConditionOperand] to apply to the conditions.
  */
 @OptIn(ExperimentalCoroutinesApi::class)
-class CombinedCondition
-constructor(
+class CombinedCondition(
     private val scope: CoroutineScope,
     private val conditions: Collection<Condition>,
     @Evaluator.ConditionOperand private val operand: Int,
 ) : Condition(scope, null, false) {
 
-    private var job: Job? = null
     private val _startStrategy by lazy { calculateStartStrategy() }
 
-    override fun start() {
-        job =
-            scope.launch {
-                val groupedConditions = conditions.groupBy { it.isOverridingCondition }
+    override suspend fun start() {
+        val groupedConditions = conditions.groupBy { it.isOverridingCondition }
 
-                lazilyEvaluate(
-                        conditions = groupedConditions.getOrDefault(true, emptyList()),
-                        filterUnknown = true,
+        lazilyEvaluate(
+                conditions = groupedConditions.getOrDefault(true, emptyList()),
+                filterUnknown = true,
+            )
+            .distinctUntilChanged()
+            .flatMapLatest { overriddenValue ->
+                // If there are overriding conditions with values set, they take precedence.
+                if (overriddenValue == null) {
+                    lazilyEvaluate(
+                        conditions = groupedConditions.getOrDefault(false, emptyList()),
+                        filterUnknown = false,
                     )
-                    .distinctUntilChanged()
-                    .flatMapLatest { overriddenValue ->
-                        // If there are overriding conditions with values set, they take precedence.
-                        if (overriddenValue == null) {
-                            lazilyEvaluate(
-                                conditions = groupedConditions.getOrDefault(false, emptyList()),
-                                filterUnknown = false,
-                            )
-                        } else {
-                            flowOf(overriddenValue)
-                        }
-                    }
-                    .collect { conditionMet ->
-                        if (conditionMet == null) {
-                            clearCondition()
-                        } else {
-                            updateCondition(conditionMet)
-                        }
-                    }
+                } else {
+                    flowOf(overriddenValue)
+                }
+            }
+            .collect { conditionMet ->
+                if (conditionMet == null) {
+                    clearCondition()
+                } else {
+                    updateCondition(conditionMet)
+                }
             }
     }
 
-    override fun stop() {
-        job?.cancel()
-        job = null
-    }
+    override fun stop() {}
 
     /**
      * Evaluates a list of conditions lazily with support for short-circuiting. Conditions are
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt
index 69236b4..44803bd 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/Condition.kt
@@ -22,6 +22,8 @@
 import androidx.lifecycle.LifecycleOwner
 import java.lang.ref.WeakReference
 import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
 
 /**
  * Base class for a condition that needs to be fulfilled in order for [Monitor] to inform its
@@ -43,11 +45,12 @@
 ) {
     private val mTag: String = javaClass.simpleName
 
-    private val _callbacks = mutableListOf<WeakReference<Callback>>()
-    private var _started = false
+    private val callbacks = mutableListOf<WeakReference<Callback>>()
+    private var started = false
+    private var currentJob: Job? = null
 
     /** Starts monitoring the condition. */
-    protected abstract fun start()
+    protected abstract suspend fun start()
 
     /** Stops monitoring the condition. */
     protected abstract fun stop()
@@ -64,21 +67,21 @@
      */
     fun addCallback(callback: Callback) {
         if (shouldLog()) Log.d(mTag, "adding callback")
-        _callbacks.add(WeakReference(callback))
+        callbacks.add(WeakReference(callback))
 
-        if (_started) {
+        if (started) {
             callback.onConditionChanged(this)
             return
         }
 
-        start()
-        _started = true
+        currentJob = _scope.launch { start() }
+        started = true
     }
 
     /** Removes the provided callback from further receiving updates. */
     fun removeCallback(callback: Callback) {
         if (shouldLog()) Log.d(mTag, "removing callback")
-        val iterator = _callbacks.iterator()
+        val iterator = callbacks.iterator()
         while (iterator.hasNext()) {
             val cb = iterator.next().get()
             if (cb == null || cb === callback) {
@@ -86,12 +89,15 @@
             }
         }
 
-        if (_callbacks.isNotEmpty() || !_started) {
+        if (callbacks.isNotEmpty() || !started) {
             return
         }
 
         stop()
-        _started = false
+        currentJob?.cancel()
+        currentJob = null
+
+        started = false
     }
 
     /**
@@ -151,7 +157,7 @@
     }
 
     private fun sendUpdate() {
-        val iterator = _callbacks.iterator()
+        val iterator = callbacks.iterator()
         while (iterator.hasNext()) {
             val cb = iterator.next().get()
             if (cb == null) {
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt
index 0f535cd..849b3d6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/condition/ConditionExtensions.kt
@@ -19,7 +19,7 @@
     return object : Condition(scope, initialValue, false) {
         var job: Job? = null
 
-        override fun start() {
+        override suspend fun start() {
             job = scope.launch { collect { updateCondition(it) } }
         }
 
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index 487d1ce..b981f98 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -46,8 +46,6 @@
 import android.window.TaskSnapshot;
 
 import com.android.internal.app.IVoiceInteractionManagerService;
-import com.android.server.am.Flags;
-import com.android.systemui.shared.R;
 import com.android.systemui.shared.recents.model.Task;
 import com.android.systemui.shared.recents.model.ThumbnailData;
 
@@ -324,14 +322,6 @@
     }
 
     /**
-     * Returns true if tasks with a presence in the UI should be marked as perceptible tasks.
-     */
-    public static boolean usePerceptibleTasks(Context context) {
-        return Flags.perceptibleTasks()
-                && context.getResources().getBoolean(R.bool.config_usePerceptibleTasks);
-    }
-
-    /**
      * Returns true if the running task represents the home task
      */
     public static boolean isHomeTask(RunningTaskInfo info) {
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 763b107..f2f1773 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -572,10 +572,6 @@
     }
 
     fun handleFidgetTap(x: Float, y: Float) {
-        if (!com.android.systemui.Flags.clockFidgetAnimation()) {
-            return
-        }
-
         clock?.run {
             smallClock.animations.onFidgetTap(x, y)
             largeClock.animations.onFidgetTap(x, y)
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index e3afe2e..d017754 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -902,8 +902,8 @@
                 if (NotificationBundleUi.isEnabled()) {
                     return enr.getEntryAdapter().canDragAndDrop();
                 } else {
-                    boolean canBubble = enr.getEntry().canBubble();
-                    Notification notif = enr.getEntry().getSbn().getNotification();
+                    boolean canBubble = enr.getEntryLegacy().canBubble();
+                    Notification notif = enr.getEntryLegacy().getSbn().getNotification();
                     PendingIntent dragIntent = notif.contentIntent != null ? notif.contentIntent
                             : notif.fullScreenIntent;
                     if (dragIntent != null && dragIntent.isActivity() && !canBubble) {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java
index bd3dfe0..8025d4b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearance.java
@@ -317,14 +317,14 @@
     public static float avoidVerticalDisplayCutout(
             float y, float menuHeight, Rect bounds, Rect cutout) {
         if (cutout.top > y + menuHeight || cutout.bottom < y) {
-            return y;
+            return clampVerticalPosition(y, menuHeight, bounds.top, bounds.bottom);
         }
 
         boolean topAvailable = cutout.top - bounds.top >= menuHeight;
         boolean bottomAvailable = bounds.bottom - cutout.bottom >= menuHeight;
         boolean topOrBottom;
         if (!topAvailable && !bottomAvailable) {
-            return y;
+            return clampVerticalPosition(y, menuHeight, bounds.top, bounds.bottom);
         } else if (topAvailable && !bottomAvailable) {
             topOrBottom = true;
         } else if (!topAvailable && bottomAvailable) {
@@ -332,7 +332,16 @@
         } else {
             topOrBottom = y + menuHeight * 0.5f < cutout.centerY();
         }
-        return (topOrBottom) ? cutout.top - menuHeight : cutout.bottom;
+
+        float finalPosition = (topOrBottom) ? cutout.top - menuHeight : cutout.bottom;
+        return clampVerticalPosition(finalPosition, menuHeight, bounds.top, bounds.bottom);
+    }
+
+    private static float clampVerticalPosition(
+            float position, float height, float min, float max) {
+        position = Float.max(min + height / 2, position);
+        position = Float.min(max - height / 2, position);
+        return position;
     }
 
     boolean isMenuOnLeftSide() {
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
index fb3bc62..24b9551 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesDialogDelegate.java
@@ -121,6 +121,13 @@
     private Spinner mPresetSpinner;
     private HearingDevicesPresetsController mPresetController;
     private HearingDevicesSpinnerAdapter mPresetInfoAdapter;
+
+    private View mInputRoutingLayout;
+    private Spinner mInputRoutingSpinner;
+    private HearingDevicesInputRoutingController.Factory mInputRoutingControllerFactory;
+    private HearingDevicesInputRoutingController mInputRoutingController;
+    private HearingDevicesSpinnerAdapter mInputRoutingAdapter;
+
     private final HearingDevicesPresetsController.PresetCallback mPresetCallback =
             new HearingDevicesPresetsController.PresetCallback() {
                 @Override
@@ -169,7 +176,8 @@
             @Background Executor bgExecutor,
             AudioManager audioManager,
             HearingDevicesUiEventLogger uiEventLogger,
-            QSSettingsPackageRepository qsSettingsPackageRepository) {
+            QSSettingsPackageRepository qsSettingsPackageRepository,
+            HearingDevicesInputRoutingController.Factory inputRoutingControllerFactory) {
         mShowPairNewDevice = showPairNewDevice;
         mSystemUIDialogFactory = systemUIDialogFactory;
         mActivityStarter = activityStarter;
@@ -182,6 +190,7 @@
         mUiEventLogger = uiEventLogger;
         mLaunchSourceId = launchSourceId;
         mQSSettingsPackageRepository = qsSettingsPackageRepository;
+        mInputRoutingControllerFactory = inputRoutingControllerFactory;
     }
 
     @Override
@@ -239,6 +248,12 @@
                 mPresetLayout.setVisibility(
                         mPresetController.isPresetControlAvailable() ? VISIBLE : GONE);
             }
+            if (mInputRoutingController != null) {
+                mInputRoutingController.setDevice(device);
+                mInputRoutingController.isInputRoutingControlAvailable(
+                        available -> mMainExecutor.execute(() -> mInputRoutingLayout.setVisibility(
+                                available ? VISIBLE : GONE)));
+            }
             if (mAmbientController != null) {
                 mAmbientController.loadDevice(device);
             }
@@ -271,7 +286,9 @@
                             mLaunchSourceId);
                     final Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_DETAILS_SETTINGS)
                             .putExtra(Intent.EXTRA_COMPONENT_NAME,
-                                    ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString());
+                                    ACCESSIBILITY_HEARING_AIDS_COMPONENT_NAME.flattenToString())
+                            .setPackage(mQSSettingsPackageRepository.getSettingsPackageName());
+
                     mActivityStarter.postStartActivityDismissingKeyguard(intent, /* delay= */ 0,
                             mDialogTransitionAnimator.createActivityTransitionController(
                                     dialog));
@@ -310,6 +327,11 @@
                 setupDeviceListView(dialog, hearingDeviceItemList);
                 setupPairNewDeviceButton(dialog);
                 setupPresetSpinner(dialog, activeHearingDevice);
+                if (com.android.settingslib.flags.Flags.hearingDevicesInputRoutingControl()
+                        && com.android.systemui.Flags
+                        .hearingDevicesInputRoutingUiImprovement()) {
+                    setupInputRoutingSpinner(dialog, activeHearingDevice);
+                }
                 if (com.android.settingslib.flags.Flags.hearingDevicesAmbientVolumeControl()) {
                     setupAmbientControls(activeHearingDevice);
                 }
@@ -383,6 +405,52 @@
         mBgExecutor.execute(() -> mPresetController.registerHapCallback());
     }
 
+    private void setupInputRoutingSpinner(SystemUIDialog dialog,
+            CachedBluetoothDevice activeHearingDevice) {
+        mInputRoutingController = mInputRoutingControllerFactory.create(dialog.getContext());
+        mInputRoutingController.setDevice(activeHearingDevice);
+
+        mInputRoutingSpinner = dialog.requireViewById(R.id.input_routing_spinner);
+        mInputRoutingAdapter = new HearingDevicesSpinnerAdapter(dialog.getContext());
+        mInputRoutingAdapter.addAll(
+                HearingDevicesInputRoutingController.getInputRoutingOptions(dialog.getContext()));
+        mInputRoutingSpinner.setAdapter(mInputRoutingAdapter);
+        // Disable redundant Touch & Hold accessibility action for Switch Access
+        mInputRoutingSpinner.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+            @Override
+            public void onInitializeAccessibilityNodeInfo(@NonNull View host,
+                    @NonNull AccessibilityNodeInfo info) {
+                info.removeAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_LONG_CLICK);
+                super.onInitializeAccessibilityNodeInfo(host, info);
+            }
+        });
+        // Should call setSelection(index, false) for the spinner before setOnItemSelectedListener()
+        // to avoid extra onItemSelected() get called when first register the listener.
+        final int initialPosition =
+                mInputRoutingController.getUserPreferredInputRoutingValue();
+        mInputRoutingSpinner.setSelection(initialPosition, false);
+        mInputRoutingAdapter.setSelected(initialPosition);
+        mInputRoutingSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+            @Override
+            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+                mInputRoutingAdapter.setSelected(position);
+                mUiEventLogger.log(HearingDevicesUiEvent.HEARING_DEVICES_INPUT_ROUTING_SELECT,
+                        mLaunchSourceId);
+                mInputRoutingController.selectInputRouting(position);
+            }
+
+            @Override
+            public void onNothingSelected(AdapterView<?> parent) {
+                // Do nothing
+            }
+        });
+
+        mInputRoutingLayout = dialog.requireViewById(R.id.input_routing_layout);
+        mInputRoutingController.isInputRoutingControlAvailable(
+                available -> mMainExecutor.execute(() -> mInputRoutingLayout.setVisibility(
+                        available ? VISIBLE : GONE)));
+    }
+
     private void setupAmbientControls(CachedBluetoothDevice activeHearingDevice) {
         final AmbientVolumeLayout ambientLayout = mDialog.requireViewById(R.id.ambient_layout);
         ambientLayout.setUiEventLogger(mUiEventLogger, mLaunchSourceId);
@@ -522,9 +590,7 @@
                     com.android.internal.R.color.materialColorOnPrimaryContainer));
         }
         text.setText(item.getToolName());
-        Intent intent = item.getToolIntent()
-                .setPackage(mQSSettingsPackageRepository.getSettingsPackageName());
-
+        Intent intent = item.getToolIntent();
         view.setOnClickListener(v -> {
             final String name = intent.getComponent() != null
                     ? intent.getComponent().flattenToString()
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingController.kt b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingController.kt
new file mode 100644
index 0000000..e8fa7ba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesInputRoutingController.kt
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.accessibility.hearingaid
+
+import android.content.Context
+import android.media.AudioManager
+import android.util.Log
+import androidx.collection.ArraySet
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.settingslib.bluetooth.HapClientProfile
+import com.android.settingslib.bluetooth.HearingAidAudioRoutingConstants
+import com.android.settingslib.bluetooth.HearingAidAudioRoutingHelper
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.res.R
+import dagger.assisted.Assisted
+import dagger.assisted.AssistedFactory
+import dagger.assisted.AssistedInject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/**
+ * The controller of the hearing device input routing.
+ *
+ * <p> It manages and update the input routing according to the value.
+ */
+open class HearingDevicesInputRoutingController
+@AssistedInject
+constructor(
+    @Assisted context: Context,
+    private val audioManager: AudioManager,
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+) {
+    private val audioRoutingHelper = HearingAidAudioRoutingHelper(context)
+    private var cachedDevice: CachedBluetoothDevice? = null
+    private val bgCoroutineScope = CoroutineScope(backgroundDispatcher)
+
+    /** Factory to create a [HearingDevicesInputRoutingController] instance. */
+    @AssistedFactory
+    interface Factory {
+        fun create(context: Context): HearingDevicesInputRoutingController
+    }
+
+    /** Possible input routing UI. Need to align with [getInputRoutingOptions] */
+    enum class InputRoutingValue {
+        HEARING_DEVICE,
+        BUILTIN_MIC,
+    }
+
+    companion object {
+        private const val TAG = "HearingDevicesInputRoutingController"
+
+        /** Gets input routing options as strings. */
+        @JvmStatic
+        fun getInputRoutingOptions(context: Context): Array<String> {
+            return context.resources.getStringArray(R.array.hearing_device_input_routing_options)
+        }
+    }
+
+    fun interface InputRoutingControlAvailableCallback {
+        fun onResult(available: Boolean)
+    }
+
+    /**
+     * Sets the device for this controller to control the input routing.
+     *
+     * @param device the [CachedBluetoothDevice] set to the controller
+     */
+    fun setDevice(device: CachedBluetoothDevice?) {
+        this@HearingDevicesInputRoutingController.cachedDevice = device
+    }
+
+    fun isInputRoutingControlAvailable(callback: InputRoutingControlAvailableCallback) {
+        bgCoroutineScope.launch {
+            val result = isInputRoutingControlAvailableInternal()
+            callback.onResult(result)
+        }
+    }
+
+    /**
+     * Checks if input routing control is available for the currently set device.
+     *
+     * @return `true` if input routing control is available.
+     */
+    private suspend fun isInputRoutingControlAvailableInternal(): Boolean {
+        val device = cachedDevice ?: return false
+
+        val memberDevices = device.memberDevice
+
+        val inputInfos =
+            withContext(backgroundDispatcher) {
+                audioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)
+            }
+        val supportedInputDeviceAddresses = ArraySet<String>()
+        supportedInputDeviceAddresses.add(device.address)
+        if (memberDevices.isNotEmpty()) {
+            memberDevices.forEach { supportedInputDeviceAddresses.add(it.address) }
+        }
+
+        val isValidInputDevice =
+            inputInfos.any { supportedInputDeviceAddresses.contains(it.address) }
+        // Not support ASHA hearing device for input routing feature
+        val isHapHearingDevice = device.profiles.any { profile -> profile is HapClientProfile }
+
+        if (isHapHearingDevice && !isValidInputDevice) {
+            Log.d(TAG, "Not supported input type hearing device.")
+        }
+        return isHapHearingDevice && isValidInputDevice
+    }
+
+    /** Gets the user's preferred [InputRoutingValue]. */
+    fun getUserPreferredInputRoutingValue(): Int {
+        val device = cachedDevice ?: return InputRoutingValue.HEARING_DEVICE.ordinal
+
+        return if (device.device.isMicrophonePreferredForCalls) {
+            InputRoutingValue.HEARING_DEVICE.ordinal
+        } else {
+            InputRoutingValue.BUILTIN_MIC.ordinal
+        }
+    }
+
+    /**
+     * Sets the input routing to [android.bluetooth.BluetoothDevice.setMicrophonePreferredForCalls]
+     * based on the input routing index.
+     *
+     * @param inputRoutingIndex The desired input routing index.
+     */
+    fun selectInputRouting(inputRoutingIndex: Int) {
+        val device = cachedDevice ?: return
+
+        val useBuiltinMic = (inputRoutingIndex == InputRoutingValue.BUILTIN_MIC.ordinal)
+        val status =
+            audioRoutingHelper.setPreferredInputDeviceForCalls(
+                device,
+                if (useBuiltinMic) HearingAidAudioRoutingConstants.RoutingValue.BUILTIN_DEVICE
+                else HearingAidAudioRoutingConstants.RoutingValue.AUTO,
+            )
+        if (!status) {
+            Log.d(TAG, "Fail to configure setPreferredInputDeviceForCalls")
+        }
+        setMicrophonePreferredForCallsForDeviceSet(device, !useBuiltinMic)
+    }
+
+    private fun setMicrophonePreferredForCallsForDeviceSet(
+        device: CachedBluetoothDevice?,
+        enabled: Boolean,
+    ) {
+        device ?: return
+        device.device.isMicrophonePreferredForCalls = enabled
+        val memberDevices = device.memberDevice
+        if (memberDevices.isNotEmpty()) {
+            memberDevices.forEach { d -> d.device.isMicrophonePreferredForCalls = enabled }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt
index 4a695d6..82ac10d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/hearingaid/HearingDevicesUiEvent.kt
@@ -40,6 +40,8 @@
     HEARING_DEVICES_AMBIENT_EXPAND_CONTROLS(2153),
     @UiEvent(doc = "Collapse the ambient volume controls")
     HEARING_DEVICES_AMBIENT_COLLAPSE_CONTROLS(2154),
+    @UiEvent(doc = "Select a input routing option from input routing spinner")
+    HEARING_DEVICES_INPUT_ROUTING_SELECT(2155),
     @UiEvent(doc = "Click on the device settings to enter hearing devices page")
     HEARING_DEVICES_SETTINGS_CLICK(2172);
 
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
index fb47d42..e25d54b 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/qs/QSAccessibilityModule.kt
@@ -29,40 +29,40 @@
 import com.android.systemui.qs.tiles.NightDisplayTile
 import com.android.systemui.qs.tiles.OneHandedModeTile
 import com.android.systemui.qs.tiles.ReduceBrightColorsTile
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
-import com.android.systemui.qs.tiles.impl.colorcorrection.domain.ColorCorrectionTileMapper
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.interactor.ColorCorrectionTileDataInteractor
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.interactor.ColorCorrectionUserActionInteractor
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
-import com.android.systemui.qs.tiles.impl.fontscaling.domain.FontScalingTileMapper
+import com.android.systemui.qs.tiles.impl.colorcorrection.ui.mapper.ColorCorrectionTileMapper
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.interactor.FontScalingTileDataInteractor
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.interactor.FontScalingTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel
-import com.android.systemui.qs.tiles.impl.hearingdevices.domain.HearingDevicesTileMapper
+import com.android.systemui.qs.tiles.impl.fontscaling.ui.mapper.FontScalingTileMapper
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.interactor.HearingDevicesTileDataInteractor
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.interactor.HearingDevicesTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
-import com.android.systemui.qs.tiles.impl.inversion.domain.ColorInversionTileMapper
+import com.android.systemui.qs.tiles.impl.hearingdevices.ui.mapper.HearingDevicesTileMapper
 import com.android.systemui.qs.tiles.impl.inversion.domain.interactor.ColorInversionTileDataInteractor
 import com.android.systemui.qs.tiles.impl.inversion.domain.interactor.ColorInversionUserActionInteractor
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
+import com.android.systemui.qs.tiles.impl.inversion.ui.mapper.ColorInversionTileMapper
 import com.android.systemui.qs.tiles.impl.night.domain.interactor.NightDisplayTileDataInteractor
 import com.android.systemui.qs.tiles.impl.night.domain.interactor.NightDisplayTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel
-import com.android.systemui.qs.tiles.impl.night.ui.NightDisplayTileMapper
+import com.android.systemui.qs.tiles.impl.night.ui.mapper.NightDisplayTileMapper
 import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileDataInteractor
 import com.android.systemui.qs.tiles.impl.onehanded.domain.OneHandedModeTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel
-import com.android.systemui.qs.tiles.impl.onehanded.ui.OneHandedModeTileMapper
+import com.android.systemui.qs.tiles.impl.onehanded.ui.mapper.OneHandedModeTileMapper
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.interactor.ReduceBrightColorsTileDataInteractor
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.interactor.ReduceBrightColorsTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
-import com.android.systemui.qs.tiles.impl.reducebrightness.ui.ReduceBrightColorsTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
-import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
+import com.android.systemui.qs.tiles.impl.reducebrightness.ui.mapper.ReduceBrightColorsTileMapper
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
index 831bc1d..26d5562 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatterySaverModule.kt
@@ -5,15 +5,15 @@
 import com.android.systemui.qs.shared.model.TileCategory
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.BatterySaverTile
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
 import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileDataInteractor
 import com.android.systemui.qs.tiles.impl.battery.domain.interactor.BatterySaverTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel
-import com.android.systemui.qs.tiles.impl.battery.ui.BatterySaverTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.impl.battery.ui.mapper.BatterySaverTileMapper
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
@@ -63,7 +63,7 @@
             factory: QSTileViewModelFactory.Static<BatterySaverTileModel>,
             mapper: BatterySaverTileMapper,
             stateInteractor: BatterySaverTileDataInteractor,
-            userActionInteractor: BatterySaverTileUserActionInteractor
+            userActionInteractor: BatterySaverTileUserActionInteractor,
         ): QSTileViewModel =
             factory.create(
                 TileSpec.create(BATTERY_SAVER_TILE_SPEC),
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
index 22d2aaf..87e9784 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
@@ -32,7 +32,6 @@
 import com.android.keyguard.logging.KeyguardLogger
 import com.android.settingslib.Utils
 import com.android.systemui.CoreStartable
-import com.android.systemui.Flags.lightRevealMigration
 import com.android.systemui.biometrics.data.repository.FacePropertyRepository
 import com.android.systemui.biometrics.shared.model.UdfpsOverlayParams
 import com.android.systemui.dagger.SysUISingleton
@@ -43,6 +42,7 @@
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.res.R
+import com.android.systemui.shared.Flags.ambientAod
 import com.android.systemui.statusbar.CircleReveal
 import com.android.systemui.statusbar.LiftReveal
 import com.android.systemui.statusbar.LightRevealEffect
@@ -196,7 +196,7 @@
 
         // This code path is not used if the KeyguardTransitionRepository is managing the light
         // reveal scrim.
-        if (!lightRevealMigration()) {
+        if (!ambientAod()) {
             if (statusBarStateController.isDozing || biometricUnlockController.isWakeAndUnlock) {
                 circleReveal?.let {
                     lightRevealScrim.revealAmount = 0f
@@ -213,7 +213,7 @@
     }
 
     override fun onKeyguardFadingAwayChanged() {
-        if (lightRevealMigration()) {
+        if (ambientAod()) {
             return
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ActionIntentCreator.kt b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ActionIntentCreator.kt
index df6c1b1..8cebe04 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ActionIntentCreator.kt
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ActionIntentCreator.kt
@@ -24,11 +24,17 @@
 import android.net.Uri
 import android.text.TextUtils
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.res.R
+import java.util.function.Consumer
 import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
 
 @SysUISingleton
-class ActionIntentCreator @Inject constructor() : IntentCreator {
+class ActionIntentCreator
+@Inject
+constructor(@Application private val applicationScope: CoroutineScope) : IntentCreator {
     override fun getTextEditorIntent(context: Context?) =
         Intent(context, EditTextActivity::class.java).apply {
             addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK)
@@ -65,7 +71,7 @@
             .addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
     }
 
-    override fun getImageEditIntent(uri: Uri?, context: Context): Intent {
+    suspend fun getImageEditIntent(uri: Uri?, context: Context): Intent {
         val editorPackage = context.getString(R.string.config_screenshotEditor)
         return Intent(Intent.ACTION_EDIT).apply {
             if (!TextUtils.isEmpty(editorPackage)) {
@@ -78,6 +84,14 @@
         }
     }
 
+    override fun getImageEditIntentAsync(
+        uri: Uri?,
+        context: Context,
+        outputConsumer: Consumer<Intent>,
+    ) {
+        applicationScope.launch { outputConsumer.accept(getImageEditIntent(uri, context)) }
+    }
+
     override fun getRemoteCopyIntent(clipData: ClipData?, context: Context): Intent {
         val remoteCopyPackage = context.getString(R.string.config_remoteCopyPackage)
         return Intent(REMOTE_COPY_ACTION).apply {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
index 314b6e7..984d247 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/ClipboardOverlayController.java
@@ -558,8 +558,10 @@
 
     private void editImage(Uri uri) {
         mClipboardLogger.logSessionComplete(CLIPBOARD_OVERLAY_EDIT_TAPPED);
-        mContext.startActivity(mIntentCreator.getImageEditIntent(uri, mContext));
-        animateOut();
+        mIntentCreator.getImageEditIntentAsync(uri, mContext, intent -> {
+            mContext.startActivity(intent);
+            animateOut();
+        });
     }
 
     private void editText() {
@@ -747,8 +749,10 @@
                             mIntentCreator.getTextEditorIntent(mContext));
                     break;
                 case IMAGE:
-                    finishWithSharedTransition(CLIPBOARD_OVERLAY_EDIT_TAPPED,
-                            mIntentCreator.getImageEditIntent(mClipboardModel.getUri(), mContext));
+                    mIntentCreator.getImageEditIntentAsync(mClipboardModel.getUri(), mContext,
+                            intent -> {
+                                finishWithSharedTransition(CLIPBOARD_OVERLAY_EDIT_TAPPED, intent);
+                            });
                     break;
                 default:
                     Log.w(TAG, "Got preview tapped callback for non-editable type "
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DefaultIntentCreator.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DefaultIntentCreator.java
index 4b24536..e9a9cbf 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DefaultIntentCreator.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/DefaultIntentCreator.java
@@ -27,6 +27,8 @@
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.res.R;
 
+import java.util.function.Consumer;
+
 import javax.inject.Inject;
 
 @SysUISingleton
@@ -73,7 +75,7 @@
         return chooserIntent;
     }
 
-    public Intent getImageEditIntent(Uri uri, Context context) {
+    public void getImageEditIntentAsync(Uri uri, Context context, Consumer<Intent> outputConsumer) {
         String editorPackage = context.getString(R.string.config_screenshotEditor);
         Intent editIntent = new Intent(Intent.ACTION_EDIT);
         if (!TextUtils.isEmpty(editorPackage)) {
@@ -83,7 +85,7 @@
         editIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
         editIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
         editIntent.putExtra(EXTRA_EDIT_SOURCE, EDIT_SOURCE_CLIPBOARD);
-        return editIntent;
+        outputConsumer.accept(editIntent);
     }
 
     public Intent getRemoteCopyIntent(ClipData clipData, Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
index c8a6b05..283596f 100644
--- a/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
+++ b/packages/SystemUI/src/com/android/systemui/clipboardoverlay/IntentCreator.java
@@ -21,9 +21,11 @@
 import android.content.Intent;
 import android.net.Uri;
 
+import java.util.function.Consumer;
+
 public interface IntentCreator {
     Intent getTextEditorIntent(Context context);
     Intent getShareIntent(ClipData clipData, Context context);
-    Intent getImageEditIntent(Uri uri, Context context);
+    void getImageEditIntentAsync(Uri uri, Context context, Consumer<Intent> outputConsumer);
     Intent getRemoteCopyIntent(ClipData clipData, Context context);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt b/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt
index 9db7b50..1301fb8 100644
--- a/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/domain/interactor/SysUIStateDisplaysInteractor.kt
@@ -17,9 +17,9 @@
 package com.android.systemui.common.domain.interactor
 
 import android.util.Log
+import com.android.app.displaylib.PerDisplayRepository
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.display.data.repository.DisplayRepository
-import com.android.systemui.display.data.repository.PerDisplayRepository
 import com.android.systemui.model.StateChange
 import com.android.systemui.model.SysUiState
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt
index 2adaec2..6792f31 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/Icon.kt
@@ -19,6 +19,7 @@
 import android.annotation.DrawableRes
 import android.graphics.drawable.Drawable
 import androidx.compose.runtime.Stable
+import com.android.systemui.common.shared.model.Icon.Loaded
 
 /**
  * Models an icon, that can either be already [loaded][Icon.Loaded] or be a [reference]
@@ -33,8 +34,37 @@
     constructor(
         val drawable: Drawable,
         override val contentDescription: ContentDescription?,
+        /**
+         * Serves as an id to compare two instances. When provided this is used alongside
+         * [contentDescription] to determine equality. This is useful when comparing icons
+         * representing the same UI, but with different [drawable] instances.
+         */
         @DrawableRes val res: Int? = null,
-    ) : Icon()
+    ) : Icon() {
+
+        override fun equals(other: Any?): Boolean {
+            val that = other as? Loaded ?: return false
+
+            if (this.res != null && that.res != null) {
+                return this.res == that.res && this.contentDescription == that.contentDescription
+            }
+
+            return this.res == that.res &&
+                this.drawable == that.drawable &&
+                this.contentDescription == that.contentDescription
+        }
+
+        override fun hashCode(): Int {
+            var result = contentDescription?.hashCode() ?: 0
+            result =
+                if (res != null) {
+                    31 * result + res.hashCode()
+                } else {
+                    31 * result + drawable.hashCode()
+                }
+            return result
+        }
+    }
 
     data class Resource(
         @DrawableRes val res: Int,
@@ -49,4 +79,4 @@
 fun Drawable.asIcon(
     contentDescription: ContentDescription? = null,
     @DrawableRes res: Int? = null,
-): Icon.Loaded = Icon.Loaded(this, contentDescription, res)
+): Loaded = Loaded(this, contentDescription, res)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java b/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java
deleted file mode 100644
index 4be9601..0000000
--- a/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.communal;
-
-import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.keyguard.WakefulnessLifecycle;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
-import com.android.systemui.keyguard.shared.model.DozeStateModel;
-import com.android.systemui.shared.condition.Condition;
-import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.kotlin.JavaAdapter;
-
-import kotlinx.coroutines.CoroutineScope;
-import kotlinx.coroutines.Job;
-
-import javax.inject.Inject;
-
-/**
- * Condition which estimates device inactivity in order to avoid launching a full-screen activity
- * while the user is actively using the device.
- */
-public class DeviceInactiveCondition extends Condition {
-    private final KeyguardStateController mKeyguardStateController;
-    private final WakefulnessLifecycle mWakefulnessLifecycle;
-    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
-    private final KeyguardInteractor mKeyguardInteractor;
-    private final JavaAdapter mJavaAdapter;
-    private Job mAnyDozeListenerJob;
-    private boolean mAnyDoze;
-    private final KeyguardStateController.Callback mKeyguardStateCallback =
-            new KeyguardStateController.Callback() {
-                @Override
-                public void onKeyguardShowingChanged() {
-                    updateState();
-                }
-            };
-    private final WakefulnessLifecycle.Observer mWakefulnessObserver =
-            new WakefulnessLifecycle.Observer() {
-                @Override
-                public void onStartedGoingToSleep() {
-                    updateState();
-                }
-            };
-    private final KeyguardUpdateMonitorCallback mKeyguardUpdateCallback =
-            new KeyguardUpdateMonitorCallback() {
-                @Override
-                public void onDreamingStateChanged(boolean dreaming) {
-                    updateState();
-                }
-            };
-
-    @Inject
-    public DeviceInactiveCondition(@Application CoroutineScope scope,
-            KeyguardStateController keyguardStateController,
-            WakefulnessLifecycle wakefulnessLifecycle, KeyguardUpdateMonitor keyguardUpdateMonitor,
-            KeyguardInteractor keyguardInteractor, JavaAdapter javaAdapter) {
-        super(scope);
-        mKeyguardStateController = keyguardStateController;
-        mWakefulnessLifecycle = wakefulnessLifecycle;
-        mKeyguardUpdateMonitor = keyguardUpdateMonitor;
-        mKeyguardInteractor = keyguardInteractor;
-        mJavaAdapter = javaAdapter;
-    }
-
-    @Override
-    protected void start() {
-        updateState();
-        mKeyguardStateController.addCallback(mKeyguardStateCallback);
-        mKeyguardUpdateMonitor.registerCallback(mKeyguardUpdateCallback);
-        mWakefulnessLifecycle.addObserver(mWakefulnessObserver);
-        mAnyDozeListenerJob = mJavaAdapter.alwaysCollectFlow(
-                mKeyguardInteractor.getDozeTransitionModel(), dozeModel -> {
-                    mAnyDoze = !DozeStateModel.Companion.isDozeOff(dozeModel.getTo());
-                    updateState();
-                });
-    }
-
-    @Override
-    protected void stop() {
-        mKeyguardStateController.removeCallback(mKeyguardStateCallback);
-        mKeyguardUpdateMonitor.removeCallback(mKeyguardUpdateCallback);
-        mWakefulnessLifecycle.removeObserver(mWakefulnessObserver);
-        mAnyDozeListenerJob.cancel(null);
-    }
-
-    @Override
-    public int getStartStrategy() {
-        return START_EAGERLY;
-    }
-
-    private void updateState() {
-        final boolean asleep = mWakefulnessLifecycle.getWakefulness() == WAKEFULNESS_ASLEEP;
-        // Doze/AoD is also a dream, but we should never override it with low light as to the user
-        // it's totally unrelated.
-        updateCondition(!mAnyDoze && (asleep || mKeyguardStateController.isShowing()
-                || mKeyguardUpdateMonitor.isDreaming()));
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.kt b/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.kt
new file mode 100644
index 0000000..70dce2e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/communal/DeviceInactiveCondition.kt
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.communal
+
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyguard.WakefulnessLifecycle
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
+import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff
+import com.android.systemui.keyguard.shared.model.DozeTransitionModel
+import com.android.systemui.shared.condition.Condition
+import com.android.systemui.statusbar.policy.KeyguardStateController
+import com.android.systemui.util.kotlin.JavaAdapter
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Job
+import kotlinx.coroutines.launch
+
+/**
+ * Condition which estimates device inactivity in order to avoid launching a full-screen activity
+ * while the user is actively using the device.
+ */
+class DeviceInactiveCondition
+@Inject
+constructor(
+    @Application private val applicationScope: CoroutineScope,
+    @Background backgroundScope: CoroutineScope,
+    private val keyguardStateController: KeyguardStateController,
+    private val wakefulnessLifecycle: WakefulnessLifecycle,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
+    private val keyguardInteractor: KeyguardInteractor,
+    private val javaAdapter: JavaAdapter,
+) : Condition(backgroundScope) {
+    private var anyDozeListenerJob: Job? = null
+    private var anyDoze = false
+    private val keyguardStateCallback: KeyguardStateController.Callback =
+        object : KeyguardStateController.Callback {
+            override fun onKeyguardShowingChanged() {
+                updateState()
+            }
+        }
+    private val wakefulnessObserver: WakefulnessLifecycle.Observer =
+        object : WakefulnessLifecycle.Observer {
+            override fun onStartedGoingToSleep() {
+                updateState()
+            }
+        }
+    private val keyguardUpdateCallback: KeyguardUpdateMonitorCallback =
+        object : KeyguardUpdateMonitorCallback() {
+            override fun onDreamingStateChanged(dreaming: Boolean) {
+                updateState()
+            }
+        }
+
+    override suspend fun start() {
+        updateState()
+        keyguardStateController.addCallback(keyguardStateCallback)
+
+        // Keyguard update monitor callbacks must be registered on the main thread
+        applicationScope.launch { keyguardUpdateMonitor.registerCallback(keyguardUpdateCallback) }
+        wakefulnessLifecycle.addObserver(wakefulnessObserver)
+        anyDozeListenerJob =
+            javaAdapter.alwaysCollectFlow(keyguardInteractor.dozeTransitionModel) {
+                dozeModel: DozeTransitionModel ->
+                anyDoze = !isDozeOff(dozeModel.to)
+                updateState()
+            }
+    }
+
+    override fun stop() {
+        keyguardStateController.removeCallback(keyguardStateCallback)
+        keyguardUpdateMonitor.removeCallback(keyguardUpdateCallback)
+        wakefulnessLifecycle.removeObserver(wakefulnessObserver)
+        anyDozeListenerJob?.cancel(null)
+    }
+
+    override val startStrategy: Int
+        get() = START_EAGERLY
+
+    private fun updateState() {
+        val asleep = wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP
+        // Doze/AoD is also a dream, but we should never override it with low light as to the user
+        // it's totally unrelated.
+        updateCondition(
+            !anyDoze &&
+                (asleep || keyguardStateController.isShowing || keyguardUpdateMonitor.isDreaming)
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
index 6f688d1..42a345b 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/data/repository/CommunalSettingsRepository.kt
@@ -32,6 +32,7 @@
 import com.android.systemui.communal.data.repository.CommunalSettingsRepositoryModule.Companion.DEFAULT_BACKGROUND_TYPE
 import com.android.systemui.communal.shared.model.CommunalBackgroundType
 import com.android.systemui.communal.shared.model.WhenToDream
+import com.android.systemui.communal.shared.model.WhenToStartHub
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
@@ -64,6 +65,12 @@
      */
     fun getWhenToDreamState(user: UserInfo): Flow<WhenToDream>
 
+    /**
+     * Returns a[WhenToStartHub] for the specified user, indicating what state the device should be
+     * in to automatically display the hub.
+     */
+    fun getWhenToStartHubState(user: UserInfo): Flow<WhenToStartHub>
+
     /** Returns whether glanceable hub is enabled by the current user. */
     fun getSettingEnabledByUser(user: UserInfo): Flow<Boolean>
 
@@ -124,6 +131,10 @@
         resources.getBoolean(com.android.internal.R.bool.config_dreamsActivatedOnPosturedByDefault)
     }
 
+    private val whenToStartHubByDefault by lazy {
+        resources.getInteger(com.android.internal.R.integer.config_whenToStartHubModeDefault)
+    }
+
     private val _suppressionReasons =
         MutableStateFlow<List<SuppressionReason>>(
             // Suppress hub by default until we get an initial update.
@@ -195,6 +206,31 @@
             }
             .flowOn(bgDispatcher)
 
+    override fun getWhenToStartHubState(user: UserInfo): Flow<WhenToStartHub> =
+        secureSettings
+            .observerFlow(
+                userId = user.id,
+                names = arrayOf(Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB),
+            )
+            .emitOnStart()
+            .map {
+                when (
+                    secureSettings.getIntForUser(
+                        Settings.Secure.WHEN_TO_START_GLANCEABLE_HUB,
+                        whenToStartHubByDefault,
+                        user.id,
+                    )
+                ) {
+                    Settings.Secure.GLANCEABLE_HUB_START_NEVER -> WhenToStartHub.NEVER
+                    Settings.Secure.GLANCEABLE_HUB_START_CHARGING -> WhenToStartHub.WHILE_CHARGING
+                    Settings.Secure.GLANCEABLE_HUB_START_CHARGING_UPRIGHT ->
+                        WhenToStartHub.WHILE_CHARGING_AND_POSTURED
+                    Settings.Secure.GLANCEABLE_HUB_START_DOCKED -> WhenToStartHub.WHILE_DOCKED
+                    else -> WhenToStartHub.NEVER
+                }
+            }
+            .flowOn(bgDispatcher)
+
     override fun getAllowedByDevicePolicy(user: UserInfo): Flow<Boolean> =
         broadcastDispatcher
             .broadcastFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt
index 51df333..20bfabd 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalAutoOpenInteractor.kt
@@ -22,7 +22,7 @@
 import com.android.systemui.communal.data.model.FEATURE_MANUAL_OPEN
 import com.android.systemui.communal.data.model.SuppressionReason
 import com.android.systemui.communal.posturing.domain.interactor.PosturingInteractor
-import com.android.systemui.communal.shared.model.WhenToDream
+import com.android.systemui.communal.shared.model.WhenToStartHub
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dock.DockManager
@@ -49,17 +49,17 @@
     @Named(SWIPE_TO_HUB) private val allowSwipeAlways: Boolean,
 ) {
     val shouldAutoOpen: Flow<Boolean> =
-        communalSettingsInteractor.whenToDream
-            .flatMapLatestConflated { whenToDream ->
-                when (whenToDream) {
-                    WhenToDream.WHILE_CHARGING -> batteryInteractor.isDevicePluggedIn
-                    WhenToDream.WHILE_DOCKED -> {
+        communalSettingsInteractor.whenToStartHub
+            .flatMapLatestConflated { whenToStartHub ->
+                when (whenToStartHub) {
+                    WhenToStartHub.WHILE_CHARGING -> batteryInteractor.isDevicePluggedIn
+                    WhenToStartHub.WHILE_DOCKED -> {
                         allOf(batteryInteractor.isDevicePluggedIn, dockManager.retrieveIsDocked())
                     }
-                    WhenToDream.WHILE_POSTURED -> {
+                    WhenToStartHub.WHILE_CHARGING_AND_POSTURED -> {
                         allOf(batteryInteractor.isDevicePluggedIn, posturingInteractor.postured)
                     }
-                    WhenToDream.NEVER -> flowOf(false)
+                    WhenToStartHub.NEVER -> flowOf(false)
                 }
             }
             .flowOn(backgroundContext)
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
index 0d7a2d9..cf51fa1 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalSettingsInteractor.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.communal.domain.interactor
 
 import android.content.pm.UserInfo
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import com.android.systemui.communal.data.model.FEATURE_AUTO_OPEN
 import com.android.systemui.communal.data.model.FEATURE_ENABLED
 import com.android.systemui.communal.data.model.FEATURE_MANUAL_OPEN
@@ -25,10 +24,12 @@
 import com.android.systemui.communal.data.repository.CommunalSettingsRepository
 import com.android.systemui.communal.shared.model.CommunalBackgroundType
 import com.android.systemui.communal.shared.model.WhenToDream
+import com.android.systemui.communal.shared.model.WhenToStartHub
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.user.domain.interactor.SelectedUserInteractor
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
 import java.util.concurrent.Executor
 import javax.inject.Inject
@@ -79,6 +80,12 @@
             repository.getWhenToDreamState(user)
         }
 
+    /** When to automatically start hub for the currently selected user. */
+    val whenToStartHub: Flow<WhenToStartHub> =
+        userInteractor.selectedUserInfo.flatMapLatest { user ->
+            repository.getWhenToStartHubState(user)
+        }
+
     /** Whether communal hub is allowed by device policy for the current user */
     val allowedForCurrentUserByDevicePolicy: Flow<Boolean> =
         userInteractor.selectedUserInfo.flatMapLatestConflated { user ->
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt b/packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt
similarity index 71%
copy from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt
copy to packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt
index 260729b..be89fda 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/shared/model/WhenToStartHub.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,6 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package com.android.systemui.communal.shared.model
 
-@JvmInline value class IssueRecordingModel(val isRecording: Boolean)
+enum class WhenToStartHub {
+    NEVER,
+    WHILE_CHARGING,
+    WHILE_CHARGING_AND_POSTURED,
+    WHILE_DOCKED,
+}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
index 756edb3..5a4b0b0 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/CommunalViewModel.kt
@@ -229,7 +229,7 @@
             MutableStateFlow(false)
         }
 
-    val blurRadiusPx: Float = blurConfig.maxBlurRadiusPx / 2.0f
+    val blurRadiusPx: Float = blurConfig.maxBlurRadiusPx
 
     init {
         // Initialize our media host for the UMO. This only needs to happen once and must be done
diff --git a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt
index 06a14ea..440c300 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.communal.widgets
 
+import android.appwidget.AppWidgetProviderInfo
 import com.android.systemui.CoreStartable
 import com.android.systemui.communal.domain.interactor.CommunalInteractor
 import com.android.systemui.communal.domain.interactor.CommunalSettingsInteractor
@@ -101,6 +102,7 @@
                     val (_, isActive) = withPrev
                     // The validation is performed once the hub becomes active.
                     if (isActive) {
+                        removeNotLockscreenWidgets(widgets)
                         validateWidgetsAndDeleteOrphaned(widgets)
                     }
                 }
@@ -144,6 +146,19 @@
             }
         }
 
+    private fun removeNotLockscreenWidgets(widgets: List<CommunalWidgetContentModel>) {
+        widgets
+            .filter { widget ->
+                when (widget) {
+                    is CommunalWidgetContentModel.Available ->
+                        widget.providerInfo.widgetCategory and
+                            AppWidgetProviderInfo.WIDGET_CATEGORY_NOT_KEYGUARD != 0
+                    else -> false
+                }
+            }
+            .onEach { widget -> communalInteractor.deleteWidget(id = widget.appWidgetId) }
+    }
+
     /**
      * Ensure the existence of all associated users for widgets, and remove widgets belonging to
      * users who have been deleted.
diff --git a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
index 037b6fa..ba9f52b 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
@@ -51,8 +51,9 @@
 import com.android.systemui.qs.shared.model.TileCategory
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.DeviceControlsTile
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.res.R
 import dagger.Binds
 import dagger.BindsOptionalOf
 import dagger.Module
@@ -91,8 +92,8 @@
                 tileSpec = TileSpec.create(DEVICE_CONTROLS_SPEC),
                 uiConfig =
                     QSTileUIConfig.Resource(
-                        iconRes = com.android.systemui.res.R.drawable.controls_icon,
-                        labelRes = com.android.systemui.res.R.string.quick_controls_title
+                        iconRes = R.drawable.controls_icon,
+                        labelRes = R.string.quick_controls_title,
                     ),
                 instanceId = uiEventLogger.getNewInstanceId(),
                 category = TileCategory.UTILITIES,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt b/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt
index 39708a7..a8f218859 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/dagger/PerDisplayRepositoriesModule.kt
@@ -16,9 +16,10 @@
 
 package com.android.systemui.dagger
 
-import com.android.systemui.display.data.repository.DefaultDisplayOnlyInstanceRepositoryImpl
-import com.android.systemui.display.data.repository.PerDisplayInstanceRepositoryImpl
-import com.android.systemui.display.data.repository.PerDisplayRepository
+import com.android.app.displaylib.DefaultDisplayOnlyInstanceRepositoryImpl
+import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
+import com.android.app.displaylib.PerDisplayRepository
+import com.android.systemui.display.data.repository.PerDisplayCoroutineScopeRepositoryModule
 import com.android.systemui.model.SysUIStateInstanceProvider
 import com.android.systemui.model.SysUiState
 import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
@@ -26,7 +27,7 @@
 import dagger.Provides
 
 /** This module is meant to contain all the code to create the various [PerDisplayRepository<>]. */
-@Module
+@Module(includes = [PerDisplayCoroutineScopeRepositoryModule::class])
 class PerDisplayRepositoriesModule {
 
     @SysUISingleton
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
index f08126a..edee64e 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIModule.java
@@ -65,7 +65,7 @@
 import com.android.systemui.demomode.dagger.DemoModeModule;
 import com.android.systemui.deviceentry.DeviceEntryModule;
 import com.android.systemui.display.DisplayModule;
-import com.android.systemui.display.data.repository.PerDisplayRepository;
+import com.android.app.displaylib.PerDisplayRepository;
 import com.android.systemui.doze.dagger.DozeComponent;
 import com.android.systemui.dreams.dagger.DreamModule;
 import com.android.systemui.flags.FeatureFlags;
@@ -97,11 +97,11 @@
 import com.android.systemui.plugins.BcSmartspaceDataPlugin;
 import com.android.systemui.privacy.PrivacyModule;
 import com.android.systemui.process.condition.SystemProcessCondition;
-import com.android.systemui.qrcodescanner.dagger.QRCodeScannerModule;
 import com.android.systemui.qs.FgsManagerController;
 import com.android.systemui.qs.FgsManagerControllerImpl;
 import com.android.systemui.qs.QSFragmentStartableModule;
 import com.android.systemui.qs.footer.dagger.FooterActionsModule;
+import com.android.systemui.qs.tiles.impl.qr.ui.model.QRCodeScannerModule;
 import com.android.systemui.recents.Recents;
 import com.android.systemui.recordissue.RecordIssueModule;
 import com.android.systemui.retail.RetailModeModule;
diff --git a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
index 9b181be..32b69e5 100644
--- a/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/DisplayModule.kt
@@ -16,18 +16,26 @@
 
 package com.android.systemui.display
 
+import android.hardware.display.DisplayManager
+import android.os.Handler
+import com.android.app.displaylib.DisplayLibBackground
+import com.android.app.displaylib.DisplayLibComponent
+import com.android.app.displaylib.PerDisplayRepository
+import com.android.app.displaylib.createDisplayLibComponent
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.repository.DeviceStateRepository
 import com.android.systemui.display.data.repository.DeviceStateRepositoryImpl
 import com.android.systemui.display.data.repository.DisplayRepository
 import com.android.systemui.display.data.repository.DisplayRepositoryImpl
-import com.android.systemui.display.data.repository.DisplayScopeRepository
-import com.android.systemui.display.data.repository.DisplayScopeRepositoryImpl
 import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
 import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepositoryImpl
+import com.android.systemui.display.data.repository.DisplaysWithDecorationsRepository
+import com.android.systemui.display.data.repository.DisplaysWithDecorationsRepositoryImpl
 import com.android.systemui.display.data.repository.FocusedDisplayRepository
 import com.android.systemui.display.data.repository.FocusedDisplayRepositoryImpl
+import com.android.systemui.display.data.repository.PerDisplayRepoDumpHelper
 import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractor
 import com.android.systemui.display.domain.interactor.ConnectedDisplayInteractorImpl
 import com.android.systemui.display.domain.interactor.DisplayWindowPropertiesInteractorModule
@@ -40,9 +48,11 @@
 import dagger.Provides
 import dagger.multibindings.ClassKey
 import dagger.multibindings.IntoMap
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
 
 /** Module binding display related classes. */
-@Module(includes = [DisplayWindowPropertiesInteractorModule::class])
+@Module(includes = [DisplayWindowPropertiesInteractorModule::class, DisplayLibModule::class])
 interface DisplayModule {
     @Binds
     fun bindConnectedDisplayInteractor(
@@ -66,28 +76,24 @@
         focusedDisplayRepository: FocusedDisplayRepositoryImpl
     ): FocusedDisplayRepository
 
-    @Binds fun displayScopeRepository(impl: DisplayScopeRepositoryImpl): DisplayScopeRepository
-
     @Binds
     fun displayWindowPropertiesRepository(
         impl: DisplayWindowPropertiesRepositoryImpl
     ): DisplayWindowPropertiesRepository
 
-    companion object {
-        @Provides
-        @SysUISingleton
-        @IntoMap
-        @ClassKey(DisplayScopeRepositoryImpl::class)
-        fun displayScopeRepoCoreStartable(
-            repoImplLazy: Lazy<DisplayScopeRepositoryImpl>
-        ): CoreStartable {
-            return if (StatusBarConnectedDisplays.isEnabled) {
-                repoImplLazy.get()
-            } else {
-                CoreStartable.NOP
-            }
-        }
+    @Binds
+    fun displaysWithDecorationsRepository(
+        impl: DisplaysWithDecorationsRepositoryImpl
+    ): DisplaysWithDecorationsRepository
 
+    @Binds
+    fun dumpRegistrationLambda(helper: PerDisplayRepoDumpHelper): PerDisplayRepository.InitCallback
+
+    @Binds
+    @DisplayLibBackground
+    fun bindDisplayLibBackground(@Background bgScope: CoroutineScope): CoroutineScope
+
+    companion object {
         @Provides
         @SysUISingleton
         @IntoMap
@@ -103,3 +109,31 @@
         }
     }
 }
+
+/** Module to bind the DisplayRepository from displaylib to the systemui dagger graph. */
+@Module
+object DisplayLibModule {
+    @Provides
+    @SysUISingleton
+    fun displayLibComponent(
+        displayManager: DisplayManager,
+        @Background backgroundHandler: Handler,
+        @Background bgApplicationScope: CoroutineScope,
+        @Background backgroundCoroutineDispatcher: CoroutineDispatcher,
+    ): DisplayLibComponent {
+        return createDisplayLibComponent(
+            displayManager,
+            backgroundHandler,
+            bgApplicationScope,
+            backgroundCoroutineDispatcher,
+        )
+    }
+
+    @Provides
+    @SysUISingleton
+    fun providesDisplayRepositoryFromLib(
+        displayLibComponent: DisplayLibComponent
+    ): com.android.app.displaylib.DisplayRepository {
+        return displayLibComponent.displayRepository
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/DisplayEvent.kt b/packages/SystemUI/src/com/android/systemui/display/data/DisplayEvent.kt
deleted file mode 100644
index 626a68f..0000000
--- a/packages/SystemUI/src/com/android/systemui/display/data/DisplayEvent.kt
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.display.data
-
-sealed interface DisplayEvent {
-    val displayId: Int
-    data class Added(override val displayId: Int) : DisplayEvent
-    data class Removed(override val displayId: Int) : DisplayEvent
-    data class Changed(override val displayId: Int) : DisplayEvent
-}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
index 101e8cc..01bbf2d 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayRepository.kt
@@ -16,485 +16,25 @@
 
 package com.android.systemui.display.data.repository
 
-import android.annotation.SuppressLint
-import android.hardware.display.DisplayManager
-import android.hardware.display.DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED
-import android.hardware.display.DisplayManager.DisplayListener
-import android.hardware.display.DisplayManager.EVENT_TYPE_DISPLAY_ADDED
-import android.hardware.display.DisplayManager.EVENT_TYPE_DISPLAY_CHANGED
-import android.hardware.display.DisplayManager.EVENT_TYPE_DISPLAY_REMOVED
-import android.os.Handler
-import android.util.Log
-import android.view.Display
-import android.view.IWindowManager
 import com.android.app.displaylib.DisplayRepository as DisplayRepositoryFromLib
-import com.android.app.tracing.FlowTracing.traceEach
-import com.android.app.tracing.traceSection
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.display.data.DisplayEvent
-import com.android.systemui.statusbar.CommandQueue
-import com.android.systemui.util.Compile
-import com.android.systemui.util.kotlin.pairwiseBy
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import javax.inject.Inject
-import kotlinx.coroutines.CoroutineDispatcher
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.asFlow
-import kotlinx.coroutines.flow.callbackFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.filter
-import kotlinx.coroutines.flow.filterIsInstance
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOn
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.merge
-import kotlinx.coroutines.flow.onEach
-import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.flow.scan
-import kotlinx.coroutines.flow.stateIn
 
-/** Repository for providing access to display related information and events. */
-interface DisplayRepository : DisplayRepositoryFromLib {
-    /** Display change event indicating a change to the given displayId has occurred. */
-    val displayChangeEvent: Flow<Int>
-
-    /** Display addition event indicating a new display has been added. */
-    val displayAdditionEvent: Flow<Display?>
-
-    /** Display removal event indicating a display has been removed. */
-    val displayRemovalEvent: Flow<Int>
-
-    /** A [StateFlow] that maintains a set of display IDs that should have system decorations. */
-    val displayIdsWithSystemDecorations: StateFlow<Set<Int>>
-
-    /**
-     * Provides the current set of display ids.
-     *
-     * Note that it is preferred to use this instead of [displays] if only the
-     * [Display.getDisplayId] is needed.
-     */
-    val displayIds: StateFlow<Set<Int>>
-
-    /**
-     * Pending display id that can be enabled/disabled.
-     *
-     * When `null`, it means there is no pending display waiting to be enabled.
-     */
-    val pendingDisplay: Flow<PendingDisplay?>
-
-    /** Whether the default display is currently off. */
-    val defaultDisplayOff: Flow<Boolean>
-
-    /**
-     * Given a display ID int, return the corresponding Display object, or null if none exist.
-     *
-     * This method is guaranteed to not result in any binder call.
-     */
-    fun getDisplay(displayId: Int): Display? =
-        displays.value.firstOrNull { it.displayId == displayId }
-
-    /** Represents a connected display that has not been enabled yet. */
-    interface PendingDisplay {
-        /** Id of the pending display. */
-        val id: Int
-
-        /** Enables the display, making it available to the system. */
-        suspend fun enable()
-
-        /**
-         * Ignores the pending display. When called, this specific display id doesn't appear as
-         * pending anymore until the display is disconnected and reconnected again.
-         */
-        suspend fun ignore()
-
-        /** Disables the display, making it unavailable to the system. */
-        suspend fun disable()
-    }
-}
+/**
+ * Repository for providing access to display related information and events.
+ *
+ * This is now just an interface that extends [DisplayRepositoryFromLib] to avoid changing all the
+ * imports in sysui using this interface.
+ */
+interface DisplayRepository : DisplayRepositoryFromLib, DisplaysWithDecorationsRepository
 
 @SysUISingleton
-@SuppressLint("SharedFlowCreation")
 class DisplayRepositoryImpl
 @Inject
 constructor(
-    private val displayManager: DisplayManager,
-    private val commandQueue: CommandQueue,
-    private val windowManager: IWindowManager,
-    @Background backgroundHandler: Handler,
-    @Background bgApplicationScope: CoroutineScope,
-    @Background backgroundCoroutineDispatcher: CoroutineDispatcher,
-) : DisplayRepository {
-    private val allDisplayEvents: Flow<DisplayEvent> =
-        conflatedCallbackFlow {
-                val callback =
-                    object : DisplayListener {
-                        override fun onDisplayAdded(displayId: Int) {
-                            trySend(DisplayEvent.Added(displayId))
-                        }
-
-                        override fun onDisplayRemoved(displayId: Int) {
-                            trySend(DisplayEvent.Removed(displayId))
-                        }
-
-                        override fun onDisplayChanged(displayId: Int) {
-                            trySend(DisplayEvent.Changed(displayId))
-                        }
-                    }
-                displayManager.registerDisplayListener(
-                    callback,
-                    backgroundHandler,
-                    EVENT_TYPE_DISPLAY_ADDED or
-                        EVENT_TYPE_DISPLAY_CHANGED or
-                        EVENT_TYPE_DISPLAY_REMOVED,
-                )
-                awaitClose { displayManager.unregisterDisplayListener(callback) }
-            }
-            .onStart { emit(DisplayEvent.Changed(Display.DEFAULT_DISPLAY)) }
-            .debugLog("allDisplayEvents")
-            .flowOn(backgroundCoroutineDispatcher)
-
-    override val displayChangeEvent: Flow<Int> =
-        allDisplayEvents.filterIsInstance<DisplayEvent.Changed>().map { event -> event.displayId }
-
-    override val displayRemovalEvent: Flow<Int> =
-        allDisplayEvents.filterIsInstance<DisplayEvent.Removed>().map { it.displayId }
-
-    // This is necessary because there might be multiple displays, and we could
-    // have missed events for those added before this process or flow started.
-    // Note it causes a binder call from the main thread (it's traced).
-    private val initialDisplays: Set<Display> =
-        traceSection("$TAG#initialDisplays") { displayManager.displays?.toSet() ?: emptySet() }
-    private val initialDisplayIds = initialDisplays.map { display -> display.displayId }.toSet()
-
-    /** Propagate to the listeners only enabled displays */
-    private val enabledDisplayIds: StateFlow<Set<Int>> =
-        allDisplayEvents
-            .scan(initial = initialDisplayIds) { previousIds: Set<Int>, event: DisplayEvent ->
-                val id = event.displayId
-                when (event) {
-                    is DisplayEvent.Removed -> previousIds - id
-                    is DisplayEvent.Added,
-                    is DisplayEvent.Changed -> previousIds + id
-                }
-            }
-            .distinctUntilChanged()
-            .debugLog("enabledDisplayIds")
-            .stateIn(bgApplicationScope, SharingStarted.WhileSubscribed(), initialDisplayIds)
-
-    private val defaultDisplay by lazy {
-        getDisplayFromDisplayManager(Display.DEFAULT_DISPLAY)
-            ?: error("Unable to get default display.")
-    }
-
-    /**
-     * Represents displays that went though the [DisplayListener.onDisplayAdded] callback.
-     *
-     * Those are commonly the ones provided by [DisplayManager.getDisplays] by default.
-     */
-    private val enabledDisplays: StateFlow<Set<Display>> =
-        enabledDisplayIds
-            .mapElementsLazily { displayId -> getDisplayFromDisplayManager(displayId) }
-            .onEach {
-                if (it.isEmpty()) Log.wtf(TAG, "No enabled displays. This should never happen.")
-            }
-            .flowOn(backgroundCoroutineDispatcher)
-            .debugLog("enabledDisplays")
-            .stateIn(
-                bgApplicationScope,
-                started = SharingStarted.WhileSubscribed(),
-                // This triggers a single binder call on the UI thread per process. The
-                // alternative would be to use sharedFlows, but they are prohibited due to
-                // performance concerns.
-                // Ultimately, this is a trade-off between a one-time UI thread binder call and
-                // the constant overhead of sharedFlows.
-                initialValue = initialDisplays,
-            )
-
-    /**
-     * Represents displays that went though the [DisplayListener.onDisplayAdded] callback.
-     *
-     * Those are commonly the ones provided by [DisplayManager.getDisplays] by default.
-     */
-    override val displays: StateFlow<Set<Display>> = enabledDisplays
-
-    override val displayIds: StateFlow<Set<Int>> = enabledDisplayIds
-
-    /**
-     * Implementation that maps from [displays], instead of [allDisplayEvents] for 2 reasons:
-     * 1. Guarantee that it emits __after__ [displays] emitted. This way it is guaranteed that
-     *    calling [getDisplay] for the newly added display will be non-null.
-     * 2. Reuse the existing instance of [Display] without a new call to [DisplayManager].
-     */
-    override val displayAdditionEvent: Flow<Display?> =
-        displays
-            .pairwiseBy { previousDisplays, currentDisplays -> currentDisplays - previousDisplays }
-            .flatMapLatest { it.asFlow() }
-
-    val _ignoredDisplayIds = MutableStateFlow<Set<Int>>(emptySet())
-    private val ignoredDisplayIds: Flow<Set<Int>> = _ignoredDisplayIds.debugLog("ignoredDisplayIds")
-
-    private fun getInitialConnectedDisplays(): Set<Int> =
-        traceSection("$TAG#getInitialConnectedDisplays") {
-            displayManager
-                .getDisplays(DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED)
-                .map { it.displayId }
-                .toSet()
-                .also {
-                    if (DEBUG) {
-                        Log.d(TAG, "getInitialConnectedDisplays: $it")
-                    }
-                }
-        }
-
-    /* keeps connected displays until they are disconnected. */
-    private val connectedDisplayIds: StateFlow<Set<Int>> =
-        conflatedCallbackFlow {
-                val connectedIds = getInitialConnectedDisplays().toMutableSet()
-                val callback =
-                    object : DisplayConnectionListener {
-                        override fun onDisplayConnected(id: Int) {
-                            if (DEBUG) {
-                                Log.d(TAG, "display with id=$id connected.")
-                            }
-                            connectedIds += id
-                            _ignoredDisplayIds.value -= id
-                            trySend(connectedIds.toSet())
-                        }
-
-                        override fun onDisplayDisconnected(id: Int) {
-                            connectedIds -= id
-                            if (DEBUG) {
-                                Log.d(TAG, "display with id=$id disconnected.")
-                            }
-                            _ignoredDisplayIds.value -= id
-                            trySend(connectedIds.toSet())
-                        }
-                    }
-                trySend(connectedIds.toSet())
-                displayManager.registerDisplayListener(
-                    callback,
-                    backgroundHandler,
-                    /* eventFlags */ 0,
-                    DisplayManager.PRIVATE_EVENT_TYPE_DISPLAY_CONNECTION_CHANGED,
-                )
-                awaitClose { displayManager.unregisterDisplayListener(callback) }
-            }
-            .distinctUntilChanged()
-            .debugLog("connectedDisplayIds")
-            .stateIn(
-                bgApplicationScope,
-                started = SharingStarted.WhileSubscribed(),
-                // The initial value is set to empty, but connected displays are gathered as soon as
-                // the flow starts being collected. This is to ensure the call to get displays (an
-                // IPC) happens in the background instead of when this object
-                // is instantiated.
-                initialValue = emptySet(),
-            )
-
-    private val connectedExternalDisplayIds: Flow<Set<Int>> =
-        connectedDisplayIds
-            .map { connectedDisplayIds ->
-                traceSection("$TAG#filteringExternalDisplays") {
-                    connectedDisplayIds
-                        .filter { id -> getDisplayType(id) == Display.TYPE_EXTERNAL }
-                        .toSet()
-                }
-            }
-            .flowOn(backgroundCoroutineDispatcher)
-            .debugLog("connectedExternalDisplayIds")
-
-    private fun getDisplayType(displayId: Int): Int? =
-        traceSection("$TAG#getDisplayType") { displayManager.getDisplay(displayId)?.type }
-
-    private fun getDisplayFromDisplayManager(displayId: Int): Display? =
-        traceSection("$TAG#getDisplay") { displayManager.getDisplay(displayId) }
-
-    /**
-     * Pending displays are the ones connected, but not enabled and not ignored.
-     *
-     * A connected display is ignored after the user makes the decision to use it or not. For now,
-     * the initial decision from the user is final and not reversible.
-     */
-    private val pendingDisplayIds: Flow<Set<Int>> =
-        combine(enabledDisplayIds, connectedExternalDisplayIds, ignoredDisplayIds) {
-                enabledDisplaysIds,
-                connectedExternalDisplayIds,
-                ignoredDisplayIds ->
-                if (DEBUG) {
-                    Log.d(
-                        TAG,
-                        "combining enabled=$enabledDisplaysIds, " +
-                            "connectedExternalDisplayIds=$connectedExternalDisplayIds, " +
-                            "ignored=$ignoredDisplayIds",
-                    )
-                }
-                connectedExternalDisplayIds - enabledDisplaysIds - ignoredDisplayIds
-            }
-            .debugLog("allPendingDisplayIds")
-
-    /** Which display id should be enabled among the pending ones. */
-    private val pendingDisplayId: Flow<Int?> =
-        pendingDisplayIds.map { it.maxOrNull() }.distinctUntilChanged().debugLog("pendingDisplayId")
-
-    override val pendingDisplay: Flow<DisplayRepository.PendingDisplay?> =
-        pendingDisplayId
-            .map { displayId ->
-                val id = displayId ?: return@map null
-                object : DisplayRepository.PendingDisplay {
-                    override val id = id
-
-                    override suspend fun enable() {
-                        traceSection("DisplayRepository#enable($id)") {
-                            if (DEBUG) {
-                                Log.d(TAG, "Enabling display with id=$id")
-                            }
-                            displayManager.enableConnectedDisplay(id)
-                        }
-                        // After the display has been enabled, it is automatically ignored.
-                        ignore()
-                    }
-
-                    override suspend fun ignore() {
-                        traceSection("DisplayRepository#ignore($id)") {
-                            _ignoredDisplayIds.value += id
-                        }
-                    }
-
-                    override suspend fun disable() {
-                        ignore()
-                        traceSection("DisplayRepository#disable($id)") {
-                            if (DEBUG) {
-                                Log.d(TAG, "Disabling display with id=$id")
-                            }
-                            displayManager.disableConnectedDisplay(id)
-                        }
-                    }
-                }
-            }
-            .debugLog("pendingDisplay")
-
-    override val defaultDisplayOff: Flow<Boolean> =
-        displayChangeEvent
-            .filter { it == Display.DEFAULT_DISPLAY }
-            .map { defaultDisplay.state == Display.STATE_OFF }
-            .distinctUntilChanged()
-
-    private fun <T> Flow<T>.debugLog(flowName: String): Flow<T> {
-        return if (DEBUG) {
-            traceEach(flowName, logcat = true, traceEmissionCount = true)
-        } else {
-            this
-        }
-    }
-
-    /**
-     * Maps a set of T to a set of V, minimizing the number of `createValue` calls taking into
-     * account the diff between each root flow emission.
-     *
-     * This is needed to minimize the number of [getDisplayFromDisplayManager] in this class. Note
-     * that if the [createValue] returns a null element, it will not be added in the output set.
-     */
-    private fun <T, V> Flow<Set<T>>.mapElementsLazily(createValue: (T) -> V?): Flow<Set<V>> {
-        data class State<T, V>(
-            val previousSet: Set<T>,
-            // Caches T values from the previousSet that were already converted to V
-            val valueMap: Map<T, V>,
-            val resultSet: Set<V>,
-        )
-
-        val emptyInitialState = State(emptySet<T>(), emptyMap(), emptySet<V>())
-        return this.scan(emptyInitialState) { state, currentSet ->
-                if (currentSet == state.previousSet) {
-                    state
-                } else {
-                    val removed = state.previousSet - currentSet
-                    val added = currentSet - state.previousSet
-                    val newMap = state.valueMap.toMutableMap()
-
-                    added.forEach { key -> createValue(key)?.let { newMap[key] = it } }
-                    removed.forEach { key -> newMap.remove(key) }
-
-                    val resultSet = newMap.values.toSet()
-                    State(currentSet, newMap, resultSet)
-                }
-            }
-            .filter { it != emptyInitialState }
-            .map { it.resultSet }
-    }
-
-    private val decorationEvents: Flow<Event> = callbackFlow {
-        val callback =
-            object : CommandQueue.Callbacks {
-                override fun onDisplayAddSystemDecorations(displayId: Int) {
-                    trySend(Event.Add(displayId))
-                }
-
-                override fun onDisplayRemoveSystemDecorations(displayId: Int) {
-                    trySend(Event.Remove(displayId))
-                }
-            }
-        commandQueue.addCallback(callback)
-        awaitClose { commandQueue.removeCallback(callback) }
-    }
-
-    private val initialDisplayIdsWithDecorations: Set<Int> =
-        displayIds.value.filter { windowManager.shouldShowSystemDecors(it) }.toSet()
-
-    /**
-     * A [StateFlow] that maintains a set of display IDs that should have system decorations.
-     *
-     * Updates to the set are triggered by:
-     * - Adding displays via [CommandQueue.Callbacks.onDisplayAddSystemDecorations].
-     * - Removing displays via [CommandQueue.Callbacks.onDisplayRemoveSystemDecorations].
-     * - Removing displays via [displayRemovalEvent] emissions.
-     *
-     * The set is initialized with displays that qualify for system decorations based on
-     * [WindowManager.shouldShowSystemDecors].
-     */
-    override val displayIdsWithSystemDecorations: StateFlow<Set<Int>> =
-        merge(decorationEvents, displayRemovalEvent.map { Event.Remove(it) })
-            .scan(initialDisplayIdsWithDecorations) { displayIds: Set<Int>, event: Event ->
-                when (event) {
-                    is Event.Add -> displayIds + event.displayId
-                    is Event.Remove -> displayIds - event.displayId
-                }
-            }
-            .distinctUntilChanged()
-            .stateIn(
-                scope = bgApplicationScope,
-                started = SharingStarted.WhileSubscribed(),
-                initialValue = initialDisplayIdsWithDecorations,
-            )
-
-    private sealed class Event(val displayId: Int) {
-        class Add(displayId: Int) : Event(displayId)
-
-        class Remove(displayId: Int) : Event(displayId)
-    }
-
-    private companion object {
-        const val TAG = "DisplayRepository"
-        val DEBUG = Log.isLoggable(TAG, Log.DEBUG) || Compile.IS_DEBUG
-    }
-}
-
-/** Used to provide default implementations for all methods. */
-private interface DisplayConnectionListener : DisplayListener {
-
-    override fun onDisplayConnected(id: Int) {}
-
-    override fun onDisplayDisconnected(id: Int) {}
-
-    override fun onDisplayAdded(id: Int) {}
-
-    override fun onDisplayRemoved(id: Int) {}
-
-    override fun onDisplayChanged(id: Int) {}
-}
+    private val displayRepositoryFromLib: com.android.app.displaylib.DisplayRepository,
+    private val displaysWithDecorationsRepositoryImpl: DisplaysWithDecorationsRepository,
+) :
+    DisplayRepositoryFromLib by displayRepositoryFromLib,
+    DisplaysWithDecorationsRepository by displaysWithDecorationsRepositoryImpl,
+    DisplayRepository
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
index d912b6a..ac59b16 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplayScopeRepository.kt
@@ -17,60 +17,58 @@
 package com.android.systemui.display.data.repository
 
 import android.view.Display
-import com.android.systemui.CoreStartable
+import com.android.app.displaylib.PerDisplayInstanceProviderWithTeardown
+import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
+import com.android.app.displaylib.PerDisplayRepository
 import com.android.systemui.coroutines.newTracingContext
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
-import java.util.concurrent.ConcurrentHashMap
+import dagger.Module
+import dagger.Provides
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.cancel
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /**
- * Provides per display instances of [CoroutineScope]. These will remain active as long as the
- * display is connected, and automatically cancelled when the display is removed.
+ * Provides per display instances of [CoroutineScope].
+ *
+ * This is used to create a [PerDisplayRepository] of [CoroutineScope]
  */
-interface DisplayScopeRepository {
-    fun scopeForDisplay(displayId: Int): CoroutineScope
-}
-
 @SysUISingleton
-class DisplayScopeRepositoryImpl
+class DisplayScopeRepositoryInstanceProvider
 @Inject
 constructor(
     @Background private val backgroundApplicationScope: CoroutineScope,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
-    private val displayRepository: DisplayRepository,
-) : DisplayScopeRepository, CoreStartable {
+) : PerDisplayInstanceProviderWithTeardown<CoroutineScope> {
 
-    private val perDisplayScopes = ConcurrentHashMap<Int, CoroutineScope>()
-
-    override fun scopeForDisplay(displayId: Int): CoroutineScope {
-        return perDisplayScopes.computeIfAbsent(displayId) { createScopeForDisplay(displayId) }
-    }
-
-    override fun start() {
-        StatusBarConnectedDisplays.unsafeAssertInNewMode()
-        backgroundApplicationScope.launch {
-            displayRepository.displayRemovalEvent.collect { displayId ->
-                val scope = perDisplayScopes.remove(displayId)
-                scope?.cancel("Display $displayId has been removed.")
-            }
-        }
-    }
-
-    private fun createScopeForDisplay(displayId: Int): CoroutineScope {
+    override fun createInstance(displayId: Int): CoroutineScope {
         return if (displayId == Display.DEFAULT_DISPLAY) {
             // The default display is connected all the time, therefore we can optimise by reusing
             // the application scope, and don't need to create a new scope.
             backgroundApplicationScope
         } else {
-            CoroutineScope(
-                backgroundDispatcher + newTracingContext("DisplayScope$displayId")
-            )
+            CoroutineScope(backgroundDispatcher + newTracingContext("DisplayScope$displayId"))
         }
     }
+
+    override fun destroyInstance(instance: CoroutineScope) {
+        instance.cancel("DisplayContext has been cancelled.")
+    }
+}
+
+@Module
+object PerDisplayCoroutineScopeRepositoryModule {
+    @SysUISingleton
+    @Provides
+    fun provideDisplayCoroutineScopeRepository(
+        repositoryFactory: PerDisplayInstanceRepositoryImpl.Factory<CoroutineScope>,
+        instanceProvider: DisplayScopeRepositoryInstanceProvider,
+    ): PerDisplayRepository<CoroutineScope> {
+        return repositoryFactory.create(
+            debugName = "CoroutineScopePerDisplayRepo",
+            instanceProvider,
+        )
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplaysWithDecorationsRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplaysWithDecorationsRepository.kt
new file mode 100644
index 0000000..f4a2ed4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/DisplaysWithDecorationsRepository.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.display.data.repository
+
+import android.view.IWindowManager
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.CommandQueue
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.scan
+import kotlinx.coroutines.flow.stateIn
+
+/** Provides the displays with decorations. */
+interface DisplaysWithDecorationsRepository {
+    /** A [StateFlow] that maintains a set of display IDs that should have system decorations. */
+    val displayIdsWithSystemDecorations: StateFlow<Set<Int>>
+}
+
+@SysUISingleton
+class DisplaysWithDecorationsRepositoryImpl
+@Inject
+constructor(
+    private val commandQueue: CommandQueue,
+    private val windowManager: IWindowManager,
+    @Background bgApplicationScope: CoroutineScope,
+    displayRepository: com.android.app.displaylib.DisplayRepository,
+) : DisplaysWithDecorationsRepository {
+
+    private val decorationEvents: Flow<Event> = callbackFlow {
+        val callback =
+            object : CommandQueue.Callbacks {
+                override fun onDisplayAddSystemDecorations(displayId: Int) {
+                    trySend(Event.Add(displayId))
+                }
+
+                override fun onDisplayRemoveSystemDecorations(displayId: Int) {
+                    trySend(Event.Remove(displayId))
+                }
+            }
+        commandQueue.addCallback(callback)
+        awaitClose { commandQueue.removeCallback(callback) }
+    }
+
+    private val initialDisplayIdsWithDecorations: Set<Int> =
+        displayRepository.displayIds.value
+            .filter { windowManager.shouldShowSystemDecors(it) }
+            .toSet()
+
+    /**
+     * A [StateFlow] that maintains a set of display IDs that should have system decorations.
+     *
+     * Updates to the set are triggered by:
+     * - Adding displays via [CommandQueue.Callbacks.onDisplayAddSystemDecorations].
+     * - Removing displays via [CommandQueue.Callbacks.onDisplayRemoveSystemDecorations].
+     * - Removing displays via [displayRemovalEvent] emissions.
+     *
+     * The set is initialized with displays that qualify for system decorations based on
+     * [WindowManager.shouldShowSystemDecors].
+     */
+    override val displayIdsWithSystemDecorations: StateFlow<Set<Int>> =
+        merge(decorationEvents, displayRepository.displayRemovalEvent.map { Event.Remove(it) })
+            .scan(initialDisplayIdsWithDecorations) { displayIds: Set<Int>, event: Event ->
+                when (event) {
+                    is Event.Add -> displayIds + event.displayId
+                    is Event.Remove -> displayIds - event.displayId
+                }
+            }
+            .distinctUntilChanged()
+            .stateIn(
+                scope = bgApplicationScope,
+                started = SharingStarted.WhileSubscribed(),
+                initialValue = initialDisplayIdsWithDecorations,
+            )
+
+    private sealed class Event(val displayId: Int) {
+        class Add(displayId: Int) : Event(displayId)
+
+        class Remove(displayId: Int) : Event(displayId)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt
index a56710e..86c9d84c 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/FakePerDisplayRepository.kt
@@ -16,6 +16,9 @@
 
 package com.android.systemui.display.data.repository
 
+import com.android.app.displaylib.PerDisplayRepository
+
+// TODO b/401305290 - move to displaylib
 class FakePerDisplayRepository<T> : PerDisplayRepository<T> {
 
     private val instances = mutableMapOf<Int, T>()
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepoDumpHelper.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepoDumpHelper.kt
new file mode 100644
index 0000000..efbae5d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepoDumpHelper.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.display.data.repository
+
+import com.android.app.displaylib.PerDisplayRepository
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dump.DumpManager
+import com.android.systemui.dump.DumpableFromToString
+import javax.inject.Inject
+
+/** Helper class to register PerDisplayRepository in the dump manager in SystemUI. */
+@SysUISingleton
+class PerDisplayRepoDumpHelper @Inject constructor(private val dumpManager: DumpManager) :
+    PerDisplayRepository.InitCallback {
+    /**
+     * Registers PerDisplayRepository in the dump manager.
+     *
+     * The repository will be identified by the given debug name.
+     */
+    override fun onInit(debugName: String, instance: Any) {
+        dumpManager.registerNormalDumpable(
+            "PerDisplayRepository-$debugName",
+            DumpableFromToString(instance),
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt
deleted file mode 100644
index d1d0135..0000000
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayRepository.kt
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES 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.display.data.repository
-
-import android.util.Log
-import android.view.Display
-import com.android.app.tracing.coroutines.launchTraced as launch
-import com.android.app.tracing.traceSection
-import com.android.systemui.Dumpable
-import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.dump.DumpManager
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
-import java.io.PrintWriter
-import java.util.concurrent.ConcurrentHashMap
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.collectLatest
-
-/**
- * Used to create instances of type `T` for a specific display.
- *
- * This is useful for resources or objects that need to be managed independently for each connected
- * display (e.g., UI state, rendering contexts, or display-specific configurations).
- *
- * Note that in most cases this can be implemented by a simple `@AssistedFactory` with `displayId`
- * parameter
- *
- * ```kotlin
- * class SomeType @AssistedInject constructor(@Assisted displayId: Int,..)
- *      @AssistedFactory
- *      interface Factory {
- *         fun create(displayId: Int): SomeType
- *      }
- *  }
- * ```
- *
- * Then it can be used to create a [PerDisplayRepository] as follows:
- * ```kotlin
- * // Injected:
- * val repositoryFactory: PerDisplayRepositoryImpl.Factory
- * val instanceFactory: PerDisplayRepositoryImpl.Factory
- * // repository creation:
- * repositoryFactory.create(instanceFactory::create)
- * ```
- *
- * @see PerDisplayRepository For how to retrieve and manage instances created by this factory.
- */
-fun interface PerDisplayInstanceProvider<T> {
-    /** Creates an instance for a display. */
-    fun createInstance(displayId: Int): T?
-}
-
-/**
- * Extends [PerDisplayInstanceProvider], adding support for destroying the instance.
- *
- * This is useful for releasing resources associated with a display when it is disconnected or when
- * the per-display instance is no longer needed.
- */
-interface PerDisplayInstanceProviderWithTeardown<T> : PerDisplayInstanceProvider<T> {
-    /** Destroys a previously created instance of `T` forever. */
-    fun destroyInstance(instance: T)
-}
-
-/**
- * Provides access to per-display instances of type `T`.
- *
- * Acts as a repository, managing the caching and retrieval of instances created by a
- * [PerDisplayInstanceProvider]. It ensures that only one instance of `T` exists per display ID.
- */
-interface PerDisplayRepository<T> {
-    /** Gets the cached instance or create a new one for a given display. */
-    operator fun get(displayId: Int): T?
-
-    /** Debug name for this repository, mainly for tracing and logging. */
-    val debugName: String
-}
-
-/**
- * Default implementation of [PerDisplayRepository].
- *
- * This class manages a cache of per-display instances of type `T`, creating them using a provided
- * [PerDisplayInstanceProvider] and optionally tearing them down using a
- * [PerDisplayInstanceProviderWithTeardown] when displays are disconnected.
- *
- * It listens to the [DisplayRepository] to detect when displays are added or removed, and
- * automatically manages the lifecycle of the per-display instances.
- *
- * Note that this is a [PerDisplayStoreImpl] 2.0 that doesn't require [CoreStartable] bindings,
- * providing all args in the constructor.
- */
-class PerDisplayInstanceRepositoryImpl<T>
-@AssistedInject
-constructor(
-    @Assisted override val debugName: String,
-    @Assisted private val instanceProvider: PerDisplayInstanceProvider<T>,
-    @Background private val backgroundApplicationScope: CoroutineScope,
-    private val displayRepository: DisplayRepository,
-    private val dumpManager: DumpManager,
-) : PerDisplayRepository<T>, Dumpable {
-
-    private val perDisplayInstances = ConcurrentHashMap<Int, T?>()
-
-    init {
-        backgroundApplicationScope.launch("$debugName#start") { start() }
-    }
-
-    private suspend fun start() {
-        dumpManager.registerNormalDumpable("PerDisplayRepository-${debugName}", this)
-        displayRepository.displayIds.collectLatest { displayIds ->
-            val toRemove = perDisplayInstances.keys - displayIds
-            toRemove.forEach { displayId ->
-                Log.d(TAG, "<$debugName> destroying instance for displayId=$displayId.")
-                perDisplayInstances.remove(displayId)?.let { instance ->
-                    (instanceProvider as? PerDisplayInstanceProviderWithTeardown)?.destroyInstance(
-                        instance
-                    )
-                }
-            }
-        }
-    }
-
-    override fun get(displayId: Int): T? {
-        if (displayRepository.getDisplay(displayId) == null) {
-            Log.e(TAG, "<$debugName: Display with id $displayId doesn't exist.")
-            return null
-        }
-
-        // If it doesn't exist, create it and put it in the map.
-        return perDisplayInstances.computeIfAbsent(displayId) { key ->
-            Log.d(TAG, "<$debugName> creating instance for displayId=$key, as it wasn't available.")
-            val instance =
-                traceSection({ "creating instance of $debugName for displayId=$key" }) {
-                    instanceProvider.createInstance(key)
-                }
-            if (instance == null) {
-                Log.e(
-                    TAG,
-                    "<$debugName> returning null because createInstance($key) returned null.",
-                )
-            }
-            instance
-        }
-    }
-
-    @AssistedFactory
-    interface Factory<T> {
-        fun create(
-            debugName: String,
-            instanceProvider: PerDisplayInstanceProvider<T>,
-        ): PerDisplayInstanceRepositoryImpl<T>
-    }
-
-    companion object {
-        private const val TAG = "PerDisplayInstanceRepo"
-    }
-
-    override fun dump(pw: PrintWriter, args: Array<out String>) {
-        pw.println(perDisplayInstances)
-    }
-}
-
-/**
- * Provides an instance of a given class **only** for the default display, even if asked for another
- * display.
- *
- * This is useful in case of **flag refactors**: it can be provided instead of an instance of
- * [PerDisplayInstanceRepositoryImpl] when a flag related to multi display refactoring is off.
- *
- * Note that this still requires all instances to be provided by a [PerDisplayInstanceProvider]. If
- * you want to provide an existing instance instead for the default display, either implement it in
- * a custom [PerDisplayInstanceProvider] (e.g. inject it in the constructor and return it if the
- * displayId is zero), or use [SingleInstanceRepositoryImpl].
- */
-class DefaultDisplayOnlyInstanceRepositoryImpl<T>(
-    override val debugName: String,
-    private val instanceProvider: PerDisplayInstanceProvider<T>,
-) : PerDisplayRepository<T> {
-    private val lazyDefaultDisplayInstance by lazy {
-        instanceProvider.createInstance(Display.DEFAULT_DISPLAY)
-    }
-    override fun get(displayId: Int): T? = lazyDefaultDisplayInstance
-}
-
-/**
- * Always returns [instance] for any display.
- *
- * This can be used to provide a single instance based on a flag value during a refactor. Similar to
- * [DefaultDisplayOnlyInstanceRepositoryImpl], but also avoids creating the
- * [PerDisplayInstanceProvider]. This is useful when you want to provide an existing instance only,
- * without even instantiating a [PerDisplayInstanceProvider].
- */
-class SingleInstanceRepositoryImpl<T>(override val debugName: String, private val instance: T) :
-    PerDisplayRepository<T> {
-    override fun get(displayId: Int): T? = instance
-}
diff --git a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
index 4604886..8756c88 100644
--- a/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/data/repository/PerDisplayStore.kt
@@ -68,7 +68,7 @@
      *   displays.
      */
     override fun forDisplay(displayId: Int): T? {
-        if (displayRepository.getDisplay(displayId) == null) {
+        if (displayRepository.getDisplay(displayId)  == null) {
             Log.e(TAG, "<${instanceClass.simpleName}>: Display with id $displayId doesn't exist.")
             return null
         }
diff --git a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
index 15a3cbd..84f103e 100644
--- a/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/display/domain/interactor/ConnectedDisplayInteractor.kt
@@ -18,6 +18,7 @@
 
 import android.companion.virtual.VirtualDeviceManager
 import android.view.Display
+import com.android.app.displaylib.DisplayRepository as DisplayRepositoryFromLib
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.repository.DeviceStateRepository
@@ -138,7 +139,8 @@
             .distinctUntilChanged()
             .flowOn(backgroundCoroutineDispatcher)
 
-    private fun DisplayRepository.PendingDisplay.toInteractorPendingDisplay(): PendingDisplay =
+    private fun DisplayRepositoryFromLib.PendingDisplay.toInteractorPendingDisplay():
+        PendingDisplay =
         object : PendingDisplay {
             override suspend fun enable() = this@toInteractorPendingDisplay.enable()
 
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
index 9def81a..2b16e19 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeUi.java
@@ -18,7 +18,6 @@
 
 import static com.android.systemui.doze.DozeMachine.State.DOZE;
 import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSED;
-import static com.android.systemui.Flags.dozeuiSchedulingAlarmsBackgroundExecution;
 
 import android.app.AlarmManager;
 import android.content.Context;
@@ -84,13 +83,7 @@
         mBgExecutor = bgExecutor;
         mCanAnimateTransition = !params.getDisplayNeedsBlanking();
         mDozeParameters = params;
-        if (dozeuiSchedulingAlarmsBackgroundExecution()) {
-            mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick",
-                    bgHandler);
-        } else {
-            mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick",
-                    handler);
-        }
+        mTimeTicker = new AlarmTimeout(alarmManager, this::onTimeTick, "doze_time_tick", bgHandler);
         mDozeLog = dozeLog;
     }
 
@@ -184,7 +177,7 @@
         mTimeTickScheduled = true;
 
         long time = System.currentTimeMillis();
-        long delta = roundToNextMinute(time) - System.currentTimeMillis();
+        long delta = roundToNextMinute(time) - time;
         boolean scheduled = mTimeTicker.schedule(delta, AlarmTimeout.MODE_RESCHEDULE_IF_SCHEDULED);
         if (scheduled) {
             mDozeLog.traceTimeTickScheduled(time, time + delta);
@@ -224,14 +217,8 @@
     private void onTimeTick() {
         verifyLastTimeTick();
 
-        if (dozeuiSchedulingAlarmsBackgroundExecution()) {
-            mHandler.post(mHost::dozeTimeTick);
-        } else {
-            mHost.dozeTimeTick();
-        }
-
         // Keep wakelock until a frame has been pushed.
-        mHandler.post(mWakeLock.wrap(() -> {}));
+        mHandler.post(mWakeLock.wrap(mHost::dozeTimeTick));
 
         mTimeTickScheduled = false;
         scheduleTimeTick();
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java
deleted file mode 100644
index c17094b..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dreams.conditions;
-
-import com.android.systemui.assist.AssistManager;
-import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener;
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.shared.condition.Condition;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import javax.inject.Inject;
-
-/**
- * {@link AssistantAttentionCondition} provides a signal when assistant has the user's attention.
- */
-public class AssistantAttentionCondition extends Condition {
-    private final AssistManager mAssistManager;
-
-    private final VisualQueryAttentionListener mVisualQueryAttentionListener =
-            new VisualQueryAttentionListener() {
-        @Override
-        public void onAttentionGained() {
-            updateCondition(true);
-        }
-
-        @Override
-        public void onAttentionLost() {
-            updateCondition(false);
-        }
-    };
-
-    @Inject
-    public AssistantAttentionCondition(
-            @Application CoroutineScope scope,
-            AssistManager assistManager) {
-        super(scope);
-        mAssistManager = assistManager;
-    }
-
-    @Override
-    protected void start() {
-        mAssistManager.addVisualQueryAttentionListener(mVisualQueryAttentionListener);
-    }
-
-    @Override
-    protected void stop() {
-        mAssistManager.removeVisualQueryAttentionListener(mVisualQueryAttentionListener);
-    }
-
-    @Override
-    public int getStartStrategy() {
-        return START_EAGERLY;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.kt b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.kt
new file mode 100644
index 0000000..838163b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/AssistantAttentionCondition.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dreams.conditions
+
+import com.android.systemui.assist.AssistManager
+import com.android.systemui.assist.AssistManager.VisualQueryAttentionListener
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.shared.condition.Condition
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** [AssistantAttentionCondition] provides a signal when assistant has the user's attention. */
+class AssistantAttentionCondition
+@Inject
+constructor(@Application scope: CoroutineScope, private val assistManager: AssistManager) :
+    Condition(scope) {
+    private val visualQueryAttentionListener: VisualQueryAttentionListener =
+        object : VisualQueryAttentionListener {
+            override fun onAttentionGained() {
+                updateCondition(true)
+            }
+
+            override fun onAttentionLost() {
+                updateCondition(false)
+            }
+        }
+
+    override suspend fun start() {
+        assistManager.addVisualQueryAttentionListener(visualQueryAttentionListener)
+    }
+
+    public override fun stop() {
+        assistManager.removeVisualQueryAttentionListener(visualQueryAttentionListener)
+    }
+
+    override val startStrategy: Int
+        get() = START_EAGERLY
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
deleted file mode 100644
index fb4ed14..0000000
--- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.dreams.conditions;
-
-import android.app.DreamManager;
-
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.shared.condition.Condition;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import javax.inject.Inject;
-
-/**
- * {@link DreamCondition} provides a signal when a dream begins and ends.
- */
-public class DreamCondition extends Condition {
-    private final DreamManager mDreamManager;
-    private final KeyguardUpdateMonitor mUpdateMonitor;
-
-    private final KeyguardUpdateMonitorCallback mUpdateCallback =
-            new KeyguardUpdateMonitorCallback() {
-                @Override
-                public void onDreamingStateChanged(boolean dreaming) {
-                    updateCondition(dreaming);
-                }
-            };
-
-    @Inject
-    public DreamCondition(
-            @Application CoroutineScope scope,
-            DreamManager dreamManager,
-            KeyguardUpdateMonitor monitor) {
-        super(scope);
-        mDreamManager = dreamManager;
-        mUpdateMonitor = monitor;
-    }
-
-    @Override
-    protected void start() {
-        mUpdateMonitor.registerCallback(mUpdateCallback);
-        updateCondition(mDreamManager.isDreaming());
-    }
-
-    @Override
-    protected void stop() {
-        mUpdateMonitor.removeCallback(mUpdateCallback);
-    }
-
-    @Override
-    public int getStartStrategy() {
-        return START_EAGERLY;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.kt b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.kt
new file mode 100644
index 0000000..6968132
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.kt
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dreams.conditions
+
+import android.app.DreamManager
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.shared.condition.Condition
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** [DreamCondition] provides a signal when a dream begins and ends. */
+class DreamCondition
+@Inject
+constructor(
+    @Application scope: CoroutineScope,
+    private val _dreamManager: DreamManager,
+    private val _updateMonitor: KeyguardUpdateMonitor,
+) : Condition(scope) {
+    private val _updateCallback: KeyguardUpdateMonitorCallback =
+        object : KeyguardUpdateMonitorCallback() {
+            override fun onDreamingStateChanged(dreaming: Boolean) {
+                updateCondition(dreaming)
+            }
+        }
+
+    override suspend fun start() {
+        _updateMonitor.registerCallback(_updateCallback)
+        updateCondition(_dreamManager.isDreaming)
+    }
+
+    override fun stop() {
+        _updateMonitor.removeCallback(_updateCallback)
+    }
+
+    override val startStrategy: Int
+        get() = START_EAGERLY
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
index 15f73ee..a56f07e 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/dagger/DreamModule.java
@@ -42,9 +42,9 @@
 import com.android.systemui.qs.QsEventLogger;
 import com.android.systemui.qs.pipeline.shared.TileSpec;
 import com.android.systemui.qs.shared.model.TileCategory;
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig;
-import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy;
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig;
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig;
+import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy;
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig;
 import com.android.systemui.res.R;
 import com.android.systemui.touch.TouchInsetManager;
 
diff --git a/packages/SystemUI/src/com/android/systemui/dump/DumpableFromToString.kt b/packages/SystemUI/src/com/android/systemui/dump/DumpableFromToString.kt
new file mode 100644
index 0000000..438931a1
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/dump/DumpableFromToString.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.dump
+
+import com.android.systemui.Dumpable
+import java.io.PrintWriter
+
+/** Dumpable implementation that just calls toString() on the instance. */
+class DumpableFromToString<T>(private val instance: T) : Dumpable {
+    override fun dump(pw: PrintWriter, args: Array<out String>) {
+        pw.println("$instance")
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
index cf5c340..f2a10cc 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialogLite.java
@@ -147,14 +147,14 @@
 import com.android.systemui.util.settings.GlobalSettings;
 import com.android.systemui.util.settings.SecureSettings;
 
+import dagger.Lazy;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.Executor;
 
 import javax.inject.Inject;
 
-import dagger.Lazy;
-
 /**
  * Helper to show the global actions dialog.  Each item is an {@link Action} that may show depending
  * on whether the keyguard is showing, and whether the device is provisioned.
@@ -270,6 +270,16 @@
     private final UserLogoutInteractor mLogoutInteractor;
     private final GlobalActionsInteractor mInteractor;
     private final Lazy<DisplayWindowPropertiesRepository> mDisplayWindowPropertiesRepositoryLazy;
+    private final Handler mHandler;
+
+    private final UserTracker.Callback mOnUserSwitched = new UserTracker.Callback() {
+        @Override
+        public void onBeforeUserSwitching(int newUser) {
+            // Dismiss the dialog as soon as we start switching. This will schedule a message
+            // in a handler so it will be pretty quick.
+            dismissDialog();
+        }
+    };
 
     @VisibleForTesting
     public enum GlobalActionsEvent implements UiEventLogger.UiEventEnum {
@@ -425,6 +435,29 @@
         mInteractor = interactor;
         mDisplayWindowPropertiesRepositoryLazy = displayWindowPropertiesRepository;
 
+        mHandler = new Handler(mMainHandler.getLooper()) {
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MESSAGE_DISMISS:
+                        if (mDialog != null) {
+                            if (SYSTEM_DIALOG_REASON_DREAM.equals(msg.obj)) {
+                                // Hide instantly.
+                                mDialog.hide();
+                                mDialog.dismiss();
+                            } else {
+                                mDialog.dismiss();
+                            }
+                            mDialog = null;
+                        }
+                        break;
+                    case MESSAGE_REFRESH:
+                        refreshSilentMode();
+                        mAdapter.notifyDataSetChanged();
+                        break;
+                }
+            }
+        };
+
         // receive broadcasts
         IntentFilter filter = new IntentFilter();
         filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
@@ -537,6 +570,7 @@
                 expandable != null ? expandable.dialogTransitionController(
                         new DialogCuj(InteractionJankMonitor.CUJ_SHADE_DIALOG_OPEN,
                                 INTERACTION_JANK_TAG)) : null;
+        mUserTracker.addCallback(mOnUserSwitched, mBackgroundExecutor);
         if (controller != null) {
             mDialogTransitionAnimator.show(mDialog, controller);
         } else {
@@ -1404,6 +1438,7 @@
         mWindowManagerFuncs.onGlobalActionsHidden();
         mLifecycle.setCurrentState(Lifecycle.State.CREATED);
         mInteractor.onDismissed();
+        mUserTracker.removeCallback(mOnUserSwitched);
     }
 
     /**
@@ -2228,29 +2263,6 @@
         mDialogPressDelay = 0; // ms
     }
 
-    private Handler mHandler = new Handler() {
-        public void handleMessage(Message msg) {
-            switch (msg.what) {
-                case MESSAGE_DISMISS:
-                    if (mDialog != null) {
-                        if (SYSTEM_DIALOG_REASON_DREAM.equals(msg.obj)) {
-                            // Hide instantly.
-                            mDialog.hide();
-                            mDialog.dismiss();
-                        } else {
-                            mDialog.dismiss();
-                        }
-                        mDialog = null;
-                    }
-                    break;
-                case MESSAGE_REFRESH:
-                    refreshSilentMode();
-                    mAdapter.notifyDataSetChanged();
-                    break;
-            }
-        }
-    };
-
     private void onAirplaneModeChanged() {
         // Let the service state callbacks handle the state.
         if (mHasTelephony || mAirplaneModeOn == null) return;
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt
index 981a55c..5ebbb46 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/composable/Surfaces.kt
@@ -77,9 +77,9 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.unit.sp
 import androidx.compose.ui.zIndex
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.modifiers.thenIf
 import com.android.systemui.keyboard.shortcut.ui.model.IconSource
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 /**
  * A selectable surface with no default focus/hover indications.
@@ -235,18 +235,19 @@
         color = color.getDimmedColorIfDisabled(enabled),
         border = border,
         modifier = modifier.semantics { role = Role.Button },
-        interactionsConfig = InteractionsConfig(
-            hoverOverlayColor = MaterialTheme.colorScheme.onSurface,
-            hoverOverlayAlpha = 0.11f,
-            pressedOverlayColor = MaterialTheme.colorScheme.onSurface,
-            pressedOverlayAlpha = 0.15f,
-            focusOutlineColor = MaterialTheme.colorScheme.secondary,
-            focusOutlineStrokeWidth = 3.dp,
-            focusOutlinePadding = 2.dp,
-            surfaceCornerRadius = 28.dp,
-            focusOutlineCornerRadius = 33.dp,
-        ),
-        enabled = enabled
+        interactionsConfig =
+            InteractionsConfig(
+                hoverOverlayColor = MaterialTheme.colorScheme.onSurface,
+                hoverOverlayAlpha = 0.11f,
+                pressedOverlayColor = MaterialTheme.colorScheme.onSurface,
+                pressedOverlayAlpha = 0.15f,
+                focusOutlineColor = MaterialTheme.colorScheme.secondary,
+                focusOutlineStrokeWidth = 3.dp,
+                focusOutlinePadding = 2.dp,
+                surfaceCornerRadius = 28.dp,
+                focusOutlineCornerRadius = 33.dp,
+            ),
+        enabled = enabled,
     ) {
         Row(
             modifier =
@@ -267,7 +268,7 @@
     iconSource: IconSource,
     contentColor: Color,
     text: String?,
-    contentDescription: String?
+    contentDescription: String?,
 ) {
     if (iconSource.imageVector != null) {
         Icon(
@@ -278,8 +279,7 @@
         )
     }
 
-    if (iconSource.imageVector != null && text != null)
-        Spacer(modifier = Modifier.width(8.dp))
+    if (iconSource.imageVector != null && text != null) Spacer(modifier = Modifier.width(8.dp))
 
     if (text != null) {
         Text(
@@ -363,7 +363,7 @@
                     is HoverInteraction.Exit -> hoverInteractions.remove(interaction.enter)
                     is PressInteraction.Press -> pressInteractions.add(interaction)
                     is PressInteraction.Release -> pressInteractions.remove(interaction.press)
-                    is PressInteraction.Cancel -> pressInteractions.add(interaction.press)
+                    is PressInteraction.Cancel -> pressInteractions.remove(interaction.press)
                 }
                 isHovered.value = hoverInteractions.isNotEmpty()
                 isPressed.value = pressInteractions.isNotEmpty()
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
index c61530c..74cf7e4 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt
@@ -20,7 +20,6 @@
 import android.content.Context
 import com.android.internal.jank.InteractionJankMonitor
 import com.android.systemui.CoreStartable
-import com.android.systemui.Flags.lightRevealMigration
 import com.android.systemui.biometrics.ui.binder.DeviceEntryUnlockTrackerViewBinder
 import com.android.systemui.common.ui.ConfigurationState
 import com.android.systemui.dagger.SysUISingleton
@@ -46,6 +45,7 @@
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
+import com.android.systemui.shared.Flags.ambientAod
 import com.android.systemui.statusbar.KeyguardIndicationController
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.VibratorHelper
@@ -105,7 +105,7 @@
         bindJankViewModel()
         initializeViews()
 
-        if (lightRevealMigration()) {
+        if (ambientAod()) {
             LightRevealScrimViewBinder.bind(
                 lightRevealScrim,
                 lightRevealScrimViewModel,
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index d8fc21a..6db2ebc 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -134,7 +134,6 @@
 import com.android.keyguard.mediator.ScreenOnCoordinator;
 import com.android.systemui.CoreStartable;
 import com.android.systemui.DejankUtils;
-import com.android.systemui.Dumpable;
 import com.android.systemui.EventLogTags;
 import com.android.systemui.animation.ActivityTransitionAnimator;
 import com.android.systemui.animation.TransitionAnimator;
@@ -194,7 +193,6 @@
 import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Objects;
 import java.util.concurrent.Executor;
@@ -1746,6 +1744,9 @@
         mJavaAdapter.alwaysCollectFlow(
                 mWallpaperRepository.getWallpaperSupportsAmbientMode(),
                 this::setWallpaperSupportsAmbientMode);
+        mJavaAdapter.alwaysCollectFlow(
+                mKeyguardInteractor.getDozeTimeTick(),
+                this::triggerTimeUpdate);
     }
 
     @Override
@@ -4058,6 +4059,10 @@
         mWallpaperSupportsAmbientMode = supportsAmbientMode;
     }
 
+    private void triggerTimeUpdate(long timeInMillis) {
+        mUpdateMonitor.triggerTimeUpdate();
+    }
+
     private static class StartKeyguardExitAnimParams {
 
         @WindowManager.TransitionOldType int mTransit;
@@ -4129,14 +4134,14 @@
 
     private void notifyLockNowCallback() {
         List<LockNowCallback> callbacks;
+
         synchronized (mLockNowCallbacks) {
-            callbacks = new ArrayList<LockNowCallback>(mLockNowCallbacks);
+            callbacks = new ArrayList<>(mLockNowCallbacks);
             mLockNowCallbacks.clear();
         }
-        Iterator<LockNowCallback> iter = callbacks.listIterator();
-        while (iter.hasNext()) {
-            LockNowCallback callback = iter.next();
-            iter.remove();
+
+        for (int i = 0; i < callbacks.size(); i++) {
+            final LockNowCallback callback = callbacks.get(i);
             if (callback.mUserId != mSelectedUserInteractor.getSelectedUserId()) {
                 Log.i(TAG, "Not notifying lockNowCallback due to user mismatch");
                 continue;
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
index ab0efed..02e04aa 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardClockInteractor.kt
@@ -226,6 +226,10 @@
         }
 
     fun handleFidgetTap(x: Float, y: Float) {
+        if (!com.android.systemui.Flags.clockFidgetAnimation()) {
+            return
+        }
+
         if (selectedClockSize.value == ClockSizeSetting.DYNAMIC) {
             clockEventController.handleFidgetTap(x, y)
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceShowLockscreenInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceShowLockscreenInteractor.kt
index 07a31e1..6c08403 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceShowLockscreenInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardServiceShowLockscreenInteractor.kt
@@ -139,18 +139,16 @@
     /** Notifies the callbacks that we've either locked, or decided not to lock. */
     private fun notifyShowLockscreenCallbacks() {
         var callbacks: MutableList<ShowLockscreenCallback>
+
         synchronized(repository.showLockscreenCallbacks) {
             callbacks = ArrayList(repository.showLockscreenCallbacks)
             repository.showLockscreenCallbacks.clear()
         }
 
-        val iter: MutableIterator<ShowLockscreenCallback> = callbacks.listIterator()
-        while (iter.hasNext()) {
-            val callback = iter.next()
-            iter.remove()
+        callbacks.forEach { callback ->
             if (callback.userId != selectedUserInteractor.getSelectedUserId()) {
                 Log.i(TAG, "Not notifying lockNowCallback due to user mismatch")
-                continue
+                return
             }
             Log.i(TAG, "Notifying lockNowCallback")
             try {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt
index 0b116de..438dff9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/LightRevealScrimInteractor.kt
@@ -139,7 +139,7 @@
     fun setWallpaperSupportsAmbientMode(supportsAmbientMode: Boolean) {
         repository.maxAlpha.value =
             if (supportsAmbientMode) {
-                0.7f
+                0.54f
             } else {
                 1f
             }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToGlanceableHubTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToGlanceableHubTransitionViewModel.kt
index 45f8f10..3cf0506 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToGlanceableHubTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToGlanceableHubTransitionViewModel.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.util.MathUtils
-import com.android.systemui.Flags.lightRevealMigration
 import com.android.systemui.communal.ui.compose.TransitionDuration
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.dagger.GlanceableHubBlurComponent
@@ -28,6 +27,7 @@
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
 import com.android.systemui.keyguard.ui.transitions.GlanceableHubTransition
 import com.android.systemui.scene.shared.model.Scenes
+import com.android.systemui.shared.Flags.ambientAod
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.flow.Flow
@@ -56,14 +56,14 @@
         return transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             startTime =
-                if (lightRevealMigration()) {
+                if (ambientAod()) {
                     100.milliseconds // Wait for the light reveal to "hit" the LS elements.
                 } else {
                     0.milliseconds
                 },
             onStart = {
                 currentAlpha =
-                    if (lightRevealMigration()) {
+                    if (ambientAod()) {
                         viewState.alpha()
                     } else {
                         0f
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModel.kt
index d981eeb..ba6bda8 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToOccludedTransitionViewModel.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.util.MathUtils
-import com.android.systemui.Flags.lightRevealMigration
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.FromAodTransitionInteractor
 import com.android.systemui.keyguard.shared.model.Edge
@@ -25,6 +24,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.shared.Flags.ambientAod
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.flow.Flow
@@ -52,13 +52,13 @@
         return transitionAnimation.sharedFlow(
             duration = 250.milliseconds,
             startTime =
-                if (lightRevealMigration()) {
+                if (ambientAod()) {
                     100.milliseconds // Wait for the light reveal to "hit" the LS elements.
                 } else {
                     0.milliseconds
                 },
             onStart = {
-                if (lightRevealMigration()) {
+                if (ambientAod()) {
                     currentAlpha = viewState.alpha()
                 } else {
                     currentAlpha = 0f
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModel.kt
index b15cacf..2eb5bf9 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/DozingToOccludedTransitionViewModel.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.keyguard.ui.viewmodel
 
 import android.util.MathUtils
-import com.android.systemui.Flags.lightRevealMigration
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.keyguard.domain.interactor.FromAodTransitionInteractor
 import com.android.systemui.keyguard.shared.model.Edge
@@ -25,6 +24,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState.OCCLUDED
 import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
 import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
+import com.android.systemui.shared.Flags.ambientAod
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.flow.Flow
@@ -56,7 +56,7 @@
             duration = 250.milliseconds,
             startTime = 0.milliseconds,
             onStart = {
-                if (lightRevealMigration()) {
+                if (ambientAod()) {
                     currentAlpha = viewState.alpha()
                 } else {
                     currentAlpha = 0f
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesVerboseLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesVerboseLog.java
index b0c2f8c..b27a421 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesVerboseLog.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/QSTilesVerboseLog.java
@@ -26,8 +26,7 @@
 import javax.inject.Qualifier;
 
 /**
- * A {@link LogBuffer} for QS tiles messages. It's used exclusively in
- * {@link com.android.systemui.qs.tiles.base.logging.QSTileLogger}
+ * A {@link LogBuffer} for QS tiles messages. It's used exclusively in @link QSTileLogger}.
  */
 @Qualifier
 @Documented
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt
index 9e32dd8..c1658e1 100644
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/AmbientLightModeMonitor.kt
@@ -122,7 +122,7 @@
         }
 
     /** Interface of the ambient light mode callback, which gets triggered when the mode changes. */
-    interface Callback {
+    fun interface Callback {
         fun onChange(@AmbientLightMode mode: Int)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt
index 57d7098..ce5fd19 100644
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/DirectBootCondition.kt
@@ -20,7 +20,7 @@
 import android.content.IntentFilter
 import android.os.UserManager
 import com.android.systemui.broadcast.BroadcastDispatcher
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.shared.condition.Condition
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
@@ -35,7 +35,7 @@
 constructor(
     broadcastDispatcher: BroadcastDispatcher,
     private val userManager: UserManager,
-    @Application private val coroutineScope: CoroutineScope,
+    @Background private val coroutineScope: CoroutineScope,
 ) : Condition(coroutineScope) {
     private var job: Job? = null
     private val directBootFlow =
@@ -45,7 +45,7 @@
             .cancellable()
             .distinctUntilChanged()
 
-    override fun start() {
+    override suspend fun start() {
         job = coroutineScope.launch { directBootFlow.collect { updateCondition(it) } }
         updateCondition(!userManager.isUserUnlocked)
     }
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java
deleted file mode 100644
index 5ec81a9..0000000
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.lowlightclock;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import androidx.annotation.NonNull;
-
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.shared.condition.Condition;
-import com.android.systemui.statusbar.commandline.Command;
-import com.android.systemui.statusbar.commandline.CommandRegistry;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import java.io.PrintWriter;
-import java.util.List;
-
-import javax.inject.Inject;
-
-/**
- * This condition registers for and fulfills cmd shell commands to force a device into or out of
- * low-light conditions.
- */
-public class ForceLowLightCondition extends Condition {
-    /**
-     * Command root
-     */
-    public static final String COMMAND_ROOT = "low-light";
-    /**
-     * Command for forcing device into low light.
-     */
-    public static final String COMMAND_ENABLE_LOW_LIGHT = "enable";
-
-    /**
-     * Command for preventing a device from entering low light.
-     */
-    public static final String COMMAND_DISABLE_LOW_LIGHT = "disable";
-
-    /**
-     * Command for clearing previously forced low-light conditions.
-     */
-    public static final String COMMAND_CLEAR_LOW_LIGHT = "clear";
-
-    private static final String TAG = "ForceLowLightCondition";
-    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
-
-    /**
-     * Default Constructor.
-     *
-     * @param commandRegistry command registry to register commands with.
-     */
-    @Inject
-    public ForceLowLightCondition(
-            @Application CoroutineScope scope,
-            CommandRegistry commandRegistry
-    ) {
-        super(scope, null, true);
-
-        if (DEBUG) {
-            Log.d(TAG, "registering commands");
-        }
-        commandRegistry.registerCommand(COMMAND_ROOT, () -> new Command() {
-            @Override
-            public void execute(@NonNull PrintWriter pw, @NonNull List<String> args) {
-                if (args.size() != 1) {
-                    pw.println("no command specified");
-                    help(pw);
-                    return;
-                }
-
-                final String cmd = args.get(0);
-
-                if (TextUtils.equals(cmd, COMMAND_ENABLE_LOW_LIGHT)) {
-                    logAndPrint(pw, "forcing low light");
-                    updateCondition(true);
-                } else if (TextUtils.equals(cmd, COMMAND_DISABLE_LOW_LIGHT)) {
-                    logAndPrint(pw, "forcing to not enter low light");
-                    updateCondition(false);
-                } else if (TextUtils.equals(cmd, COMMAND_CLEAR_LOW_LIGHT)) {
-                    logAndPrint(pw, "clearing any forced low light");
-                    clearCondition();
-                } else {
-                    pw.println("invalid command");
-                    help(pw);
-                }
-            }
-
-            @Override
-            public void help(@NonNull PrintWriter pw) {
-                pw.println("Usage: adb shell cmd statusbar low-light <cmd>");
-                pw.println("Supported commands:");
-                pw.println("  - enable");
-                pw.println("    forces device into low-light");
-                pw.println("  - disable");
-                pw.println("    forces device to not enter low-light");
-                pw.println("  - clear");
-                pw.println("    clears any previously forced state");
-            }
-
-            private void logAndPrint(PrintWriter pw, String message) {
-                pw.println(message);
-                if (DEBUG) {
-                    Log.d(TAG, message);
-                }
-            }
-        });
-    }
-
-    @Override
-    protected void start() {
-    }
-
-    @Override
-    protected void stop() {
-    }
-
-    @Override
-    public int getStartStrategy() {
-        return START_EAGERLY;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.kt
new file mode 100644
index 0000000..85a9430
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/ForceLowLightCondition.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.lowlightclock
+
+import android.text.TextUtils
+import android.util.Log
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.shared.condition.Condition
+import com.android.systemui.statusbar.commandline.Command
+import com.android.systemui.statusbar.commandline.CommandRegistry
+import java.io.PrintWriter
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/**
+ * This condition registers for and fulfills cmd shell commands to force a device into or out of
+ * low-light conditions.
+ */
+class ForceLowLightCondition
+@Inject
+constructor(@Background scope: CoroutineScope, commandRegistry: CommandRegistry) :
+    Condition(scope, null, true) {
+    /**
+     * Default Constructor.
+     *
+     * @param commandRegistry command registry to register commands with.
+     */
+    init {
+        if (DEBUG) {
+            Log.d(TAG, "registering commands")
+        }
+        commandRegistry.registerCommand(COMMAND_ROOT) {
+            object : Command {
+                override fun execute(pw: PrintWriter, args: List<String>) {
+                    if (args.size != 1) {
+                        pw.println("no command specified")
+                        help(pw)
+                        return
+                    }
+
+                    val cmd = args[0]
+
+                    if (TextUtils.equals(cmd, COMMAND_ENABLE_LOW_LIGHT)) {
+                        logAndPrint(pw, "forcing low light")
+                        updateCondition(true)
+                    } else if (TextUtils.equals(cmd, COMMAND_DISABLE_LOW_LIGHT)) {
+                        logAndPrint(pw, "forcing to not enter low light")
+                        updateCondition(false)
+                    } else if (TextUtils.equals(cmd, COMMAND_CLEAR_LOW_LIGHT)) {
+                        logAndPrint(pw, "clearing any forced low light")
+                        clearCondition()
+                    } else {
+                        pw.println("invalid command")
+                        help(pw)
+                    }
+                }
+
+                override fun help(pw: PrintWriter) {
+                    pw.println("Usage: adb shell cmd statusbar low-light <cmd>")
+                    pw.println("Supported commands:")
+                    pw.println("  - enable")
+                    pw.println("    forces device into low-light")
+                    pw.println("  - disable")
+                    pw.println("    forces device to not enter low-light")
+                    pw.println("  - clear")
+                    pw.println("    clears any previously forced state")
+                }
+
+                private fun logAndPrint(pw: PrintWriter, message: String) {
+                    pw.println(message)
+                    if (DEBUG) {
+                        Log.d(TAG, message)
+                    }
+                }
+            }
+        }
+    }
+
+    override suspend fun start() {}
+
+    override fun stop() {}
+
+    override val startStrategy: Int
+        get() = START_EAGERLY
+
+    companion object {
+        /** Command root */
+        const val COMMAND_ROOT: String = "low-light"
+
+        /** Command for forcing device into low light. */
+        const val COMMAND_ENABLE_LOW_LIGHT: String = "enable"
+
+        /** Command for preventing a device from entering low light. */
+        const val COMMAND_DISABLE_LOW_LIGHT: String = "disable"
+
+        /** Command for clearing previously forced low-light conditions. */
+        const val COMMAND_CLEAR_LOW_LIGHT: String = "clear"
+
+        private const val TAG = "ForceLowLightCondition"
+        private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java
deleted file mode 100644
index c1a24e7..0000000
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.lowlightclock;
-
-import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.shared.condition.Condition;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import javax.inject.Inject;
-
-/**
- * Condition for monitoring when the device enters and exits lowlight mode.
- */
-public class LowLightCondition extends Condition {
-    private final AmbientLightModeMonitor mAmbientLightModeMonitor;
-    private final UiEventLogger mUiEventLogger;
-
-    @Inject
-    public LowLightCondition(@Application CoroutineScope scope,
-            AmbientLightModeMonitor ambientLightModeMonitor,
-            UiEventLogger uiEventLogger) {
-        super(scope);
-        mAmbientLightModeMonitor = ambientLightModeMonitor;
-        mUiEventLogger = uiEventLogger;
-    }
-
-    @Override
-    protected void start() {
-        mAmbientLightModeMonitor.start(this::onLowLightChanged);
-    }
-
-    @Override
-    protected void stop() {
-        mAmbientLightModeMonitor.stop();
-
-        // Reset condition met to false.
-        updateCondition(false);
-    }
-
-    @Override
-    public int getStartStrategy() {
-        // As this condition keeps the lowlight sensor active, it should only run when needed.
-        return START_WHEN_NEEDED;
-    }
-
-    private void onLowLightChanged(int lowLightMode) {
-        if (lowLightMode == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED) {
-            // Ignore undecided mode changes.
-            return;
-        }
-
-        final boolean isLowLight = lowLightMode == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK;
-        if (isLowLight == isConditionMet()) {
-            // No change in condition, don't do anything.
-            return;
-        }
-        mUiEventLogger.log(isLowLight ? LowLightDockEvent.AMBIENT_LIGHT_TO_DARK
-                : LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT);
-        updateCondition(isLowLight);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.kt
new file mode 100644
index 0000000..34e9a63
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/LowLightCondition.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.lowlightclock
+
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.shared.condition.Condition
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** Condition for monitoring when the device enters and exits lowlight mode. */
+class LowLightCondition
+@Inject
+constructor(
+    @Background scope: CoroutineScope,
+    private val ambientLightModeMonitor: AmbientLightModeMonitor,
+    private val uiEventLogger: UiEventLogger,
+) : Condition(scope) {
+    override suspend fun start() {
+        ambientLightModeMonitor.start { lowLightMode: Int -> onLowLightChanged(lowLightMode) }
+    }
+
+    override fun stop() {
+        ambientLightModeMonitor.stop()
+
+        // Reset condition met to false.
+        updateCondition(false)
+    }
+
+    override val startStrategy: Int
+        get() = // As this condition keeps the lowlight sensor active, it should only run when
+            // needed.
+            START_WHEN_NEEDED
+
+    private fun onLowLightChanged(lowLightMode: Int) {
+        if (lowLightMode == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED) {
+            // Ignore undecided mode changes.
+            return
+        }
+
+        val isLowLight = lowLightMode == AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK
+        if (isLowLight == isConditionMet) {
+            // No change in condition, don't do anything.
+            return
+        }
+        uiEventLogger.log(
+            if (isLowLight) LowLightDockEvent.AMBIENT_LIGHT_TO_DARK
+            else LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT
+        )
+        updateCondition(isLowLight)
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java b/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java
deleted file mode 100644
index 8157255..0000000
--- a/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.lowlightclock;
-
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.util.Log;
-
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.shared.condition.Condition;
-import com.android.systemui.util.settings.SecureSettings;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import javax.inject.Inject;
-
-/**
- * Condition for monitoring if the screensaver setting is enabled.
- */
-public class ScreenSaverEnabledCondition extends Condition {
-    private static final String TAG = ScreenSaverEnabledCondition.class.getSimpleName();
-
-    private final boolean mScreenSaverEnabledByDefaultConfig;
-    private final SecureSettings mSecureSettings;
-
-    private final ContentObserver mScreenSaverSettingObserver = new ContentObserver(null) {
-        @Override
-        public void onChange(boolean selfChange) {
-            updateScreenSaverEnabledSetting();
-        }
-    };
-
-    @Inject
-    public ScreenSaverEnabledCondition(@Application CoroutineScope scope, @Main Resources resources,
-            SecureSettings secureSettings) {
-        super(scope);
-        mScreenSaverEnabledByDefaultConfig = resources.getBoolean(
-                com.android.internal.R.bool.config_dreamsEnabledByDefault);
-        mSecureSettings = secureSettings;
-    }
-
-    @Override
-    protected void start() {
-        mSecureSettings.registerContentObserverForUserSync(
-                Settings.Secure.SCREENSAVER_ENABLED,
-                mScreenSaverSettingObserver, UserHandle.USER_CURRENT);
-        updateScreenSaverEnabledSetting();
-    }
-
-    @Override
-    protected void stop() {
-        mSecureSettings.unregisterContentObserverSync(mScreenSaverSettingObserver);
-    }
-
-    @Override
-    public int getStartStrategy() {
-        return START_EAGERLY;
-    }
-
-    private void updateScreenSaverEnabledSetting() {
-        final boolean enabled = mSecureSettings.getIntForUser(
-                Settings.Secure.SCREENSAVER_ENABLED,
-                mScreenSaverEnabledByDefaultConfig ? 1 : 0,
-                UserHandle.USER_CURRENT) != 0;
-        if (!enabled) {
-            Log.i(TAG, "Disabling low-light clock because screen saver has been disabled");
-        }
-        updateCondition(enabled);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.kt b/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.kt
new file mode 100644
index 0000000..e761cc0
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/lowlightclock/ScreenSaverEnabledCondition.kt
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.lowlightclock
+
+import android.content.res.Resources
+import android.database.ContentObserver
+import android.os.UserHandle
+import android.provider.Settings
+import android.util.Log
+import com.android.internal.R
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.shared.condition.Condition
+import com.android.systemui.util.settings.SecureSettings
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/** Condition for monitoring if the screensaver setting is enabled. */
+class ScreenSaverEnabledCondition
+@Inject
+constructor(
+    @Background scope: CoroutineScope,
+    @Main resources: Resources,
+    private val secureSettings: SecureSettings,
+) : Condition(scope) {
+    private val screenSaverEnabledByDefaultConfig =
+        resources.getBoolean(R.bool.config_dreamsEnabledByDefault)
+
+    private val screenSaverSettingObserver: ContentObserver =
+        object : ContentObserver(null) {
+            override fun onChange(selfChange: Boolean) {
+                updateScreenSaverEnabledSetting()
+            }
+        }
+
+    public override suspend fun start() {
+        secureSettings.registerContentObserverForUserSync(
+            Settings.Secure.SCREENSAVER_ENABLED,
+            screenSaverSettingObserver,
+            UserHandle.USER_CURRENT,
+        )
+        updateScreenSaverEnabledSetting()
+    }
+
+    override fun stop() {
+        secureSettings.unregisterContentObserverSync(screenSaverSettingObserver)
+    }
+
+    override val startStrategy: Int
+        get() = START_EAGERLY
+
+    private fun updateScreenSaverEnabledSetting() {
+        val enabled =
+            secureSettings.getIntForUser(
+                Settings.Secure.SCREENSAVER_ENABLED,
+                if (screenSaverEnabledByDefaultConfig) 1 else 0,
+                UserHandle.USER_CURRENT,
+            ) != 0
+        if (!enabled) {
+            Log.i(TAG, "Disabling low-light clock because screen saver has been disabled")
+        }
+        updateCondition(enabled)
+    }
+
+    companion object {
+        private val TAG: String = ScreenSaverEnabledCondition::class.java.simpleName
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/SeekBarObserver.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/SeekBarObserver.kt
index cedf661..5b65531 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/SeekBarObserver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/SeekBarObserver.kt
@@ -127,7 +127,6 @@
         }
 
         holder.seekBar.setMax(data.duration)
-        val totalTimeDescription = data.durationDescription
         if (data.scrubbing) {
             holder.scrubbingTotalTimeView.text = formatTimeLabel(data.duration)
         }
@@ -147,17 +146,9 @@
                 }
             }
 
-            val elapsedTimeDescription = data.elapsedTimeDescription
             if (data.scrubbing) {
                 holder.scrubbingElapsedTimeView.text = formatTimeLabel(it)
             }
-
-            holder.seekBar.contentDescription =
-                holder.seekBar.context.getString(
-                    R.string.controls_media_seekbar_description,
-                    elapsedTimeDescription,
-                    totalTimeDescription,
-                )
         }
     }
 
@@ -166,6 +157,18 @@
         return DateUtils.formatElapsedTime(milliseconds / DateUtils.SECOND_IN_MILLIS)
     }
 
+    fun updateContentDescription(
+        elapsedTimeDescription: CharSequence,
+        durationDescription: CharSequence,
+    ) {
+        holder.seekBar.contentDescription =
+            holder.seekBar.context.getString(
+                R.string.controls_media_seekbar_description,
+                elapsedTimeDescription,
+                durationDescription,
+            )
+    }
+
     @VisibleForTesting
     open fun buildResetAnimator(targetTime: Int): Animator {
         val animator =
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
index 006eb20..f69985e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java
@@ -224,6 +224,8 @@
             this::setIsScrubbing;
     private final SeekBarViewModel.EnabledChangeListener mEnabledChangeListener =
             this::setIsSeekBarEnabled;
+    private final SeekBarViewModel.ContentDescriptionListener mContentDescriptionListener =
+            this::setSeekbarContentDescription;
 
     private final BroadcastDialogController mBroadcastDialogController;
     private boolean mIsCurrentBroadcastedApp = false;
@@ -327,6 +329,7 @@
         }
         mSeekBarViewModel.removeScrubbingChangeListener(mScrubbingChangeListener);
         mSeekBarViewModel.removeEnabledChangeListener(mEnabledChangeListener);
+        mSeekBarViewModel.removeContentDescriptionListener(mContentDescriptionListener);
         mSeekBarViewModel.onDestroy();
         mMediaViewController.onDestroy();
     }
@@ -395,6 +398,10 @@
         });
     }
 
+    private void setSeekbarContentDescription(CharSequence elapsedTime, CharSequence duration) {
+        mSeekBarObserver.updateContentDescription(elapsedTime, duration);
+    }
+
     /**
      * Reloads animator duration scale.
      */
@@ -424,6 +431,7 @@
         mSeekBarViewModel.attachTouchHandlers(vh.getSeekBar());
         mSeekBarViewModel.setScrubbingChangeListener(mScrubbingChangeListener);
         mSeekBarViewModel.setEnabledChangeListener(mEnabledChangeListener);
+        mSeekBarViewModel.setContentDescriptionListener(mContentDescriptionListener);
         mMediaViewController.attach(player);
 
         vh.getPlayer().setOnLongClickListener(v -> {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
index dba1900..e87d5de 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaViewController.kt
@@ -229,6 +229,20 @@
             }
         }
 
+    private val seekbarDescriptionListener =
+        object : SeekBarViewModel.ContentDescriptionListener {
+            override fun onContentDescriptionChanged(
+                elapsedTimeDescription: CharSequence,
+                durationDescription: CharSequence,
+            ) {
+                if (!SceneContainerFlag.isEnabled) return
+                seekBarObserver.updateContentDescription(
+                    elapsedTimeDescription,
+                    durationDescription,
+                )
+            }
+        }
+
     /**
      * Sets the listening state of the player.
      *
@@ -350,6 +364,7 @@
             }
             seekBarViewModel.removeScrubbingChangeListener(scrubbingChangeListener)
             seekBarViewModel.removeEnabledChangeListener(enabledChangeListener)
+            seekBarViewModel.removeContentDescriptionListener(seekbarDescriptionListener)
             seekBarViewModel.onDestroy()
         }
         mediaHostStatesManager.removeController(this)
@@ -653,6 +668,7 @@
         seekBarViewModel.attachTouchHandlers(mediaViewHolder.seekBar)
         seekBarViewModel.setScrubbingChangeListener(scrubbingChangeListener)
         seekBarViewModel.setEnabledChangeListener(enabledChangeListener)
+        seekBarViewModel.setContentDescriptionListener(seekbarDescriptionListener)
 
         val mediaCard = mediaViewHolder.player
         attach(mediaViewHolder.player)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
index 8744c5c..78a8cf8 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModel.kt
@@ -104,19 +104,20 @@
         )
         set(value) {
             val enabledChanged = value.enabled != field.enabled
+            field = value
             if (enabledChanged) {
                 enabledChangeListener?.onEnabledChanged(value.enabled)
             }
+            _progress.postValue(value)
+
             bgExecutor.execute {
                 val durationDescription = formatTimeContentDescription(value.duration)
                 val elapsedDescription =
                     value.elapsedTime?.let { formatTimeContentDescription(it) } ?: ""
-                field =
-                    value.copy(
-                        durationDescription = durationDescription,
-                        elapsedTimeDescription = elapsedDescription,
-                    )
-                _progress.postValue(field)
+                contentDescriptionListener?.onContentDescriptionChanged(
+                    elapsedDescription,
+                    durationDescription,
+                )
             }
         }
 
@@ -175,6 +176,7 @@
 
     private var scrubbingChangeListener: ScrubbingChangeListener? = null
     private var enabledChangeListener: EnabledChangeListener? = null
+    private var contentDescriptionListener: ContentDescriptionListener? = null
 
     /** Set to true when the user is touching the seek bar to change the position. */
     private var scrubbing = false
@@ -394,6 +396,16 @@
         }
     }
 
+    fun setContentDescriptionListener(listener: ContentDescriptionListener) {
+        contentDescriptionListener = listener
+    }
+
+    fun removeContentDescriptionListener(listener: ContentDescriptionListener) {
+        if (listener == contentDescriptionListener) {
+            contentDescriptionListener = null
+        }
+    }
+
     /** returns a pair of whether seekbar is enabled and the duration of media. */
     private fun getEnabledStateAndDuration(metadata: MediaMetadata?): Pair<Boolean, Int> {
         val duration = metadata?.getLong(MediaMetadata.METADATA_KEY_DURATION)?.toInt() ?: 0
@@ -468,6 +480,13 @@
         fun onEnabledChanged(enabled: Boolean)
     }
 
+    interface ContentDescriptionListener {
+        fun onContentDescriptionChanged(
+            elapsedTimeDescription: CharSequence,
+            durationDescription: CharSequence,
+        )
+    }
+
     private class SeekBarChangeListener(
         val viewModel: SeekBarViewModel,
         val falsingManager: FalsingManager,
@@ -639,7 +658,5 @@
         val duration: Int,
         /** whether seekBar is listening to progress updates */
         val listening: Boolean,
-        val elapsedTimeDescription: CharSequence = "",
-        val durationDescription: CharSequence = "",
     )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
index 7543e0f..f072388 100644
--- a/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/remedia/ui/compose/Media.kt
@@ -46,7 +46,6 @@
 import androidx.compose.foundation.interaction.PressInteraction
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Box
-import androidx.compose.foundation.layout.BoxWithConstraints
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
 import androidx.compose.foundation.layout.Spacer
@@ -55,7 +54,6 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
-import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.shape.CircleShape
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.material3.ButtonDefaults
@@ -75,6 +73,7 @@
 import androidx.compose.runtime.Stable
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.key
+import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateListOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
@@ -101,6 +100,7 @@
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.layout.ContentScale
 import androidx.compose.ui.layout.Layout
+import androidx.compose.ui.layout.layout
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.semantics.clearAndSetSemantics
 import androidx.compose.ui.semantics.contentDescription
@@ -110,6 +110,7 @@
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.util.fastForEach
 import androidx.compose.ui.util.fastForEachIndexed
+import androidx.compose.ui.util.fastRoundToInt
 import com.android.compose.PlatformButton
 import com.android.compose.PlatformIconButton
 import com.android.compose.PlatformOutlinedButton
@@ -138,6 +139,7 @@
 import com.android.systemui.media.remedia.ui.viewmodel.MediaSecondaryActionViewModel
 import com.android.systemui.media.remedia.ui.viewmodel.MediaViewModel
 import kotlin.math.max
+import kotlin.math.min
 
 /**
  * Renders a media controls UI element.
@@ -406,7 +408,7 @@
             )
     ) {
         // Always add the first/top row, regardless of presentation style.
-        BoxWithConstraints(modifier = Modifier.fillMaxWidth()) {
+        Box(modifier = Modifier.fillMaxWidth()) {
             // Icon.
             Icon(
                 icon = viewModel.icon,
@@ -418,9 +420,26 @@
                         .clip(CircleShape),
             )
 
+            var cardMaxWidth: Int by remember { mutableIntStateOf(0) }
             Row(
                 horizontalArrangement = Arrangement.spacedBy(8.dp),
-                modifier = Modifier.align(Alignment.TopEnd),
+                modifier =
+                    Modifier.align(Alignment.TopEnd)
+                        // Output switcher chips must each be limited to at most 40% of the maximum
+                        // width of the card.
+                        //
+                        // This saves the maximum possible width of the card so it can be referred
+                        // to by child custom layout code below.
+                        //
+                        // The assumption is that the row can be as wide as the entire card.
+                        .layout { measurable, constraints ->
+                            cardMaxWidth = constraints.maxWidth
+                            val placeable = measurable.measure(constraints)
+
+                            layout(placeable.measuredWidth, placeable.measuredHeight) {
+                                placeable.place(0, 0)
+                            }
+                        },
             ) {
                 viewModel.outputSwitcherChips.fastForEach { chip ->
                     OutputSwitcherChip(
@@ -433,9 +452,23 @@
                                 //
                                 // The underlying assumption is that there'll never be more than one
                                 // chip with text and one more icon-only chip. Only the one with
-                                // text
-                                // can ever end up being too wide.
-                                .widthIn(max = this@BoxWithConstraints.maxWidth * 0.4f),
+                                // text can ever end up being too wide.
+                                .layout { measurable, constraints ->
+                                    val placeable =
+                                        measurable.measure(
+                                            constraints.copy(
+                                                maxWidth =
+                                                    min(
+                                                        (cardMaxWidth * 0.4f).fastRoundToInt(),
+                                                        constraints.maxWidth,
+                                                    )
+                                            )
+                                        )
+
+                                    layout(placeable.measuredWidth, placeable.measuredHeight) {
+                                        placeable.place(0, 0)
+                                    }
+                                },
                     )
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionViewBinder.kt b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionViewBinder.kt
index c6e4db7..324a3ef 100644
--- a/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/mediaprojection/permission/BaseMediaProjectionPermissionViewBinder.kt
@@ -150,6 +150,13 @@
             titleTextView.isEnabled = true
         } else {
             errorTextView.visibility = View.VISIBLE
+            if (com.android.systemui.Flags.mediaProjectionGreyErrorText()) {
+                errorTextView.isEnabled = false
+                errorTextView.setTextColor(context.getColorStateList(R.color.menu_item_text))
+                errorTextView.setText(
+                    R.string.media_projection_entry_app_permission_dialog_single_app_not_supported
+                )
+            }
             titleTextView.isEnabled = false
         }
         return view
diff --git a/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt b/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
index 71cb745..68cd807 100644
--- a/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
+++ b/packages/SystemUI/src/com/android/systemui/model/SysUiState.kt
@@ -17,9 +17,9 @@
 
 import android.util.Log
 import android.view.Display
+import com.android.app.displaylib.PerDisplayInstanceProviderWithTeardown
 import com.android.systemui.Dumpable
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.display.data.repository.PerDisplayInstanceProviderWithTeardown
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.model.SysUiState.SysUiStateCallback
 import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
index 49fa3ba..88f679e 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarController.java
@@ -72,4 +72,8 @@
     /** @return {@link NavigationBar} on the default display. */
     @Nullable
     NavigationBar getDefaultNavigationBar();
+
+    /** @return {@link NavigationBar} for a specific display, or null if not available. */
+    @Nullable
+    NavigationBar getNavigationBar(int displayId);
 }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
index 45ff7f4..f096510 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerEmptyImpl.kt
@@ -54,4 +54,6 @@
     override fun isOverviewEnabled(displayId: Int) = false
 
     override fun getDefaultNavigationBar(): NavigationBar? = null
+
+    override fun getNavigationBar(displayId: Int): NavigationBar? = null
 }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
index 50d0a45..8fbf8b60 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarControllerImpl.java
@@ -469,7 +469,8 @@
         return (navBar == null) ? null : navBar.getView();
     }
 
-    private @Nullable NavigationBar getNavigationBar(int displayId) {
+    @Override
+    public @Nullable NavigationBar getNavigationBar(int displayId) {
         return mNavigationBars.get(displayId);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
index 914e0f7..39482be 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationBarModule.java
@@ -24,13 +24,16 @@
 import android.view.View;
 import android.view.WindowManager;
 
+import com.android.app.displaylib.PerDisplayRepository;
 import com.android.app.viewcapture.ViewCapture;
 import com.android.app.viewcapture.ViewCaptureAwareWindowManager;
 import com.android.systemui.dagger.qualifiers.DisplayId;
+import com.android.systemui.model.SysUiState;
 import com.android.systemui.navigationbar.NavigationBarComponent.NavigationBarScope;
 import com.android.systemui.navigationbar.views.NavigationBarFrame;
 import com.android.systemui.navigationbar.views.NavigationBarView;
 import com.android.systemui.res.R;
+import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround;
 
 import dagger.Lazy;
 import dagger.Module;
@@ -71,6 +74,20 @@
         return context.getSystemService(WindowManager.class);
     }
 
+    /** A SysUiState for the navigation bar display. */
+    @Provides
+    @NavigationBarScope
+    @DisplayId
+    static SysUiState provideSysUiState(@DisplayId Context context,
+            SysUiState defaultState,
+            PerDisplayRepository<SysUiState> repository) {
+        if (ShadeWindowGoesAround.isEnabled()) {
+            return repository.get(context.getDisplayId());
+        } else {
+            return defaultState;
+        }
+    }
+
     /** A ViewCaptureAwareWindowManager specific to the display's context. */
     @Provides
     @NavigationBarScope
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index 237ec7c..6cda192 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -22,6 +22,7 @@
 import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION;
 
 import static com.android.systemui.Flags.edgebackGestureHandlerGetRunningTasksBackground;
+import static com.android.systemui.Flags.predictiveBackDelayWmTransition;
 import static com.android.systemui.classifier.Classifier.BACK_GESTURE;
 import static com.android.systemui.navigationbar.gestural.Utilities.isTrackpadThreeFingerSwipe;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TOUCHPAD_GESTURES_DISABLED;
@@ -1182,6 +1183,9 @@
                         return;
                     } else if (dx > dy && dx > mTouchSlop) {
                         if (mAllowGesture) {
+                            if (!predictiveBackDelayWmTransition() && mBackAnimation != null) {
+                                mBackAnimation.onThresholdCrossed();
+                            }
                             if (mBackAnimation == null) {
                                 pilferPointers();
                             }
@@ -1197,7 +1201,8 @@
                 // forward touch
                 mEdgeBackPlugin.onMotionEvent(ev);
                 dispatchToBackAnimation(ev);
-                if (mBackAnimation != null && mThresholdCrossed && !mLastFrameThresholdCrossed) {
+                if (predictiveBackDelayWmTransition() && mBackAnimation != null
+                        && mThresholdCrossed && !mLastFrameThresholdCrossed) {
                     mBackAnimation.onThresholdCrossed();
                 }
             }
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
index f95f459..8b5b3ad 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBar.java
@@ -569,7 +569,7 @@
             NavigationModeController navigationModeController,
             StatusBarStateController statusBarStateController,
             StatusBarKeyguardViewManager statusBarKeyguardViewManager,
-            SysUiState sysUiFlagsContainer,
+            @DisplayId SysUiState sysUiFlagsContainer,
             UserTracker userTracker,
             CommandQueue commandQueue,
             Optional<Pip> pipOptional,
@@ -1694,7 +1694,7 @@
                         (mNavbarFlags & NAVBAR_BACK_DISMISS_IME) != 0)
                 .setFlag(SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY,
                         allowSystemGestureIgnoringBarVisibility())
-                .commitUpdate(mDisplayId);
+                .commitUpdate();
     }
 
     private void updateAssistantEntrypoints(boolean assistantAvailable,
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
index 36cb8fa..cbc4c26 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/views/NavigationBarView.java
@@ -740,15 +740,13 @@
 
     /** */
     public void updateDisabledSystemUiStateFlags(SysUiState sysUiState) {
-        int displayId = mContext.getDisplayId();
-
         sysUiState.setFlag(SYSUI_STATE_OVERVIEW_DISABLED,
                         (mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0)
                 .setFlag(SYSUI_STATE_HOME_DISABLED,
                         (mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0)
                 .setFlag(SYSUI_STATE_SEARCH_DISABLED,
                         (mDisabledFlags & View.STATUS_BAR_DISABLE_SEARCH) != 0)
-                .commitUpdate(displayId);
+                .commitUpdate();
     }
 
     public void setInScreenPinning(boolean active) {
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
index 5d54656..fb3271e 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskModule.kt
@@ -32,16 +32,16 @@
 import com.android.systemui.qs.shared.model.TileCategory
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.NotesTile
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
-import com.android.systemui.qs.tiles.impl.notes.domain.NotesTileMapper
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel
 import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileDataInteractor
 import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
-import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
+import com.android.systemui.qs.tiles.impl.notes.ui.mapper.NotesTileMapper
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
diff --git a/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java
deleted file mode 100644
index ea2bf6a..0000000
--- a/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.process.condition;
-
-import com.android.systemui.dagger.qualifiers.Application;
-import com.android.systemui.process.ProcessWrapper;
-import com.android.systemui.shared.condition.Condition;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import javax.inject.Inject;
-
-/**
- * {@link SystemProcessCondition} checks to make sure the current process is being ran by the
- * System User.
- */
-public class SystemProcessCondition extends Condition {
-    private final ProcessWrapper mProcessWrapper;
-
-    @Inject
-    public SystemProcessCondition(@Application CoroutineScope scope,
-            ProcessWrapper processWrapper) {
-        super(scope);
-        mProcessWrapper = processWrapper;
-    }
-
-    @Override
-    protected void start() {
-        updateCondition(mProcessWrapper.isSystemUser());
-    }
-
-    @Override
-    protected void stop() {
-    }
-
-    @Override
-    public int getStartStrategy() {
-        return START_EAGERLY;
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.kt b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.kt
new file mode 100644
index 0000000..9a424c3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/process/condition/SystemProcessCondition.kt
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.process.condition
+
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.process.ProcessWrapper
+import com.android.systemui.shared.condition.Condition
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+
+/**
+ * [SystemProcessCondition] checks to make sure the current process is being ran by the System User.
+ */
+class SystemProcessCondition
+@Inject
+constructor(@Application scope: CoroutineScope, private val processWrapper: ProcessWrapper) :
+    Condition(scope) {
+    override val startStrategy: Int
+        get() = START_EAGERLY
+
+    override suspend fun start() {
+        updateCondition(processWrapper.isSystemUser)
+    }
+
+    override fun stop() {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
index a4386de..05a60a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/composefragment/QSFragmentCompose.kt
@@ -18,7 +18,6 @@
 
 import android.annotation.SuppressLint
 import android.content.Context
-import android.content.res.Configuration
 import android.graphics.PointF
 import android.graphics.Rect
 import android.os.Bundle
@@ -49,7 +48,6 @@
 import androidx.compose.foundation.verticalScroll
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
-import androidx.compose.runtime.CompositionLocalProvider
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
@@ -72,8 +70,6 @@
 import androidx.compose.ui.layout.positionInRoot
 import androidx.compose.ui.layout.positionOnScreen
 import androidx.compose.ui.platform.ComposeView
-import androidx.compose.ui.platform.LocalConfiguration
-import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.semantics.CustomAccessibilityAction
@@ -255,7 +251,7 @@
 
     @Composable
     private fun Content() {
-        PlatformTheme(isDarkTheme = true /* Delete AlwaysDarkMode when removing this */) {
+        PlatformTheme {
             ProvideShortcutHelperIndication(interactionsConfig = interactionsConfig()) {
                 // TODO(b/389985793): Make sure that there is no coroutine work or recompositions
                 // happening when alwaysCompose is true but isQsVisibleAndAnyShadeExpanded is false.
@@ -747,25 +743,22 @@
                         )
                         val BrightnessSlider =
                             @Composable {
-                                AlwaysDarkMode {
-                                    Box(
-                                        Modifier.systemGestureExclusionInShade(
-                                            enabled = {
-                                                layoutState.transitionState is TransitionState.Idle
-                                            }
-                                        )
-                                    ) {
-                                        BrightnessSliderContainer(
-                                            viewModel =
-                                                containerViewModel.brightnessSliderViewModel,
-                                            containerColors =
-                                                ContainerColors(
-                                                    Color.Transparent,
-                                                    ContainerColors.defaultContainerColor,
-                                                ),
-                                            modifier = Modifier.fillMaxWidth(),
-                                        )
-                                    }
+                                Box(
+                                    Modifier.systemGestureExclusionInShade(
+                                        enabled = {
+                                            layoutState.transitionState is TransitionState.Idle
+                                        }
+                                    )
+                                ) {
+                                    BrightnessSliderContainer(
+                                        viewModel = containerViewModel.brightnessSliderViewModel,
+                                        containerColors =
+                                            ContainerColors(
+                                                Color.Transparent,
+                                                ContainerColors.defaultContainerColor,
+                                            ),
+                                        modifier = Modifier.fillMaxWidth(),
+                                    )
                                 }
                             }
                         val TileGrid =
@@ -1243,28 +1236,3 @@
 
 private inline val alwaysCompose
     get() = Flags.alwaysComposeQsUiFragment()
-
-/**
- * Forces the configuration and themes to be dark theme. This is needed in order to have
- * [colorResource] retrieve the dark mode colors.
- *
- * This should be removed when we remove the force dark mode in [PlatformTheme] at the root of the
- * compose hierarchy.
- */
-@Composable
-private fun AlwaysDarkMode(content: @Composable () -> Unit) {
-    val currentConfig = LocalConfiguration.current
-    val darkConfig =
-        Configuration(currentConfig).apply {
-            uiMode =
-                (uiMode and (Configuration.UI_MODE_NIGHT_MASK.inv())) or
-                    Configuration.UI_MODE_NIGHT_YES
-        }
-    val newContext = LocalContext.current.createConfigurationContext(darkConfig)
-    CompositionLocalProvider(
-        LocalConfiguration provides darkConfig,
-        LocalContext provides newContext,
-    ) {
-        content()
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
index e2a3916..f1193fa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModuleBase.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.qs.panels.dagger.PanelsModule
 import com.android.systemui.qs.pipeline.dagger.QSPipelineModule
 import com.android.systemui.qs.tileimpl.QSTileImpl
-import com.android.systemui.qs.tiles.di.QSTilesModule
+import com.android.systemui.qs.tiles.base.ui.model.QSTilesModule
 import com.android.systemui.qs.ui.adapter.QSSceneAdapter
 import com.android.systemui.qs.ui.adapter.QSSceneAdapterImpl
 import dagger.Binds
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
index a2cee3b..ec0a754 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractor.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.qs.panels.domain.model.EditTilesModel
 import com.android.systemui.qs.panels.shared.model.EditTileData
 import com.android.systemui.qs.shared.model.TileCategory
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
 import javax.inject.Inject
 
 @SysUISingleton
@@ -50,7 +50,7 @@
                         it,
                         Icon.Resource(
                             config.uiConfig.iconRes,
-                            ContentDescription.Resource(config.uiConfig.labelRes)
+                            ContentDescription.Resource(config.uiConfig.labelRes),
                         ),
                         Text.Resource(config.uiConfig.labelRes),
                         null,
@@ -61,7 +61,7 @@
                         it,
                         Icon.Resource(
                             android.R.drawable.star_on,
-                            ContentDescription.Loaded(it.spec)
+                            ContentDescription.Loaded(it.spec),
                         ),
                         Text.Loaded(it.spec),
                         null,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractor.kt
index 00cd96c..46a6e4a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractor.kt
@@ -19,14 +19,14 @@
 import android.os.UserHandle
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
+import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.map
-import javax.inject.Inject
 
 /**
  * Uses the [QSTileAvailabilityInteractor] from the new tiles to provide a map of availability, for
@@ -38,23 +38,26 @@
 class NewTilesAvailabilityInteractor
 @Inject
 constructor(
-        private val availabilityInteractors:
-                Map<String, @JvmSuppressWildcards QSTileAvailabilityInteractor>,
-        userRepository: UserRepository,
+    private val availabilityInteractors:
+        Map<String, @JvmSuppressWildcards QSTileAvailabilityInteractor>,
+    userRepository: UserRepository,
 ) {
     val newTilesAvailable: Flow<Map<TileSpec, Boolean>> =
-            userRepository.selectedUserInfo.map { it.id }
-                    .flatMapLatestConflated { userId ->
-                        if (availabilityInteractors.isEmpty()) {
-                            flowOf(emptyMap())
-                        } else {
-                            combine(availabilityInteractors.map { (spec, interactor) ->
-                                interactor.availability(UserHandle.of(userId)).map {
-                                    TileSpec.create(spec) to it
-                                }
-                            }) {
-                                it.toMap()
+        userRepository.selectedUserInfo
+            .map { it.id }
+            .flatMapLatestConflated { userId ->
+                if (availabilityInteractors.isEmpty()) {
+                    flowOf(emptyMap())
+                } else {
+                    combine(
+                        availabilityInteractors.map { (spec, interactor) ->
+                            interactor.availability(UserHandle.of(userId)).map {
+                                TileSpec.create(spec) to it
                             }
                         }
+                    ) {
+                        it.toMap()
                     }
+                }
+            }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
index 22971a9..a7ebb22 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/PaginatedGridLayout.kt
@@ -88,7 +88,11 @@
         LaunchedEffect(listening, pagerState) {
             snapshotFlow { listening() }
                 .collect {
-                    if (!listening()) {
+                    // Whenever we go from not listening to listening, we should be in the first
+                    // page. If we did this when going from listening to not listening, opening
+                    // edit mode in second page will cause it to go to first page during the
+                    // transition.
+                    if (listening()) {
                         pagerState.scrollToPage(0)
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
index d20b360..728652e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/QuickQuickSettings.kt
@@ -82,6 +82,7 @@
                         viewModel.tileHapticsViewModelFactoryProvider,
                     // There should be no QuickQuickSettings when the details view is enabled.
                     detailsViewModel = null,
+                    isVisible = listening,
                 )
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
index d40ecc9..1176095 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/TileDetails.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.qs.panels.ui.compose
 
+import androidx.compose.foundation.background
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.Row
@@ -23,11 +24,13 @@
 import androidx.compose.foundation.layout.fillMaxWidth
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.width
 import androidx.compose.material.icons.Icons
 import androidx.compose.material.icons.automirrored.filled.ArrowBack
 import androidx.compose.material.icons.filled.Settings
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
+import androidx.compose.material3.IconButtonDefaults
 import androidx.compose.material3.LocalContentColor
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.Text
@@ -63,6 +66,7 @@
 
     val title = tileDetailedViewModel.title
     val subTitle = tileDetailedViewModel.subTitle
+    val colors = MaterialTheme.colorScheme
 
     Column(
         modifier =
@@ -70,20 +74,33 @@
                 .fillMaxWidth()
                 // The height of the details view is TBD.
                 .fillMaxHeight()
+                .background(color = colors.onPrimary)
     ) {
         CompositionLocalProvider(
             value = LocalContentColor provides MaterialTheme.colorScheme.onSurfaceVariant
         ) {
             Row(
-                modifier = Modifier.fillMaxWidth(),
+                modifier = Modifier
+                    .fillMaxWidth()
+                    .padding(
+                        start = TileDetailsDefaults.TitleRowStart,
+                        top = TileDetailsDefaults.TitleRowTop,
+                        end = TileDetailsDefaults.TitleRowEnd,
+                        bottom = TileDetailsDefaults.TitleRowBottom
+                    ),
                 horizontalArrangement = Arrangement.SpaceBetween,
                 verticalAlignment = Alignment.CenterVertically,
             ) {
                 IconButton(
                     onClick = { detailsViewModel.closeDetailedView() },
+                    colors = IconButtonDefaults.iconButtonColors(
+                        contentColor = colors.onSurface
+                    ),
                     modifier =
-                        Modifier.align(Alignment.CenterVertically)
+                        Modifier
+                            .align(Alignment.CenterVertically)
                             .height(TileDetailsDefaults.IconHeight)
+                            .width(TileDetailsDefaults.IconWidth)
                             .padding(start = TileDetailsDefaults.IconPadding),
                 ) {
                     Icon(
@@ -96,13 +113,19 @@
                     text = title,
                     modifier = Modifier.align(Alignment.CenterVertically),
                     textAlign = TextAlign.Center,
-                    style = MaterialTheme.typography.titleLarge,
+                    style = MaterialTheme.typography.titleMedium,
+                    color = colors.onSurface,
                 )
                 IconButton(
                     onClick = { tileDetailedViewModel.clickOnSettingsButton() },
+                    colors = IconButtonDefaults.iconButtonColors(
+                        contentColor = colors.onSurface
+                    ),
                     modifier =
-                        Modifier.align(Alignment.CenterVertically)
+                        Modifier
+                            .align(Alignment.CenterVertically)
                             .height(TileDetailsDefaults.IconHeight)
+                            .width(TileDetailsDefaults.IconWidth)
                             .padding(end = TileDetailsDefaults.IconPadding),
                 ) {
                     Icon(
@@ -116,7 +139,8 @@
                 text = subTitle,
                 modifier = Modifier.fillMaxWidth(),
                 textAlign = TextAlign.Center,
-                style = MaterialTheme.typography.titleSmall,
+                style = MaterialTheme.typography.bodySmall,
+                color = colors.onSurfaceVariant,
             )
         }
         MapTileDetailsContent(tileDetailedViewModel)
@@ -135,6 +159,11 @@
 }
 
 private object TileDetailsDefaults {
-    val IconHeight = 48.dp
+    val IconHeight = 24.dp
+    val IconWidth = 24.dp
     val IconPadding = 4.dp
+    val TitleRowStart = 14.dp
+    val TitleRowTop = 22.dp
+    val TitleRowEnd = 20.dp
+    val TitleRowBottom = 8.dp
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
index 50012ab..699778f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/CommonTile.kt
@@ -39,12 +39,14 @@
 import androidx.compose.foundation.layout.width
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.foundation.text.BasicText
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.DisposableEffect
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.key
+import androidx.compose.runtime.mutableIntStateOf
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.runtime.setValue
@@ -102,6 +104,7 @@
     sideDrawable: Drawable?,
     colors: TileColors,
     squishiness: () -> Float,
+    isVisible: () -> Boolean = { true },
     accessibilityUiState: AccessibilityUiState? = null,
     iconShape: RoundedCornerShape = RoundedCornerShape(CommonTileDefaults.InactiveCornerRadius),
     toggleClick: (() -> Unit)? = null,
@@ -158,6 +161,7 @@
             secondaryLabel = secondaryLabel,
             colors = colors,
             accessibilityUiState = accessibilityUiState,
+            isVisible = isVisible,
         )
 
         if (sideDrawable != null) {
@@ -170,12 +174,14 @@
     }
 }
 
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 fun LargeTileLabels(
     label: String,
     secondaryLabel: String?,
     colors: TileColors,
     modifier: Modifier = Modifier,
+    isVisible: () -> Boolean = { true },
     accessibilityUiState: AccessibilityUiState? = null,
 ) {
     val animatedLabelColor by animateColorAsState(colors.label, label = "QSTileLabelColor")
@@ -184,14 +190,16 @@
     Column(verticalArrangement = Arrangement.Center, modifier = modifier.fillMaxHeight()) {
         TileLabel(
             text = label,
-            style = MaterialTheme.typography.labelLarge,
+            style = MaterialTheme.typography.titleSmallEmphasized,
             color = { animatedLabelColor },
+            isVisible = isVisible,
         )
         if (!TextUtils.isEmpty(secondaryLabel)) {
             TileLabel(
                 secondaryLabel ?: "",
                 color = { animatedSecondaryLabelColor },
-                style = MaterialTheme.typography.bodyMedium,
+                style = MaterialTheme.typography.labelMedium,
+                isVisible = isVisible,
                 modifier =
                     Modifier.thenIf(
                         accessibilityUiState?.stateDescription?.contains(secondaryLabel ?: "") ==
@@ -277,36 +285,50 @@
     color: ColorProducer,
     style: TextStyle,
     modifier: Modifier = Modifier,
+    isVisible: () -> Boolean = { true },
 ) {
+    var textSize by remember { mutableIntStateOf(0) }
+
     BasicText(
         text = text,
         color = color,
         style = style,
         maxLines = 1,
+        onTextLayout = { textSize = it.size.width },
         modifier =
             modifier
                 .fillMaxWidth()
-                .graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen }
+                .graphicsLayer {
+                    if (textSize > size.width) {
+                        compositingStrategy = CompositingStrategy.Offscreen
+                    }
+                }
                 .drawWithContent {
                     drawContent()
-                    // Draw a blur over the end of the text
-                    val edgeWidthPx = TileLabelBlurWidth.toPx()
-                    drawRect(
-                        topLeft = Offset(size.width - edgeWidthPx, 0f),
-                        size = Size(edgeWidthPx, size.height),
-                        brush =
-                            Brush.horizontalGradient(
-                                colors = listOf(Color.Transparent, Color.Black),
-                                startX = size.width,
-                                endX = size.width - edgeWidthPx,
-                            ),
-                        blendMode = BlendMode.DstIn,
-                    )
+                    if (textSize > size.width) {
+                        // Draw a blur over the end of the text
+                        val edgeWidthPx = TileLabelBlurWidth.toPx()
+                        drawRect(
+                            topLeft = Offset(size.width - edgeWidthPx, 0f),
+                            size = Size(edgeWidthPx, size.height),
+                            brush =
+                                Brush.horizontalGradient(
+                                    colors = listOf(Color.Transparent, Color.Black),
+                                    startX = size.width,
+                                    endX = size.width - edgeWidthPx,
+                                ),
+                            blendMode = BlendMode.DstIn,
+                        )
+                    }
                 }
-                .basicMarquee(
-                    iterations = TILE_MARQUEE_ITERATIONS,
-                    initialDelayMillis = TILE_INITIAL_DELAY_MILLIS,
-                ),
+                .thenIf(isVisible()) {
+                    // Only apply the marquee when the label is visible, which is needed for the
+                    // always composed QS
+                    Modifier.basicMarquee(
+                        iterations = TILE_MARQUEE_ITERATIONS,
+                        initialDelayMillis = TILE_INITIAL_DELAY_MILLIS,
+                    )
+                },
     )
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
index eb0947f..46f05d0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/EditTile.kt
@@ -63,7 +63,9 @@
 import androidx.compose.material.icons.automirrored.filled.ArrowBack
 import androidx.compose.material.icons.filled.Add
 import androidx.compose.material.icons.filled.Clear
+import androidx.compose.material3.ButtonDefaults
 import androidx.compose.material3.ExperimentalMaterial3Api
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
 import androidx.compose.material3.Icon
 import androidx.compose.material3.IconButton
 import androidx.compose.material3.LocalContentColor
@@ -89,6 +91,7 @@
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.draw.clip
 import androidx.compose.ui.draw.drawBehind
+import androidx.compose.ui.geometry.CornerRadius
 import androidx.compose.ui.geometry.Offset
 import androidx.compose.ui.geometry.isSpecified
 import androidx.compose.ui.graphics.Color
@@ -107,14 +110,15 @@
 import androidx.compose.ui.semantics.customActions
 import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.semantics.stateDescription
+import androidx.compose.ui.text.style.Hyphens
 import androidx.compose.ui.text.style.TextAlign
 import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
-import androidx.compose.ui.unit.sp
 import androidx.compose.ui.util.fastMap
 import com.android.compose.gesture.effect.rememberOffsetOverscrollEffectFactory
 import com.android.compose.modifiers.height
+import com.android.compose.theme.LocalAndroidColorScheme
 import com.android.systemui.common.ui.compose.load
 import com.android.systemui.qs.panels.shared.model.SizedTile
 import com.android.systemui.qs.panels.shared.model.SizedTileImpl
@@ -132,6 +136,7 @@
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.AUTO_SCROLL_SPEED
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.AvailableTilesGridMinHeight
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.CurrentTilesGridPadding
+import com.android.systemui.qs.panels.ui.compose.infinitegrid.EditModeTileDefaults.GridBackgroundCornerRadius
 import com.android.systemui.qs.panels.ui.compose.selection.InteractiveTileContainer
 import com.android.systemui.qs.panels.ui.compose.selection.MutableSelectionState
 import com.android.systemui.qs.panels.ui.compose.selection.ResizingState
@@ -161,17 +166,31 @@
 
 object TileType
 
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 private fun EditModeTopBar(onStopEditing: () -> Unit, onReset: (() -> Unit)?) {
-
+    val primaryContainerColor = MaterialTheme.colorScheme.primaryContainer
     TopAppBar(
-        colors = TopAppBarDefaults.topAppBarColors(containerColor = Color.Transparent),
-        title = { Text(text = stringResource(id = R.string.qs_edit)) },
+        colors =
+            TopAppBarDefaults.topAppBarColors(
+                containerColor = Color.Transparent,
+                titleContentColor = MaterialTheme.colorScheme.onSurface,
+            ),
+        title = {
+            Text(
+                text = stringResource(id = R.string.qs_edit_tiles),
+                style = MaterialTheme.typography.titleLargeEmphasized,
+                modifier = Modifier.padding(start = 24.dp),
+            )
+        },
         navigationIcon = {
-            IconButton(onClick = onStopEditing) {
+            IconButton(
+                onClick = onStopEditing,
+                modifier = Modifier.drawBehind { drawCircle(primaryContainerColor) },
+            ) {
                 Icon(
                     Icons.AutoMirrored.Filled.ArrowBack,
+                    tint = MaterialTheme.colorScheme.onSurface,
                     contentDescription =
                         stringResource(id = com.android.internal.R.string.action_bar_up_description),
                 )
@@ -179,14 +198,26 @@
         },
         actions = {
             if (onReset != null) {
-                TextButton(onClick = onReset) {
-                    Text(stringResource(id = com.android.internal.R.string.reset))
+                TextButton(
+                    onClick = onReset,
+                    colors =
+                        ButtonDefaults.textButtonColors(
+                            containerColor = MaterialTheme.colorScheme.primary,
+                            contentColor = MaterialTheme.colorScheme.onPrimary,
+                        ),
+                ) {
+                    Text(
+                        text = stringResource(id = com.android.internal.R.string.reset),
+                        style = MaterialTheme.typography.labelLarge,
+                    )
                 }
             }
         },
+        modifier = Modifier.padding(vertical = 8.dp),
     )
 }
 
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 fun DefaultEditTileGrid(
     listState: EditTileListState,
@@ -247,7 +278,7 @@
                     targetState = listState.dragInProgress || selectionState.selected,
                     label = "QSEditHeader",
                     contentAlignment = Alignment.Center,
-                    modifier = Modifier.fillMaxWidth().heightIn(min = 80.dp),
+                    modifier = Modifier.fillMaxWidth().heightIn(min = 48.dp),
                 ) { showRemoveTarget ->
                     EditGridHeader {
                         if (showRemoveTarget) {
@@ -258,7 +289,9 @@
                                 }
                             }
                         } else {
-                            Text(text = stringResource(id = R.string.drag_to_rearrange_tiles))
+                            EditGridCenteredText(
+                                text = stringResource(id = R.string.drag_to_rearrange_tiles)
+                            )
                         }
                     }
                 }
@@ -292,10 +325,6 @@
                                 spacedBy(dimensionResource(id = R.dimen.qs_label_container_margin)),
                             modifier = modifier.fillMaxSize(),
                         ) {
-                            EditGridHeader {
-                                Text(text = stringResource(id = R.string.drag_to_add_tiles))
-                            }
-
                             val availableTiles = remember {
                                 mutableStateListOf<AvailableTileGridCell>().apply {
                                     addAll(toAvailableTiles(listState.tiles, otherTiles))
@@ -374,14 +403,17 @@
     modifier: Modifier = Modifier,
     content: @Composable BoxScope.() -> Unit,
 ) {
-    CompositionLocalProvider(
-        LocalContentColor provides MaterialTheme.colorScheme.onBackground.copy(alpha = .5f)
-    ) {
+    CompositionLocalProvider(LocalContentColor provides MaterialTheme.colorScheme.onSurface) {
         Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxWidth()) { content() }
     }
 }
 
 @Composable
+private fun EditGridCenteredText(text: String, modifier: Modifier = Modifier) {
+    Text(text = text, style = MaterialTheme.typography.titleSmall, modifier = modifier)
+}
+
+@Composable
 private fun RemoveTileTarget(onClick: () -> Unit) {
     Row(
         verticalAlignment = Alignment.CenterVertically,
@@ -423,6 +455,7 @@
             listState.tiles.fastMap { Pair(it, BounceableTileViewModel()) }
         }
 
+    val primaryColor = MaterialTheme.colorScheme.primary
     TileLazyGrid(
         state = gridState,
         columns = GridCells.Fixed(columns),
@@ -431,9 +464,9 @@
             Modifier.fillMaxWidth()
                 .height { totalHeight.roundToPx() }
                 .border(
-                    width = 1.dp,
-                    color = MaterialTheme.colorScheme.onBackground.copy(alpha = .5f),
-                    shape = RoundedCornerShape((TileHeight / 2) + CurrentTilesGridPadding),
+                    width = 2.dp,
+                    color = primaryColor,
+                    shape = RoundedCornerShape(GridBackgroundCornerRadius),
                 )
                 .dragAndDropTileList(gridState, { gridContentOffset }, listState) { spec ->
                     onSetTiles(currentListState.tileSpecs())
@@ -442,6 +475,13 @@
                 .onGloballyPositioned { coordinates ->
                     gridContentOffset = coordinates.positionInRoot()
                 }
+                .drawBehind {
+                    drawRoundRect(
+                        primaryColor,
+                        cornerRadius = CornerRadius(GridBackgroundCornerRadius.toPx()),
+                        alpha = .15f,
+                    )
+                }
                 .testTag(CURRENT_TILES_GRID_TEST_TAG),
     ) {
         EditTiles(cells, listState, selectionState, coroutineScope, largeTilesSpan, onRemoveTile) {
@@ -459,6 +499,7 @@
     }
 }
 
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 private fun AvailableTileGrid(
     tiles: List<AvailableTileGridCell>,
@@ -472,7 +513,6 @@
         remember(tiles.fastMap { it.tile.category }, tiles.fastMap { it.tile.label }) {
             groupAndSort(tiles)
         }
-    val labelColors = EditModeTileDefaults.editTileColors()
 
     // Available tiles
     Column(
@@ -483,32 +523,45 @@
     ) {
         groupedTiles.forEach { (category, tiles) ->
             key(category) {
-                Text(
-                    text = category.label.load() ?: "",
-                    fontSize = 20.sp,
-                    color = labelColors.label,
+                val surfaceColor = MaterialTheme.colorScheme.surface
+                Column(
+                    verticalArrangement = spacedBy(16.dp),
                     modifier =
-                        Modifier.fillMaxWidth().padding(start = 16.dp, bottom = 8.dp, top = 8.dp),
-                )
-                tiles.chunked(columns).forEach { row ->
-                    Row(
-                        horizontalArrangement = spacedBy(TileArrangementPadding),
-                        modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
-                    ) {
-                        row.forEach { tileGridCell ->
-                            key(tileGridCell.key) {
-                                AvailableTileGridCell(
-                                    cell = tileGridCell,
-                                    dragAndDropState = dragAndDropState,
-                                    selectionState = selectionState,
-                                    onAddTile = onAddTile,
-                                    modifier = Modifier.weight(1f).fillMaxHeight(),
+                        Modifier.drawBehind {
+                                drawRoundRect(
+                                    surfaceColor,
+                                    cornerRadius = CornerRadius(GridBackgroundCornerRadius.toPx()),
+                                    alpha = .32f,
                                 )
                             }
-                        }
+                            .padding(16.dp),
+                ) {
+                    Text(
+                        text = category.label.load() ?: "",
+                        style = MaterialTheme.typography.titleMediumEmphasized,
+                        color = MaterialTheme.colorScheme.onSurface,
+                        modifier = Modifier.fillMaxWidth().padding(start = 8.dp, bottom = 16.dp),
+                    )
+                    tiles.chunked(columns).forEach { row ->
+                        Row(
+                            horizontalArrangement = spacedBy(TileArrangementPadding),
+                            modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Max),
+                        ) {
+                            row.forEach { tileGridCell ->
+                                key(tileGridCell.key) {
+                                    AvailableTileGridCell(
+                                        cell = tileGridCell,
+                                        dragAndDropState = dragAndDropState,
+                                        selectionState = selectionState,
+                                        onAddTile = onAddTile,
+                                        modifier = Modifier.weight(1f).fillMaxHeight(),
+                                    )
+                                }
+                            }
 
-                        // Spacers for incomplete rows
-                        repeat(columns - row.size) { Spacer(modifier = Modifier.weight(1f)) }
+                            // Spacers for incomplete rows
+                            repeat(columns - row.size) { Spacer(modifier = Modifier.weight(1f)) }
+                        }
                     }
                 }
             }
@@ -698,6 +751,7 @@
     }
 }
 
+@OptIn(ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 private fun AvailableTileGridCell(
     cell: AvailableTileGridCell,
@@ -764,7 +818,8 @@
                 color = colors.label,
                 overflow = TextOverflow.Ellipsis,
                 textAlign = TextAlign.Center,
-                modifier = Modifier.align(Alignment.Center),
+                style = MaterialTheme.typography.labelMedium.copy(hyphens = Hyphens.Auto),
+                modifier = Modifier.align(Alignment.TopCenter),
             )
         }
     }
@@ -864,15 +919,16 @@
     const val AUTO_SCROLL_SPEED = 2 // 2ms per pixel
     val CurrentTilesGridPadding = 10.dp
     val AvailableTilesGridMinHeight = 200.dp
+    val GridBackgroundCornerRadius = 42.dp
 
     @Composable
     fun editTileColors(): TileColors =
         TileColors(
-            background = MaterialTheme.colorScheme.surfaceVariant,
-            iconBackground = MaterialTheme.colorScheme.surfaceVariant,
-            label = MaterialTheme.colorScheme.onSurfaceVariant,
-            secondaryLabel = MaterialTheme.colorScheme.onSurfaceVariant,
-            icon = MaterialTheme.colorScheme.onSurfaceVariant,
+            background = LocalAndroidColorScheme.current.surfaceEffect2,
+            iconBackground = Color.Transparent,
+            label = MaterialTheme.colorScheme.onSurface,
+            secondaryLabel = MaterialTheme.colorScheme.onSurface,
+            icon = MaterialTheme.colorScheme.onSurface,
         )
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
index 6236ada..984343a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/InfiniteGridLayout.kt
@@ -78,8 +78,15 @@
             }
 
         val columns = columnsWithMediaViewModel.columns
+        val largeTiles by iconTilesViewModel.largeTilesState
         val largeTilesSpan by iconTilesViewModel.largeTilesSpanState
-        val sizedTiles = tiles.map { SizedTileImpl(it, it.spec.width(largeTilesSpan)) }
+        // Tiles or largeTiles may be updated while this is composed, so listen to any changes
+        val sizedTiles =
+            remember(tiles, largeTiles, largeTilesSpan) {
+                tiles.map {
+                    SizedTileImpl(it, if (largeTiles.contains(it.spec)) largeTilesSpan else 1)
+                }
+            }
         val bounceables =
             remember(sizedTiles) { List(sizedTiles.size) { BounceableTileViewModel() } }
         val squishiness by viewModel.squishinessViewModel.squishiness.collectAsStateWithLifecycle()
@@ -112,6 +119,7 @@
                             isLastInRow = isLastInColumn,
                         ),
                     detailsViewModel = detailsViewModel,
+                    isVisible = listening,
                 )
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
index bf63c3858..e247182 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/infinitegrid/Tile.kt
@@ -25,6 +25,7 @@
 import android.service.quicksettings.Tile.STATE_INACTIVE
 import androidx.compose.animation.animateColorAsState
 import androidx.compose.animation.core.animateDpAsState
+import androidx.compose.animation.core.animateFloatAsState
 import androidx.compose.foundation.ExperimentalFoundationApi
 import androidx.compose.foundation.background
 import androidx.compose.foundation.combinedClickable
@@ -59,6 +60,7 @@
 import androidx.compose.ui.geometry.Size
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Shape
+import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.platform.LocalConfiguration
 import androidx.compose.ui.platform.LocalResources
 import androidx.compose.ui.semantics.Role
@@ -74,7 +76,9 @@
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.compose.animation.Expandable
 import com.android.compose.animation.bounceable
+import com.android.compose.animation.rememberExpandableController
 import com.android.compose.modifiers.thenIf
+import com.android.compose.theme.LocalAndroidColorScheme
 import com.android.systemui.Flags
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.Icon
@@ -135,6 +139,7 @@
     bounceableInfo: BounceableInfo,
     tileHapticsViewModelFactoryProvider: TileHapticsViewModelFactoryProvider,
     modifier: Modifier = Modifier,
+    isVisible: () -> Boolean = { true },
     detailsViewModel: DetailsViewModel?,
 ) {
     trace(tile.traceName) {
@@ -165,6 +170,7 @@
         // TODO(b/361789146): Draw the shapes instead of clipping
         val tileShape by TileDefaults.animateTileShapeAsState(uiState.state)
         val animatedColor by animateColorAsState(colors.background, label = "QSTileBackgroundColor")
+        val animatedAlpha by animateFloatAsState(colors.alpha, label = "QSTileAlpha")
 
         TileExpandable(
             color = { animatedColor },
@@ -181,7 +187,8 @@
                         nextBounceable = currentBounceableInfo.nextTile,
                         orientation = Orientation.Horizontal,
                         bounceEnd = currentBounceableInfo.bounceEnd,
-                    ),
+                    )
+                    .graphicsLayer { alpha = animatedAlpha },
         ) { expandable ->
             val longClick: (() -> Unit)? =
                 {
@@ -243,6 +250,7 @@
                         onLongClick = longClick,
                         accessibilityUiState = uiState.accessibilityUiState,
                         squishiness = squishiness,
+                        isVisible = isVisible,
                     )
                 }
             }
@@ -260,8 +268,7 @@
     content: @Composable (Expandable) -> Unit,
 ) {
     Expandable(
-        color = color(),
-        shape = shape,
+        controller = rememberExpandableController(color = color, shape = shape),
         modifier = modifier.clip(shape).verticalSquish(squishiness),
         useModifierBasedImplementation = true,
     ) {
@@ -370,6 +377,7 @@
     val label: Color,
     val secondaryLabel: Color,
     val icon: Color,
+    val alpha: Float = 1f,
 )
 
 private object TileDefaults {
@@ -393,10 +401,10 @@
     @ReadOnlyComposable
     fun activeDualTargetTileColors(): TileColors =
         TileColors(
-            background = MaterialTheme.colorScheme.surfaceVariant,
+            background = LocalAndroidColorScheme.current.surfaceEffect2,
             iconBackground = MaterialTheme.colorScheme.primary,
-            label = MaterialTheme.colorScheme.onSurfaceVariant,
-            secondaryLabel = MaterialTheme.colorScheme.onSurfaceVariant,
+            label = MaterialTheme.colorScheme.onSurface,
+            secondaryLabel = MaterialTheme.colorScheme.onSurface,
             icon = MaterialTheme.colorScheme.onPrimary,
         )
 
@@ -404,30 +412,19 @@
     @ReadOnlyComposable
     fun inactiveDualTargetTileColors(): TileColors =
         TileColors(
-            background = MaterialTheme.colorScheme.surfaceVariant,
-            iconBackground = MaterialTheme.colorScheme.surfaceContainerHighest,
-            label = MaterialTheme.colorScheme.onSurfaceVariant,
-            secondaryLabel = MaterialTheme.colorScheme.onSurfaceVariant,
-            icon = MaterialTheme.colorScheme.onSurfaceVariant,
+            background = LocalAndroidColorScheme.current.surfaceEffect2,
+            iconBackground = LocalAndroidColorScheme.current.surfaceEffect3,
+            label = MaterialTheme.colorScheme.onSurface,
+            secondaryLabel = MaterialTheme.colorScheme.onSurface,
+            icon = MaterialTheme.colorScheme.onSurface,
         )
 
     @Composable
     @ReadOnlyComposable
     fun inactiveTileColors(): TileColors =
         TileColors(
-            background = MaterialTheme.colorScheme.surfaceVariant,
-            iconBackground = MaterialTheme.colorScheme.surfaceVariant,
-            label = MaterialTheme.colorScheme.onSurfaceVariant,
-            secondaryLabel = MaterialTheme.colorScheme.onSurfaceVariant,
-            icon = MaterialTheme.colorScheme.onSurfaceVariant,
-        )
-
-    @Composable
-    @ReadOnlyComposable
-    fun unavailableTileColors(): TileColors =
-        TileColors(
-            background = MaterialTheme.colorScheme.surface,
-            iconBackground = MaterialTheme.colorScheme.surface,
+            background = LocalAndroidColorScheme.current.surfaceEffect2,
+            iconBackground = Color.Transparent,
             label = MaterialTheme.colorScheme.onSurface,
             secondaryLabel = MaterialTheme.colorScheme.onSurface,
             icon = MaterialTheme.colorScheme.onSurface,
@@ -435,6 +432,19 @@
 
     @Composable
     @ReadOnlyComposable
+    fun unavailableTileColors(): TileColors {
+        return TileColors(
+            background = LocalAndroidColorScheme.current.surfaceEffect2,
+            iconBackground = LocalAndroidColorScheme.current.surfaceEffect2,
+            label = MaterialTheme.colorScheme.onSurface,
+            secondaryLabel = MaterialTheme.colorScheme.onSurface,
+            icon = MaterialTheme.colorScheme.onSurface,
+            alpha = .38f,
+        )
+    }
+
+    @Composable
+    @ReadOnlyComposable
     fun getColorForState(uiState: TileUiState, iconOnly: Boolean): TileColors {
         return when (uiState.state) {
             STATE_ACTIVE -> {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
index a66b51f..57f63c7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/compose/selection/Selection.kt
@@ -62,7 +62,6 @@
 import androidx.compose.ui.unit.sp
 import androidx.compose.ui.unit.toSize
 import androidx.compose.ui.zIndex
-import com.android.compose.modifiers.size
 import com.android.compose.modifiers.thenIf
 import com.android.systemui.qs.panels.ui.compose.infinitegrid.CommonTileDefaults.InactiveCornerRadius
 import com.android.systemui.qs.panels.ui.compose.selection.SelectionDefaults.BADGE_ANGLE_RAD
@@ -155,6 +154,7 @@
                 Icon(
                     Icons.Default.Remove,
                     contentDescription = null,
+                    tint = MaterialTheme.colorScheme.onPrimaryContainer,
                     modifier =
                         Modifier.size(size).align(Alignment.Center).graphicsLayer {
                             this.alpha = badgeIconAlpha
@@ -218,14 +218,15 @@
                     )
                 }
         ) {
-            val secondaryColor = MaterialTheme.colorScheme.secondary
             val size = with(LocalDensity.current) { BadgeIconSize.toDp() }
+            val primaryColor = MaterialTheme.colorScheme.primary
             Icon(
                 icon,
                 contentDescription = contentDescription,
+                tint = MaterialTheme.colorScheme.onPrimary,
                 modifier =
                     Modifier.size(size).align(Alignment.Center).drawBehind {
-                        drawCircle(secondaryColor, radius = BadgeSize.toPx() / 2)
+                        drawCircle(primaryColor, radius = BadgeSize.toPx() / 2)
                     },
             )
         }
@@ -291,7 +292,7 @@
     return animateColor { state ->
         when (state) {
             None -> Color.Transparent
-            Removable -> MaterialTheme.colorScheme.secondary
+            Removable -> MaterialTheme.colorScheme.primaryContainer
             Selected -> MaterialTheme.colorScheme.primary
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt
index 3287443..60ca6e6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModel.kt
@@ -23,11 +23,15 @@
 import com.android.systemui.plugins.qs.TileDetailsViewModel
 import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractor
 import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.shade.domain.interactor.ShadeModeInteractor
 import javax.inject.Inject
 
 @SysUISingleton
 @Stable
-class DetailsViewModel @Inject constructor(val currentTilesInteractor: CurrentTilesInteractor) {
+class DetailsViewModel @Inject constructor(
+    val currentTilesInteractor: CurrentTilesInteractor,
+    val shadeModeInteractor: ShadeModeInteractor
+) {
 
     /**
      * The current active [TileDetailsViewModel]. If it's `null`, it means the qs overlay is not
@@ -52,6 +56,10 @@
      * @see activeTileDetails
      */
     fun onTileClicked(spec: TileSpec?): Boolean {
+        if (!shadeModeInteractor.isDualShade){
+            return false
+        }
+
         if (spec == null) {
             _activeTileDetails.value = null
             return false
diff --git a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DynamicIconTilesViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DynamicIconTilesViewModel.kt
index a9d673a..d6705a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DynamicIconTilesViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/panels/ui/viewmodel/DynamicIconTilesViewModel.kt
@@ -35,6 +35,9 @@
     private val hydrator = Hydrator("DynamicIconTilesViewModel")
     private val interactor = interactorFactory.create()
 
+    val largeTilesState =
+        hydrator.hydratedStateOf(traceName = "largeTiles", source = iconTilesViewModel.largeTiles)
+
     val largeTilesSpanState =
         hydrator.hydratedStateOf(
             traceName = "largeTilesSpan",
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSPipelineModule.kt
index 16aa99e..f155629 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/dagger/QSPipelineModule.kt
@@ -35,8 +35,8 @@
 import com.android.systemui.qs.pipeline.domain.interactor.CurrentTilesInteractorImpl
 import com.android.systemui.qs.pipeline.domain.startable.QSPipelineCoreStartable
 import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
-import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor
-import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractorImpl
+import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractorImpl
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
index c70a854..a3846e3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractor.kt
@@ -42,7 +42,7 @@
 import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.pipeline.shared.logging.QSPipelineLogger
-import com.android.systemui.qs.tiles.di.NewQSTileFactory
+import com.android.systemui.qs.tiles.base.ui.model.NewQSTileFactory
 import com.android.systemui.qs.toProto
 import com.android.systemui.retail.data.repository.RetailModeRepository
 import com.android.systemui.settings.UserTracker
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesDndTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesDndTile.kt
index 52b0206..43e3de2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesDndTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesDndTile.kt
@@ -39,12 +39,12 @@
 import com.android.systemui.qs.asQSTileIcon
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileDataInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel
 import com.android.systemui.qs.tiles.impl.modes.ui.ModesDndTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import javax.inject.Inject
 import kotlinx.coroutines.runBlocking
@@ -121,6 +121,7 @@
             label = tileLabel
             secondaryLabel = tileState.secondaryLabel
             contentDescription = tileState.contentDescription
+            stateDescription = tileState.stateDescription
             expandedAccessibilityClassName = tileState.expandedAccessibilityClassName
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt
index ad5dd27..fcfa46f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ModesTile.kt
@@ -42,13 +42,13 @@
 import com.android.systemui.qs.asQSTileIcon
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
 import com.android.systemui.qs.tiles.dialog.ModesDetailsViewModel
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
-import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.impl.modes.ui.mapper.ModesTileMapper
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.ui.dialog.viewmodel.ModesDialogViewModel
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt
index 5ba1527..c021b22 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotesTile.kt
@@ -33,12 +33,12 @@
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.logging.QSLogger
 import com.android.systemui.qs.tileimpl.QSTileImpl
-import com.android.systemui.qs.tiles.impl.notes.domain.NotesTileMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
 import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileDataInteractor
 import com.android.systemui.qs.tiles.impl.notes.domain.interactor.NotesTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.impl.notes.ui.mapper.NotesTileMapper
 import com.android.systemui.res.R
 import javax.inject.Inject
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandler.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandler.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandler.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandler.kt
index 972b20e..386e1a4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandler.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.actions
+package com.android.systemui.qs.tiles.base.domain.actions
 
 import android.app.PendingIntent
 import android.content.Intent
@@ -36,14 +36,14 @@
     fun handle(
         expandable: Expandable?,
         intent: Intent,
-        dismissShadeShowOverLockScreenWhenLocked: Boolean = false
+        dismissShadeShowOverLockScreenWhenLocked: Boolean = false,
     )
 
     /** @param requestLaunchingDefaultActivity used in case !pendingIndent.isActivity */
     fun handle(
         expandable: Expandable?,
         pendingIntent: PendingIntent,
-        requestLaunchingDefaultActivity: Boolean = false
+        requestLaunchingDefaultActivity: Boolean = false,
     )
 }
 
@@ -59,7 +59,7 @@
     override fun handle(
         expandable: Expandable?,
         intent: Intent,
-        dismissShadeShowOverLockScreenWhenLocked: Boolean
+        dismissShadeShowOverLockScreenWhenLocked: Boolean,
     ) {
         val animationController: ActivityTransitionAnimator.Controller? =
             expandable?.activityTransitionController(
@@ -70,7 +70,7 @@
                 intent,
                 true /* dismissShade */,
                 animationController,
-                true /* showOverLockscreenWhenLocked */
+                true, /* showOverLockscreenWhenLocked */
             )
         } else {
             activityStarter.postStartActivityDismissingKeyguard(intent, 0, animationController)
@@ -81,7 +81,7 @@
     override fun handle(
         expandable: Expandable?,
         pendingIntent: PendingIntent,
-        requestLaunchingDefaultActivity: Boolean
+        requestLaunchingDefaultActivity: Boolean,
     ) {
         if (pendingIntent.isActivity) {
             val animationController: ActivityTransitionAnimator.Controller? =
@@ -101,7 +101,7 @@
                 packageManager.queryIntentActivitiesAsUser(
                     intent,
                     PackageManager.ResolveInfoFlags.of(0L),
-                    userHandle.identifier
+                    userHandle.identifier,
                 )
             intents
                 .firstOrNull { it.activityInfo.exported }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractor.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractor.kt
index 4577527..da4d3d4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractor.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.interactor
 
 import android.content.Context
 import android.os.UserHandle
@@ -26,7 +26,7 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor.PolicyResult
+import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractor.PolicyResult
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
@@ -110,17 +110,9 @@
 
     @WorkerThread
     fun hasBaseUserRestriction(userId: Int, userRestriction: String?): Boolean =
-        RestrictedLockUtilsInternal.hasBaseUserRestriction(
-            context,
-            userRestriction,
-            userId,
-        )
+        RestrictedLockUtilsInternal.hasBaseUserRestriction(context, userRestriction, userId)
 
     @WorkerThread
     fun getEnforcedAdmin(userId: Int, userRestriction: String?): EnforcedAdmin? =
-        RestrictedLockUtilsInternal.checkIfRestrictionEnforced(
-            context,
-            userRestriction,
-            userId,
-        )
+        RestrictedLockUtilsInternal.checkIfRestrictionEnforced(context, userRestriction, userId)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileDataInteractor.kt
similarity index 82%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileDataInteractor.kt
index 9a776f2..1eb5315 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileDataInteractor.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.interactor
 
 import android.os.UserHandle
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.flowOf
@@ -49,10 +50,11 @@
     fun availability(user: UserHandle): Flow<Boolean>
 
     companion object {
-        val AlwaysAvailableInteractor = object : QSTileAvailabilityInteractor {
-            override fun availability(user: UserHandle): Flow<Boolean> {
-                return flowOf(true)
+        val AlwaysAvailableInteractor =
+            object : QSTileAvailabilityInteractor {
+                override fun availability(user: UserHandle): Flow<Boolean> {
+                    return flowOf(true)
+                }
             }
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileUserActionInteractor.kt
similarity index 85%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileUserActionInteractor.kt
index 8ad4e16..e49616c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/interactor/QSTileUserActionInteractor.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.interactor
 
 import android.annotation.WorkerThread
-import com.android.systemui.plugins.qs.TileDetailsViewModel
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
 
 interface QSTileUserActionInteractor<DATA_TYPE> {
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DataUpdateTrigger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/DataUpdateTrigger.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DataUpdateTrigger.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/DataUpdateTrigger.kt
index 4f25d3c..a77e551 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/DataUpdateTrigger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/DataUpdateTrigger.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.model
 
 /** Event that triggers data update */
 sealed interface DataUpdateTrigger {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileInput.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInput.kt
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileInput.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInput.kt
index 77ff609..59236be 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileInput.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInput.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.model
 
 import android.os.UserHandle
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 
 /** @see QSTileUserActionInteractor.handleInput */
-data class QSTileInput<T>(
-    val user: UserHandle,
-    val action: QSTileUserAction,
-    val data: T,
-)
+data class QSTileInput<T>(val user: UserHandle, val action: QSTileUserAction, val data: T)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLogger.kt
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLogger.kt
index 8ec8a6d..04d40ee 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/logging/QSTileLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/logging/QSTileLogger.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.logging
+package com.android.systemui.qs.tiles.base.shared.logging
 
 import androidx.annotation.GuardedBy
 import com.android.systemui.dagger.SysUISingleton
@@ -24,8 +24,8 @@
 import com.android.systemui.log.dagger.QSTilesLogBuffers
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.statusbar.StatusBarState
 import javax.inject.Inject
 
@@ -65,22 +65,19 @@
                         "statusBarState=${StatusBarState.toString(int1)}, " +
                         "hasState=$bool1, " +
                         "hasData=$bool2"
-                }
+                },
             )
     }
 
     /** Tracks user action when it's rejected by false gestures */
-    fun logUserActionRejectedByFalsing(
-        userAction: QSTileUserAction,
-        tileSpec: TileSpec,
-    ) {
+    fun logUserActionRejectedByFalsing(userAction: QSTileUserAction, tileSpec: TileSpec) {
         tileSpec
             .getLogBuffer()
             .log(
                 tileSpec.getLogTag(),
                 LogLevel.DEBUG,
                 { str1 = userAction.toLogString() },
-                { "tile $str1: rejected by falsing" }
+                { "tile $str1: rejected by falsing" },
             )
     }
 
@@ -96,7 +93,7 @@
                 tileSpec.getLogTag(),
                 LogLevel.DEBUG,
                 { str1 = userAction.toLogString() },
-                { "tile $str1: rejected by policy, restriction: $restriction" }
+                { "tile $str1: rejected by policy, restriction: $restriction" },
             )
     }
 
@@ -124,7 +121,7 @@
                         "statusBarState=${StatusBarState.toString(int1)}, " +
                         "state=$str2, " +
                         "data=$str3"
-                }
+                },
             )
     }
 
@@ -141,11 +138,7 @@
     }
 
     /** Tracks state changes based on the data and trigger event. */
-    fun <T> logStateUpdate(
-        tileSpec: TileSpec,
-        tileState: QSTileState,
-        data: T,
-    ) {
+    fun <T> logStateUpdate(tileSpec: TileSpec, tileState: QSTileState, data: T) {
         tileSpec
             .getLogBuffer()
             .log(
@@ -155,41 +148,23 @@
                     str1 = tileState.toLogString()
                     str2 = data.toString().take(DATA_MAX_LENGTH)
                 },
-                { "tile state update: state=$str1, data=$str2" }
+                { "tile state update: state=$str1, data=$str2" },
             )
     }
 
-    fun logError(
-        tileSpec: TileSpec,
-        message: String,
-        error: Throwable,
-    ) {
-        tileSpec
-            .getLogBuffer()
-            .log(
-                tileSpec.getLogTag(),
-                LogLevel.ERROR,
-                {},
-                { message },
-                error,
-            )
+    fun logError(tileSpec: TileSpec, message: String, error: Throwable) {
+        tileSpec.getLogBuffer().log(tileSpec.getLogTag(), LogLevel.ERROR, {}, { message }, error)
     }
 
     /** Log with level [LogLevel.WARNING] */
-    fun logWarning(
-        tileSpec: TileSpec,
-        message: String,
-    ) {
+    fun logWarning(tileSpec: TileSpec, message: String) {
         tileSpec
             .getLogBuffer()
             .log(tileSpec.getLogTag(), LogLevel.WARNING, { str1 = message }, { str1!! })
     }
 
     /** Log with level [LogLevel.INFO] */
-    fun logInfo(
-        tileSpec: TileSpec,
-        message: String,
-    ) {
+    fun logInfo(tileSpec: TileSpec, message: String) {
         tileSpec
             .getLogBuffer()
             .log(tileSpec.getLogTag(), LogLevel.INFO, { str1 = message }, { str1!! })
@@ -214,7 +189,7 @@
                 factory.create(
                     this.getLogTag(),
                     BUFFER_MAX_SIZE /* maxSize */,
-                    false /* systrace */
+                    false, /* systrace */
                 )
             }
         }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfig.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfig.kt
index 3a9cb17..7c2a08f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfig.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfig.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import android.content.res.Resources
 import androidx.annotation.DrawableRes
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProvider.kt
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProvider.kt
index 4dbddd9..e2d1605 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProvider.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import com.android.internal.util.Preconditions
 import com.android.systemui.dagger.SysUISingleton
@@ -51,7 +51,7 @@
             val keyTileSpec = entry.key
             Preconditions.checkArgument(
                 configTileSpec == keyTileSpec,
-                "A wrong config is injected keySpec=$keyTileSpec configSpec=$configTileSpec"
+                "A wrong config is injected keySpec=$keyTileSpec configSpec=$configTileSpec",
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileCoroutineScopeFactory.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileCoroutineScopeFactory.kt
index 5f476ea..018a06f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileCoroutineScopeFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileCoroutineScopeFactory.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import com.android.systemui.coroutines.newTracingContext
 import com.android.systemui.dagger.qualifiers.Background
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileScope.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileScope.kt
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileScope.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileScope.kt
index a412de3..a0caedb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileScope.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileScope.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.di
+package com.android.systemui.qs.tiles.base.shared.model
 
 import javax.inject.Scope
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileState.kt
similarity index 97%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileState.kt
index c6af729..5a19eae 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileState.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileState.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import android.content.res.Resources
 import android.content.res.Resources.Theme
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileUserAction.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileUserAction.kt
index bf3bc73..bbf04f6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileUserAction.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/shared/model/QSTileUserAction.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import com.android.systemui.animation.Expandable
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalytics.kt
similarity index 84%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalytics.kt
index 1d42777..8699148 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalytics.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalytics.kt
@@ -14,22 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.analytics
+package com.android.systemui.qs.tiles.base.ui.analytics
 
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.qs.QSEvent
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import javax.inject.Inject
 
 /** Tracks QS tiles analytic events to [UiEventLogger]. */
 @SysUISingleton
-class QSTileAnalytics
-@Inject
-constructor(
-    private val uiEventLogger: UiEventLogger,
-) {
+class QSTileAnalytics @Inject constructor(private val uiEventLogger: UiEventLogger) {
 
     fun trackUserAction(config: QSTileConfig, action: QSTileUserAction) {
         logAction(config, action)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactory.kt
similarity index 81%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactory.kt
index f65fdb5..fca7abe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/NewQSTileFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactory.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,18 +14,18 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.di
+package com.android.systemui.qs.tiles.base.ui.model
 
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.plugins.qs.QSFactory
 import com.android.systemui.plugins.qs.QSTile
 import com.android.systemui.qs.pipeline.shared.QSPipelineFlagsRepository
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModelAdapter
-import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelAdapter
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel
 import javax.inject.Inject
 import javax.inject.Provider
 
@@ -58,8 +58,7 @@
                 is TileSpec.PlatformTileSpec ->
                     tileMap[tileSpec]?.get()?.takeIf { it !is StubQSTileViewModel }
                 is TileSpec.Invalid -> null
-            }
-                ?: return null
+            } ?: return null
         return adapterFactory.create(viewModel)
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileComponent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileComponent.kt
similarity index 78%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileComponent.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileComponent.kt
index 5f692f2..f63c2db 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/di/QSTileComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileComponent.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,12 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.di
+package com.android.systemui.qs.tiles.base.ui.model
 
-import com.android.systemui.plugins.qs.TileDetailsViewModel
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
 import kotlinx.coroutines.CoroutineScope
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataToStateMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileDataToStateMapper.kt
similarity index 79%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataToStateMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileDataToStateMapper.kt
index 2bc6643..7be2ed1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/interactor/QSTileDataToStateMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTileDataToStateMapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.ui.model
 
 import androidx.annotation.WorkerThread
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
 
 interface QSTileDataToStateMapper<DATA_TYPE> {
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTilesModule.kt
similarity index 70%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTilesModule.kt
index 222fa3e..6b31539 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/di/QSTilesModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/model/QSTilesModule.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,20 +14,20 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.di
+package com.android.systemui.qs.tiles.base.ui.model
 
 import android.content.Context
 import android.content.res.Resources.Theme
 import com.android.systemui.qs.external.CustomTileStatePersister
 import com.android.systemui.qs.external.CustomTileStatePersisterImpl
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandlerImpl
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.impl.custom.di.CustomTileComponent
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProviderImpl
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandlerImpl
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProviderImpl
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.impl.custom.ui.model.CustomTileComponent
 import com.android.systemui.shade.ShadeDisplayAware
 import dagger.Binds
 import dagger.Module
@@ -35,12 +35,7 @@
 import dagger.multibindings.Multibinds
 
 /** Module listing subcomponents */
-@Module(
-    subcomponents =
-        [
-            CustomTileComponent::class,
-        ]
-)
+@Module(subcomponents = [CustomTileComponent::class])
 interface QSTilesModule {
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModel.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModel.kt
index 7a53388..51ebf14 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModel.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,10 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
 import android.os.UserHandle
 import com.android.systemui.plugins.qs.TileDetailsViewModel
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import kotlinx.coroutines.flow.StateFlow
 
 /**
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapter.kt
similarity index 96%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapter.kt
index e607eae..f604de6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapter.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
 import android.content.Context
 import android.os.UserHandle
@@ -31,6 +31,10 @@
 import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIcon
 import com.android.systemui.qs.tileimpl.QSTileImpl.DrawableIconWithRes
 import com.android.systemui.qs.tileimpl.QSTileImpl.ResourceIcon
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelFactory.kt
similarity index 84%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelFactory.kt
index 7f475f3..7404710 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelFactory.kt
@@ -14,26 +14,25 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.TileDetailsViewModel
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
-import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.impl.custom.di.CustomTileComponent
-import com.android.systemui.qs.tiles.impl.custom.di.QSTileConfigModule
-import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
-import com.android.systemui.qs.tiles.impl.di.QSTileComponent
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.QSTileCoroutineScopeFactory
+import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics
+import com.android.systemui.qs.tiles.base.ui.model.QSTileComponent
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel
+import com.android.systemui.qs.tiles.impl.custom.shared.model.QSTileConfigModule
+import com.android.systemui.qs.tiles.impl.custom.ui.model.CustomTileComponent
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.util.time.SystemClock
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImpl.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImpl.kt
index 3866c17..f8723e4 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/base/viewmodel/QSTileViewModelImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelImpl.kt
@@ -14,26 +14,26 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
+import android.annotation.SuppressLint
 import android.os.UserHandle
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.Dumpable
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.plugins.qs.TileDetailsViewModel
-import com.android.systemui.qs.tiles.base.analytics.QSTileAnalytics
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.DisabledByPolicyInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.domain.interactor.DisabledByPolicyInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
+import com.android.systemui.qs.tiles.base.ui.analytics.QSTileAnalytics
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.util.kotlin.throttle
 import com.android.systemui.util.time.SystemClock
@@ -89,8 +89,10 @@
     private val users: MutableStateFlow<UserHandle> =
         MutableStateFlow(userRepository.getSelectedUserInfo().userHandle)
 
+    @SuppressLint("SharedFlowCreation")
     private val userInputs: MutableSharedFlow<QSTileUserAction> = MutableSharedFlow()
 
+    @SuppressLint("SharedFlowCreation")
     private val forceUpdates: MutableSharedFlow<Unit> = MutableSharedFlow()
     private val spec
         get() = config.tileSpec
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/StubQSTileViewModel.kt
similarity index 80%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/StubQSTileViewModel.kt
index bdd5c73..304b804 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/viewmodel/StubQSTileViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/base/ui/viewmodel/StubQSTileViewModel.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,9 +14,12 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
 import android.os.UserHandle
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import kotlinx.coroutines.flow.StateFlow
 
 object StubQSTileViewModel : QSTileViewModel {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt
index fb63bea4..8dc73e3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDetailsViewModel.kt
@@ -19,7 +19,7 @@
 import android.content.Intent
 import android.provider.Settings
 import com.android.systemui.plugins.qs.TileDetailsViewModel
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
 import com.android.systemui.statusbar.connectivity.AccessPointController
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractor.kt
index 4f01a04..63dd9b3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileDataInteractor.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.qs.tiles.impl.airplane.domain.interactor
 
 import android.os.UserHandle
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
 import com.android.systemui.statusbar.pipeline.airplane.data.repository.AirplaneModeRepository
 import javax.inject.Inject
@@ -29,13 +29,12 @@
 /** Observes airplane mode state changes providing the [AirplaneModeTileModel]. */
 class AirplaneModeTileDataInteractor
 @Inject
-constructor(
-    private val airplaneModeRepository: AirplaneModeRepository,
-) : QSTileDataInteractor<AirplaneModeTileModel> {
+constructor(private val airplaneModeRepository: AirplaneModeRepository) :
+    QSTileDataInteractor<AirplaneModeTileModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<AirplaneModeTileModel> =
         airplaneModeRepository.isAirplaneMode.map { AirplaneModeTileModel(it) }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt
index 5053291..e86d951 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/interactor/AirplaneModeTileUserActionInteractor.kt
@@ -19,11 +19,11 @@
 import android.content.Intent
 import android.provider.Settings
 import android.telephony.TelephonyManager
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
 import javax.inject.Inject
 
@@ -54,7 +54,7 @@
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
-                        Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS)
+                        Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapper.kt
similarity index 85%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapper.kt
index 80d429c..b0b7b4e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/domain/AirplaneModeMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/airplane/ui/mapper/AirplaneModeTileMapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,21 +14,21 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.airplane.domain
+package com.android.systemui.qs.tiles.impl.airplane.ui.mapper
 
 import android.content.res.Resources
 import android.content.res.Resources.Theme
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
 
 /** Maps [AirplaneModeTileModel] to [QSTileState]. */
-class AirplaneModeMapper
+class AirplaneModeTileMapper
 @Inject
 constructor(@ShadeDisplayAware private val resources: Resources, val theme: Theme) :
     QSTileDataToStateMapper<AirplaneModeTileModel> {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractor.kt
index 51cd501..1f113d9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileDataInteractor.kt
@@ -18,8 +18,8 @@
 
 import android.os.UserHandle
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
 import com.android.systemui.statusbar.policy.NextAlarmController
 import com.android.systemui.util.time.DateFormatUtil
@@ -33,12 +33,12 @@
 @Inject
 constructor(
     private val alarmController: NextAlarmController,
-    private val dateFormatUtil: DateFormatUtil
+    private val dateFormatUtil: DateFormatUtil,
 ) : QSTileDataInteractor<AlarmTileModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<AlarmTileModel> =
         ConflatedCallbackFlow.conflatedCallbackFlow {
             val alarmCallback =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt
index 79fcd37..f6fcf25 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/interactor/AlarmTileUserActionInteractor.kt
@@ -18,19 +18,18 @@
 
 import android.content.Intent
 import android.provider.AlarmClock
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import javax.inject.Inject
 
 /** Handles alarm tile clicks. */
 class AlarmTileUserActionInteractor
 @Inject
-constructor(
-    private val inputHandler: QSTileIntentUserInputHandler,
-) : QSTileUserActionInteractor<AlarmTileModel> {
+constructor(private val inputHandler: QSTileIntentUserInputHandler) :
+    QSTileUserActionInteractor<AlarmTileModel> {
     override suspend fun handleInput(input: QSTileInput<AlarmTileModel>): Unit =
         with(input) {
             when (action) {
@@ -44,7 +43,7 @@
                     } else {
                         inputHandler.handle(
                             action.expandable,
-                            Intent(AlarmClock.ACTION_SHOW_ALARMS)
+                            Intent(AlarmClock.ACTION_SHOW_ALARMS),
                         )
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapper.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapper.kt
index d56d994..8a726ad 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/domain/AlarmTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/alarm/ui/mapper/AlarmTileMapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.alarm.domain
+package com.android.systemui.qs.tiles.impl.alarm.ui.mapper
 
 import android.content.res.Resources
 import android.content.res.Resources.Theme
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.util.time.SystemClock
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileDataInteractor.kt
index 22bbbbb..ed55449 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileDataInteractor.kt
@@ -18,11 +18,10 @@
 
 import android.os.UserHandle
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel
 import com.android.systemui.statusbar.policy.BatteryController
-import com.android.systemui.util.kotlin.combine
 import com.android.systemui.util.kotlin.getBatteryLevel
 import com.android.systemui.util.kotlin.isBatteryPowerSaveEnabled
 import com.android.systemui.util.kotlin.isDevicePluggedIn
@@ -44,7 +43,7 @@
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<BatterySaverTileModel> =
         combine(
             batteryController.isDevicePluggedIn().distinctUntilChanged().flowOn(bgCoroutineContext),
@@ -56,8 +55,8 @@
         ) {
             isPluggedIn: Boolean,
             isPowerSaverEnabled: Boolean,
-            _, // we are only interested in battery level change, not the actual level
-            ->
+            _ // we are only interested in battery level change, not the actual level
+             ->
             BatterySaverTileModel.Standard(isPluggedIn, isPowerSaverEnabled)
         }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt
index 3bbb9aa..2eb05a2 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/domain/interactor/BatterySaverTileUserActionInteractor.kt
@@ -18,11 +18,11 @@
 
 import android.content.Intent
 import android.provider.Settings
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.policy.BatteryController
 import javax.inject.Inject
 
@@ -31,7 +31,7 @@
 @Inject
 constructor(
     private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
-    private val batteryController: BatteryController
+    private val batteryController: BatteryController,
 ) : QSTileUserActionInteractor<BatterySaverTileModel> {
 
     override suspend fun handleInput(input: QSTileInput<BatterySaverTileModel>) =
@@ -45,7 +45,7 @@
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
-                        Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS)
+                        Intent(Settings.ACTION_BATTERY_SAVER_SETTINGS),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapper.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapper.kt
index 72759c5..7bc3d2b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/BatterySaverTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/battery/ui/mapper/BatterySaverTileMapper.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.battery.ui
+package com.android.systemui.qs.tiles.impl.battery.ui.mapper
 
 import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.battery.domain.model.BatterySaverTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractor.kt
index cd33d45..1d173fc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionTileDataInteractor.kt
@@ -18,8 +18,8 @@
 
 import android.os.UserHandle
 import com.android.systemui.accessibility.data.repository.ColorCorrectionRepository
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -29,15 +29,15 @@
 /** Observes color correction state changes providing the [ColorCorrectionTileModel]. */
 class ColorCorrectionTileDataInteractor
 @Inject
-constructor(
-    private val colorCorrectionRepository: ColorCorrectionRepository,
-) : QSTileDataInteractor<ColorCorrectionTileModel> {
+constructor(private val colorCorrectionRepository: ColorCorrectionRepository) :
+    QSTileDataInteractor<ColorCorrectionTileModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<ColorCorrectionTileModel> {
         return colorCorrectionRepository.isEnabled(user).map { ColorCorrectionTileModel(it) }
     }
+
     override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
index b774643..dea1f5c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/interactor/ColorCorrectionUserActionInteractor.kt
@@ -20,11 +20,11 @@
 import android.provider.Settings
 import com.android.systemui.accessibility.data.repository.ColorCorrectionRepository
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import javax.inject.Inject
 
 /** Handles color correction tile clicks. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapper.kt
similarity index 87%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapper.kt
index e5a0fe8..93d81f0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/domain/ColorCorrectionTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/colorcorrection/ui/mapper/ColorCorrectionTileMapper.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.colorcorrection.domain
+package com.android.systemui.qs.tiles.impl.colorcorrection.ui.mapper
 
 import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.colorcorrection.domain.model.ColorCorrectionTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/entity/CustomTileDefaults.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/model/CustomTileDefaults.kt
similarity index 81%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/entity/CustomTileDefaults.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/model/CustomTileDefaults.kt
index dfeb65b..4015106 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/entity/CustomTileDefaults.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/model/CustomTileDefaults.kt
@@ -14,15 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom.data.entity
+package com.android.systemui.qs.tiles.impl.custom.data.model
 
 import android.graphics.drawable.Icon
 
 sealed interface CustomTileDefaults {
 
     data object Error : CustomTileDefaults
-    data class Result(
-        val icon: Icon,
-        val label: CharSequence,
-    ) : CustomTileDefaults
+
+    data class Result(val icon: Icon, val label: CharSequence) : CustomTileDefaults
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt
index 32fb1d1..34894f5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileDefaultsRepository.kt
@@ -24,8 +24,8 @@
 import android.os.UserHandle
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
@@ -58,11 +58,7 @@
      *
      * Listen to [defaults] to get the loaded result
      */
-    fun requestNewDefaults(
-        user: UserHandle,
-        componentName: ComponentName,
-        force: Boolean = false,
-    )
+    fun requestNewDefaults(user: UserHandle, componentName: ComponentName, force: Boolean = false)
 }
 
 @QSTileScope
@@ -77,7 +73,7 @@
     private val defaultsRequests =
         MutableSharedFlow<DefaultsRequest>(
             replay = 1,
-            onBufferOverflow = BufferOverflow.DROP_OLDEST
+            onBufferOverflow = BufferOverflow.DROP_OLDEST,
         )
 
     private val defaults: SharedFlow<DefaultsResult> =
@@ -106,7 +102,7 @@
 
     private suspend fun loadDefaults(
         user: UserHandle,
-        componentName: ComponentName
+        componentName: ComponentName,
     ): CustomTileDefaults =
         withContext(backgroundDispatcher) {
             try {
@@ -120,16 +116,14 @@
 
                 CustomTileDefaults.Result(
                     Icon.createWithResource(componentName.packageName, iconRes),
-                    info.loadLabel(userContext.packageManager)
+                    info.loadLabel(userContext.packageManager),
                 )
             } catch (e: PackageManager.NameNotFoundException) {
                 CustomTileDefaults.Error
             }
         }
 
-    private fun ComponentName.getServiceInfo(
-        packageManager: PackageManager,
-    ): ServiceInfo {
+    private fun ComponentName.getServiceInfo(packageManager: PackageManager): ServiceInfo {
         val isSystemApp = packageManager.getApplicationInfo(packageName, 0).isSystemApp
         var flags =
             (PackageManager.MATCH_DIRECT_BOOT_UNAWARE or PackageManager.MATCH_DIRECT_BOOT_AWARE)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt
index cd4938f..da811a3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTilePackageUpdatesRepository.kt
@@ -23,12 +23,12 @@
 import android.content.IntentFilter
 import android.os.UserHandle
 import androidx.annotation.GuardedBy
-import com.android.systemui.common.coroutine.ConflatedCallbackFlow
-import com.android.systemui.dagger.qualifiers.Application
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
 import com.android.systemui.shade.ShadeDisplayAware
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
@@ -40,7 +40,6 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onCompletion
 import kotlinx.coroutines.flow.shareIn
-import com.android.app.tracing.coroutines.launchTraced as launch
 
 interface CustomTilePackageUpdatesRepository {
 
@@ -79,7 +78,7 @@
         "RegisterReceiverViaContext",
     )
     private fun createPackageChangesFlowForUser(user: UserHandle): Flow<Unit> =
-        ConflatedCallbackFlow.conflatedCallbackFlow {
+        conflatedCallbackFlow {
                 val receiver =
                     object : BroadcastReceiver() {
                         override fun onReceive(context: Context?, intent: Intent?) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt
index 0aaea8f..aabe7a9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/data/repository/CustomTileRepository.kt
@@ -27,10 +27,10 @@
 import com.android.systemui.qs.external.PackageManagerAdapter
 import com.android.systemui.qs.external.TileServiceKey
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.impl.custom.commons.copy
-import com.android.systemui.qs.tiles.impl.custom.commons.setFrom
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
+import com.android.systemui.qs.tiles.impl.custom.shared.model.copy
+import com.android.systemui.qs.tiles.impl.custom.shared.model.setFrom
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.channels.BufferOverflow
@@ -78,11 +78,7 @@
      * [user] differs from the cached one. [isPersistable] tile will be persisted to be possibly
      * loaded when the [restoreForTheUserIfNeeded].
      */
-    suspend fun updateWithTile(
-        user: UserHandle,
-        newTile: Tile,
-        isPersistable: Boolean,
-    )
+    suspend fun updateWithTile(user: UserHandle, newTile: Tile, isPersistable: Boolean)
 
     /**
      * Updates tile with the values from [defaults]. Overwrites the current cache when [user]
@@ -114,11 +110,7 @@
         if (isPersistable && getCurrentTileWithUser()?.user != user) {
             withContext(backgroundContext) {
                 customTileStatePersister.readState(user.getKey())?.let {
-                    updateWithTile(
-                        user,
-                        it,
-                        true,
-                    )
+                    updateWithTile(user, it, true)
                 }
             }
         }
@@ -137,11 +129,8 @@
         }
     }
 
-    override suspend fun updateWithTile(
-        user: UserHandle,
-        newTile: Tile,
-        isPersistable: Boolean,
-    ) = updateTile(user, isPersistable) { setFrom(newTile) }
+    override suspend fun updateWithTile(user: UserHandle, newTile: Tile, isPersistable: Boolean) =
+        updateTile(user, isPersistable) { setFrom(newTile) }
 
     override suspend fun updateWithDefaults(
         user: UserHandle,
@@ -182,7 +171,7 @@
                     packageManagerAdapter.getServiceInfo(
                         tileSpec.componentName,
                         META_DATA_QUERY_FLAGS,
-                        getCurrentTileWithUser()?.user?.identifier ?: UserHandle.USER_CURRENT
+                        getCurrentTileWithUser()?.user?.identifier ?: UserHandle.USER_CURRENT,
                     )
                 info?.metaData?.getBoolean(TileService.META_DATA_TOGGLEABLE_TILE, false) == true
             } catch (e: RemoteException) {
@@ -193,7 +182,7 @@
     private suspend fun updateTile(
         user: UserHandle,
         isPersistable: Boolean,
-        update: Tile.() -> Unit
+        update: Tile.() -> Unit,
     ): Unit =
         tileUpdateMutex.withLock {
             val currentTileWithUser = getCurrentTileWithUser()
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
index 0b0f2fe..e64675f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileDataInteractor.kt
@@ -20,14 +20,14 @@
 import android.service.quicksettings.Tile
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository
-import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel
 import com.android.systemui.user.data.repository.UserRepository
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt
index 6f1cb3c..c587e3a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileInteractor.kt
@@ -18,11 +18,12 @@
 
 import android.os.UserHandle
 import android.service.quicksettings.Tile
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.qs.pipeline.shared.TileSpec
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepository
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
@@ -34,7 +35,6 @@
 import kotlinx.coroutines.flow.flowOn
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import com.android.app.tracing.coroutines.launchTraced as launch
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 
@@ -100,7 +100,7 @@
             launchUpdates(user)
             customTileRepository.restoreForTheUserIfNeeded(
                 user,
-                customTileRepository.isTileActive()
+                customTileRepository.isTileActive(),
             )
             // Suspend to make sure it gets the tile from one of the sources: restoration, defaults,
             // or
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileServiceInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileServiceInteractor.kt
index c0fc93f..56fd325 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileServiceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileServiceInteractor.kt
@@ -31,8 +31,8 @@
 import com.android.systemui.qs.external.TileServiceManager
 import com.android.systemui.qs.external.TileServices
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
 import com.android.systemui.user.data.repository.UserRepository
 import dagger.Lazy
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
index 1153b5c..df2759a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/interactor/CustomTileUserActionInteractor.kt
@@ -34,13 +34,13 @@
 import com.android.systemui.animation.Expandable
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
-import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
+import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel
 import com.android.systemui.settings.DisplayTracker
 import com.android.systemui.shade.ShadeDisplayAware
 import java.util.concurrent.atomic.AtomicReference
@@ -80,10 +80,7 @@
             qsTileLogger.logCustomTileUserActionDelivered(tileSpec)
         }
 
-    private suspend fun click(
-        expandable: Expandable?,
-        activityLaunchForClick: PendingIntent?,
-    ) {
+    private suspend fun click(expandable: Expandable?, activityLaunchForClick: PendingIntent?) {
         grantToken()
         try {
             // Bind active tile to deliver user action
@@ -133,7 +130,7 @@
                         token,
                         WindowManager.LayoutParams.TYPE_QS_DIALOG,
                         displayTracker.defaultDisplayId,
-                        null /* options */
+                        null, /* options */
                     )
                 } catch (e: RemoteException) {
                     qsTileLogger.logError(tileSpec, "Failed to grant a window token", e)
@@ -147,7 +144,7 @@
         user: UserHandle,
         expandable: Expandable?,
         componentName: ComponentName,
-        state: Int
+        state: Int,
     ) {
         val resolvedIntent: Intent? =
             resolveIntent(
@@ -166,7 +163,7 @@
                 Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                     .setData(
                         Uri.fromParts(IntentFilter.SCHEME_PACKAGE, componentName.packageName, null)
-                    )
+                    ),
             )
         } else {
             qsTileIntentUserInputHandler.handle(expandable, resolvedIntent)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/entity/CustomTileDataModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/model/CustomTileDataModel.kt
similarity index 94%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/entity/CustomTileDataModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/model/CustomTileDataModel.kt
index 5b6ff1e..4393e9e1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/entity/CustomTileDataModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/model/CustomTileDataModel.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom.domain.entity
+package com.android.systemui.qs.tiles.impl.custom.domain.model
 
 import android.content.ComponentName
 import android.graphics.drawable.Icon
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/QSTileConfigModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/QSTileConfigModule.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/QSTileConfigModule.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/QSTileConfigModule.kt
index 558fb64..c950888 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/QSTileConfigModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/QSTileConfigModule.kt
@@ -14,10 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom.di
+package com.android.systemui.qs.tiles.impl.custom.shared.model
 
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
 import dagger.Module
 import dagger.Provides
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/commons/TileExt.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/TileExt.kt
similarity index 95%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/commons/TileExt.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/TileExt.kt
index 869f6f32..022894e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/commons/TileExt.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/shared/model/TileExt.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom.commons
+package com.android.systemui.qs.tiles.impl.custom.shared.model
 
 import android.service.quicksettings.Tile
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapper.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapper.kt
index c446865..dfaaea1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/domain/CustomTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/mapper/CustomTileMapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom.domain
+package com.android.systemui.qs.tiles.impl.custom.ui.mapper
 
 import android.annotation.SuppressLint
 import android.app.IUriGrantsManager
@@ -26,10 +26,10 @@
 import android.widget.Switch
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
 
@@ -38,9 +38,8 @@
 @Inject
 constructor(
     @ShadeDisplayAware private val context: Context,
-    private val uriGrantsManager: IUriGrantsManager
-) :
-    QSTileDataToStateMapper<CustomTileDataModel> {
+    private val uriGrantsManager: IUriGrantsManager,
+) : QSTileDataToStateMapper<CustomTileDataModel> {
 
     override fun map(config: QSTileConfig, data: CustomTileDataModel): QSTileState {
         val userContext =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileComponent.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileComponent.kt
similarity index 77%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileComponent.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileComponent.kt
index 7b099c2..4f23033 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileComponent.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileComponent.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom.di
+package com.android.systemui.qs.tiles.impl.custom.ui.model
 
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
+import com.android.systemui.qs.tiles.base.ui.model.QSTileComponent
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository
-import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
 import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileInteractor
 import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileServiceInteractor
-import com.android.systemui.qs.tiles.impl.di.QSTileComponent
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel
+import com.android.systemui.qs.tiles.impl.custom.shared.model.QSTileConfigModule
 import dagger.Subcomponent
 
 @QSTileScope
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileModule.kt
similarity index 79%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileModule.kt
index 196fa12..ee7908a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/di/CustomTileModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/custom/ui/model/CustomTileModule.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,23 +14,23 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom.di
+package com.android.systemui.qs.tiles.impl.custom.ui.model
 
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileCoroutineScopeFactory
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileCoroutineScopeFactory
+import com.android.systemui.qs.tiles.base.shared.model.QSTileScope
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepository
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileDefaultsRepositoryImpl
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepository
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTilePackageUpdatesRepositoryImpl
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepository
 import com.android.systemui.qs.tiles.impl.custom.data.repository.CustomTileRepositoryImpl
-import com.android.systemui.qs.tiles.impl.custom.domain.CustomTileMapper
-import com.android.systemui.qs.tiles.impl.custom.domain.entity.CustomTileDataModel
 import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileDataInteractor
 import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileUserActionInteractor
-import com.android.systemui.qs.tiles.impl.di.QSTileScope
+import com.android.systemui.qs.tiles.impl.custom.domain.model.CustomTileDataModel
+import com.android.systemui.qs.tiles.impl.custom.ui.mapper.CustomTileMapper
 import dagger.Binds
 import dagger.Module
 import dagger.Provides
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractor.kt
index 38eb594..9720d15 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileDataInteractor.kt
@@ -17,11 +17,11 @@
 package com.android.systemui.qs.tiles.impl.flashlight.domain.interactor
 
 import android.os.UserHandle
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
 import com.android.systemui.statusbar.policy.FlashlightController
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import javax.inject.Inject
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
@@ -30,22 +30,23 @@
 /** Observes flashlight state changes providing the [FlashlightTileModel]. */
 class FlashlightTileDataInteractor
 @Inject
-constructor(
-    private val flashlightController: FlashlightController,
-) : QSTileDataInteractor<FlashlightTileModel> {
+constructor(private val flashlightController: FlashlightController) :
+    QSTileDataInteractor<FlashlightTileModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<FlashlightTileModel> = conflatedCallbackFlow {
         val callback =
             object : FlashlightController.FlashlightListener {
                 override fun onFlashlightChanged(enabled: Boolean) {
                     trySend(FlashlightTileModel.FlashlightAvailable(enabled))
                 }
+
                 override fun onFlashlightError() {
                     trySend(FlashlightTileModel.FlashlightAvailable(false))
                 }
+
                 override fun onFlashlightAvailabilityChanged(available: Boolean) {
                     trySend(
                         if (available)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt
index 13afc15..8a76b2a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/interactor/FlashlightTileUserActionInteractor.kt
@@ -17,19 +17,18 @@
 package com.android.systemui.qs.tiles.impl.flashlight.domain.interactor
 
 import android.app.ActivityManager
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.policy.FlashlightController
 import javax.inject.Inject
 
 /** Handles flashlight tile clicks. */
 class FlashlightTileUserActionInteractor
 @Inject
-constructor(
-    private val flashlightController: FlashlightController,
-) : QSTileUserActionInteractor<FlashlightTileModel> {
+constructor(private val flashlightController: FlashlightController) :
+    QSTileUserActionInteractor<FlashlightTileModel> {
 
     override suspend fun handleInput(input: QSTileInput<FlashlightTileModel>) =
         with(input) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapper.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapper.kt
index 32ccba6..0be4a9f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/domain/FlashlightMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/flashlight/ui/mapper/FlashlightMapper.kt
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.flashlight.domain
+package com.android.systemui.qs.tiles.impl.flashlight.ui.mapper
 
 import android.content.res.Resources
 import android.content.res.Resources.Theme
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractor.kt
index 745e6a3..3464741 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileDataInteractor.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.qs.tiles.impl.fontscaling.domain.interactor
 
 import android.os.UserHandle
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -29,7 +29,7 @@
     QSTileDataInteractor<FontScalingTileModel> {
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<FontScalingTileModel> = flowOf(FontScalingTileModel)
 
     override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
index 0ebb51e..65db0f9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/interactor/FontScalingTileUserActionInteractor.kt
@@ -25,11 +25,11 @@
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.phone.SystemUIDialog
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapper.kt
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapper.kt
index c571b13..659e1fe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/domain/FontScalingTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/fontscaling/ui/mapper/FontScalingTileMapper.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.fontscaling.domain
+package com.android.systemui.qs.tiles.impl.fontscaling.ui.mapper
 
 import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.fontscaling.domain.model.FontScalingTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractor.kt
index 33b7feb..50ea30d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileDataInteractor.kt
@@ -19,8 +19,8 @@
 import android.os.UserHandle
 import com.android.systemui.accessibility.hearingaid.HearingDevicesChecker
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
 import com.android.systemui.statusbar.policy.BluetoothController
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractor.kt
index 268efce..049d061 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/interactor/HearingDevicesTileUserActionInteractor.kt
@@ -22,11 +22,11 @@
 import com.android.systemui.accessibility.hearingaid.HearingDevicesUiEventLogger.Companion.LAUNCH_SOURCE_QS_TILE
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.withContext
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapper.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapper.kt
index 12f7149..d89c535 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/domain/HearingDevicesTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/hearingdevices/ui/mapper/HearingDevicesTileMapper.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.hearingdevices.domain
+package com.android.systemui.qs.tiles.impl.hearingdevices.ui.mapper
 
 import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.hearingdevices.domain.model.HearingDevicesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt
index 871c051..786ac47 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileDataInteractor.kt
@@ -24,8 +24,8 @@
 import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
 import com.android.systemui.common.shared.model.Text
 import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
index 0431e36..7fd282c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/interactor/InternetTileUserActionInteractor.kt
@@ -19,12 +19,12 @@
 import android.content.Intent
 import android.provider.Settings
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.dialog.InternetDialogManager
 import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.connectivity.AccessPointController
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapper.kt
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapper.kt
index 8d58805..a96ad38 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/domain/InternetTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/internet/ui/mapper/InternetTileMapper.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.internet.domain
+package com.android.systemui.qs.tiles.impl.internet.ui.mapper
 
 import android.content.Context
 import android.content.res.Resources
@@ -25,10 +25,10 @@
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.common.shared.model.Text.Companion.loadText
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.statusbar.pipeline.shared.ui.model.InternetTileIconModel
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractor.kt
index 7f3dd3e..fea9e7e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionTileDataInteractor.kt
@@ -18,8 +18,8 @@
 
 import android.os.UserHandle
 import com.android.systemui.accessibility.data.repository.ColorInversionRepository
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -29,15 +29,15 @@
 /** Observes color inversion state changes providing the [ColorInversionTileModel]. */
 class ColorInversionTileDataInteractor
 @Inject
-constructor(
-    private val colorInversionRepository: ColorInversionRepository,
-) : QSTileDataInteractor<ColorInversionTileModel> {
+constructor(private val colorInversionRepository: ColorInversionRepository) :
+    QSTileDataInteractor<ColorInversionTileModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<ColorInversionTileModel> {
         return colorInversionRepository.isEnabled(user).map { ColorInversionTileModel(it) }
     }
+
     override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
index f783497..12530bc 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/interactor/ColorInversionUserActionInteractor.kt
@@ -20,11 +20,11 @@
 import android.provider.Settings
 import com.android.systemui.accessibility.data.repository.ColorInversionRepository
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import javax.inject.Inject
 
 /** Handles color inversion tile clicks. */
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapper.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapper.kt
index 05590e8..868abc0 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/domain/ColorInversionTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/inversion/ui/mapper/ColorInversionTileMapper.kt
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.inversion.domain
+package com.android.systemui.qs.tiles.impl.inversion.ui.mapper
 
 import android.content.res.Resources
 import android.content.res.Resources.Theme
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.inversion.domain.model.ColorInversionTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/data/model/IssueRecordingModel.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/data/model/IssueRecordingModel.kt
index 260729b..704102b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/data/model/IssueRecordingModel.kt
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package com.android.systemui.qs.tiles.impl.irecording.data.model
 
 @JvmInline value class IssueRecordingModel(val isRecording: Boolean)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractor.kt
similarity index 84%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractor.kt
index 09a6ce8..95fe191 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingDataInteractor.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,13 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package com.android.systemui.qs.tiles.impl.irecording.domain.interactor
 
 import android.os.UserHandle
 import com.android.systemui.Flags
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel
 import com.android.systemui.recordissue.IssueRecordingState
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractor.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractor.kt
index fceee5a..7182a37 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/domain/interactor/IssueRecordingUserActionInteractor.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package com.android.systemui.qs.tiles.impl.irecording.domain.interactor
 
 import android.app.AlertDialog
 import android.app.BroadcastOptions
@@ -30,9 +30,10 @@
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
 import com.android.systemui.qs.tiles.DELAY_MS
 import com.android.systemui.qs.tiles.INTERVAL_MS
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
+import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel
 import com.android.systemui.recordissue.IssueRecordingService.Companion.getStartIntent
 import com.android.systemui.recordissue.IssueRecordingService.Companion.getStopIntent
 import com.android.systemui.recordissue.IssueRecordingState
@@ -47,8 +48,6 @@
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.withContext
 
-private const val TAG = "IssueRecordingActionInteractor"
-
 class IssueRecordingUserActionInteractor
 @Inject
 constructor(
@@ -128,4 +127,8 @@
             action,
             PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE,
         )
+
+    companion object {
+        private const val TAG = "IssueRecordingUserActionInteractor"
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapper.kt
similarity index 83%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapper.kt
index afb137e..bd51bbe 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/IssueRecordingMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/irecording/ui/mapper/IssueRecordingMapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.irecording
+package com.android.systemui.qs.tiles.impl.irecording.ui.mapper
 
 import android.content.res.Resources
 import android.content.res.Resources.Theme
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractor.kt
index bd2f2c9..052d062 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileDataInteractor.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.qs.tiles.impl.location.domain.interactor
 
 import android.os.UserHandle
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
 import com.android.systemui.statusbar.policy.LocationController
 import com.android.systemui.util.kotlin.isLocationEnabledFlow
@@ -30,13 +30,12 @@
 /** Observes location state changes providing the [LocationTileModel]. */
 class LocationTileDataInteractor
 @Inject
-constructor(
-    private val locationController: LocationController,
-) : QSTileDataInteractor<LocationTileModel> {
+constructor(private val locationController: LocationController) :
+    QSTileDataInteractor<LocationTileModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<LocationTileModel> =
         locationController.isLocationEnabledFlow().map { LocationTileModel(it) }
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt
index d46bcfc..f5d1400 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/interactor/LocationTileUserActionInteractor.kt
@@ -18,21 +18,21 @@
 
 import android.content.Intent
 import android.provider.Settings
+import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.coroutines.newTracingContext
 import com.android.systemui.dagger.qualifiers.Application
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.policy.KeyguardStateController
 import com.android.systemui.statusbar.policy.LocationController
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.CoroutineScope
-import com.android.app.tracing.coroutines.launchTraced as launch
 import kotlinx.coroutines.withContext
 
 /** Handles location tile clicks. */
@@ -68,7 +68,7 @@
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
-                        Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
+                        Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapper.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapper.kt
index ced5a4f..d2c9116 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/domain/LocationTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/location/ui/mapper/LocationTileMapper.kt
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.location.domain
+package com.android.systemui.qs.tiles.impl.location.ui.mapper
 
 import android.content.res.Resources
 import android.content.res.Resources.Theme
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractor.kt
index b1ae3ba..c3e7bea 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileDataInteractor.kt
@@ -18,12 +18,14 @@
 
 import android.content.Context
 import android.os.UserHandle
+import android.text.TextUtils
 import com.android.app.tracing.coroutines.flow.flowName
 import com.android.settingslib.notification.modes.ZenMode
+import com.android.settingslib.notification.modes.ZenModeDescriptions
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.modes.shared.ModesUi
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
@@ -44,6 +46,8 @@
     @Background val bgDispatcher: CoroutineDispatcher,
 ) : QSTileDataInteractor<ModesDndTileModel> {
 
+    private val zenModeDescriptions = ZenModeDescriptions(context)
+
     override fun tileData(
         user: UserHandle,
         triggers: Flow<DataUpdateTrigger>,
@@ -65,7 +69,10 @@
     fun getCurrentTileModel() = buildTileData(zenModeInteractor.getDndMode())
 
     private fun buildTileData(dndMode: ZenMode): ModesDndTileModel {
-        return ModesDndTileModel(isActivated = dndMode.isActive)
+        return ModesDndTileModel(
+            isActivated = dndMode.isActive,
+            extraStatus = TextUtils.nullIfEmpty(zenModeDescriptions.getTriggerDescription(dndMode)),
+        )
     }
 
     override fun availability(user: UserHandle): Flow<Boolean> =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractor.kt
index e8fcea0..012ae03 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesDndTileUserActionInteractor.kt
@@ -24,11 +24,11 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.qs.shared.QSSettingsPackageRepository
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
 import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate
 import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogEventLogger
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt
index 479f618..e97985c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileDataInteractor.kt
@@ -25,8 +25,8 @@
 import com.android.systemui.modes.shared.ModesUi
 import com.android.systemui.modes.shared.ModesUiIcons
 import com.android.systemui.qs.tiles.ModesTile
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
index ab1326a..5240a18 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractor.kt
@@ -23,11 +23,11 @@
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.qs.flags.QSComposeFragment
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
 import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogDelegate
 import com.android.systemui.statusbar.policy.ui.dialog.ModesDialogEventLogger
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesDndTileModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesDndTileModel.kt
index eab7988..e13cc65 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesDndTileModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/domain/model/ModesDndTileModel.kt
@@ -16,4 +16,4 @@
 
 package com.android.systemui.qs.tiles.impl.modes.domain.model
 
-data class ModesDndTileModel(val isActivated: Boolean)
+data class ModesDndTileModel(val isActivated: Boolean, val extraStatus: String?)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapper.kt
index 4869b6f..632c572 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesDndTileMapper.kt
@@ -19,10 +19,10 @@
 import android.content.res.Resources
 import android.widget.Switch
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
@@ -49,11 +49,9 @@
                     QSTileState.ActivationState.INACTIVE
                 }
             label = resources.getString(R.string.quick_settings_dnd_label)
-            secondaryLabel =
-                resources.getString(
-                    if (data.isActivated) R.string.zen_mode_on else R.string.zen_mode_off
-                )
+            secondaryLabel = data.extraStatus
             contentDescription = label
+            stateDescription = data.extraStatus
             supportedActions =
                 setOf(QSTileState.UserAction.CLICK, QSTileState.UserAction.LONG_CLICK)
             expandedAccessibilityClass = Switch::class
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapper.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapper.kt
index 99ae3b8..4668350 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/ModesTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/modes/ui/mapper/ModesTileMapper.kt
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.modes.ui
+package com.android.systemui.qs.tiles.impl.modes.ui.mapper
 
 import android.content.res.Resources
 import android.icu.text.MessageFormat
 import android.widget.Button
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import java.util.Locale
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt
index e8e43e8..f6f267f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileDataInteractor.kt
@@ -20,8 +20,8 @@
 import android.hardware.display.ColorDisplayManager
 import android.os.UserHandle
 import com.android.systemui.accessibility.data.repository.NightDisplayRepository
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.util.time.DateFormatUtil
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt
index 7076a8f..4173942 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/domain/interactor/NightDisplayTileUserActionInteractor.kt
@@ -22,12 +22,12 @@
 import com.android.systemui.accessibility.data.repository.NightDisplayRepository
 import com.android.systemui.accessibility.qs.QSAccessibilityModule
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import javax.inject.Inject
 
 /** Handles night display tile clicks. */
@@ -52,7 +52,7 @@
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
-                        Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS)
+                        Intent(Settings.ACTION_NIGHT_DISPLAY_SETTINGS),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapper.kt
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapper.kt
index 16b3628..3e47875 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/NightDisplayTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/night/ui/mapper/NightDisplayTileMapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.night.ui
+package com.android.systemui.qs.tiles.impl.night.ui.mapper
 
 import android.content.res.Resources
 import android.service.quicksettings.Tile
@@ -23,11 +23,11 @@
 import com.android.systemui.accessibility.qs.QSAccessibilityModule
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.night.domain.model.NightDisplayTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import java.time.DateTimeException
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt
index a501b85..157da8a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileDataInteractor.kt
@@ -19,8 +19,8 @@
 import android.os.UserHandle
 import com.android.systemui.Flags
 import com.android.systemui.notetask.NoteTaskEnabledKey
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt
index df01d99..527f9e8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/interactor/NotesTileUserActionInteractor.kt
@@ -20,15 +20,16 @@
 import com.android.systemui.notetask.NoteTaskController
 import com.android.systemui.notetask.NoteTaskEntryPoint
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import javax.inject.Inject
 
 class NotesTileUserActionInteractor
-@Inject constructor(
+@Inject
+constructor(
     private val qsTileIntentUserInputHandler: QSTileIntentUserInputHandler,
     private val panelInteractor: PanelInteractor,
     private val noteTaskController: NoteTaskController,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapper.kt
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapper.kt
index ecdd711..36b28df 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/domain/NotesTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/notes/ui/mapper/NotesTileMapper.kt
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.notes.domain
+package com.android.systemui.qs.tiles.impl.notes.ui.mapper
 
 import android.content.res.Resources
 import android.widget.Button
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.notes.domain.model.NotesTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileDataInteractor.kt
index 8c0fd2c..39f3976 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileDataInteractor.kt
@@ -18,8 +18,8 @@
 
 import android.os.UserHandle
 import com.android.systemui.accessibility.data.repository.OneHandedModeRepository
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel
 import com.android.wm.shell.onehanded.OneHanded
 import javax.inject.Inject
@@ -30,16 +30,16 @@
 /** Observes one handed mode state changes providing the [OneHandedModeTileModel]. */
 class OneHandedModeTileDataInteractor
 @Inject
-constructor(
-    private val oneHandedModeRepository: OneHandedModeRepository,
-) : QSTileDataInteractor<OneHandedModeTileModel> {
+constructor(private val oneHandedModeRepository: OneHandedModeRepository) :
+    QSTileDataInteractor<OneHandedModeTileModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<OneHandedModeTileModel> {
         return oneHandedModeRepository.isEnabled(user).map { OneHandedModeTileModel(it) }
     }
+
     override fun availability(user: UserHandle): Flow<Boolean> =
         flowOf(OneHanded.sIsSupportOneHandedMode)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt
index 0a0f0a6..88f9d84 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/domain/OneHandedModeTileUserActionInteractor.kt
@@ -19,11 +19,11 @@
 import android.content.Intent
 import android.provider.Settings
 import com.android.systemui.accessibility.data.repository.OneHandedModeRepository
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import javax.inject.Inject
 
 /** Handles one handed mode tile clicks. */
@@ -38,15 +38,12 @@
         with(input) {
             when (action) {
                 is QSTileUserAction.Click -> {
-                    oneHandedModeRepository.setIsEnabled(
-                        !data.isEnabled,
-                        user,
-                    )
+                    oneHandedModeRepository.setIsEnabled(!data.isEnabled, user)
                 }
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
-                        Intent(Settings.ACTION_ONE_HANDED_SETTINGS)
+                        Intent(Settings.ACTION_ONE_HANDED_SETTINGS),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapper.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapper.kt
index 5b3ea93..ace36ce 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/OneHandedModeTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/onehanded/ui/mapper/OneHandedModeTileMapper.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.onehanded.ui
+package com.android.systemui.qs.tiles.impl.onehanded.ui.mapper
 
 import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.onehanded.domain.model.OneHandedModeTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
index 233e913..0b4752b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileDataInteractor.kt
@@ -21,8 +21,8 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController
 import com.android.systemui.qrcodescanner.controller.QRCodeScannerController.DEFAULT_QR_CODE_SCANNER_CHANGE
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel
 import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import javax.inject.Inject
@@ -44,7 +44,7 @@
 ) : QSTileDataInteractor<QRCodeScannerTileModel> {
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<QRCodeScannerTileModel> =
         conflatedCallbackFlow {
                 qrController.registerQRCodeScannerChangeObservers(DEFAULT_QR_CODE_SCANNER_CHANGE)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt
index bb5df02..eb47d0b8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/domain/interactor/QRCodeScannerTileUserActionInteractor.kt
@@ -16,19 +16,18 @@
 
 package com.android.systemui.qs.tiles.impl.qr.domain.interactor
 
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import javax.inject.Inject
 
 /** Handles qr tile clicks. */
 class QRCodeScannerTileUserActionInteractor
 @Inject
-constructor(
-    private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler,
-) : QSTileUserActionInteractor<QRCodeScannerTileModel> {
+constructor(private val qsTileIntentUserActionHandler: QSTileIntentUserInputHandler) :
+    QSTileUserActionInteractor<QRCodeScannerTileModel> {
 
     override suspend fun handleInput(input: QSTileInput<QRCodeScannerTileModel>): Unit =
         with(input) {
@@ -39,7 +38,7 @@
                             qsTileIntentUserActionHandler.handle(
                                 action.expandable,
                                 data.intent,
-                                true
+                                true,
                             )
                         is QRCodeScannerTileModel.TemporarilyUnavailable -> {} // no-op
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapper.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapper.kt
index 21e92d3..120961b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/QRCodeScannerTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/mapper/QRCodeScannerTileMapper.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.qr.ui
+package com.android.systemui.qs.tiles.impl.qr.ui.mapper
 
 import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/model/QRCodeScannerModule.kt
similarity index 83%
rename from packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/model/QRCodeScannerModule.kt
index ef1f834..c3c6be3 100644
--- a/packages/SystemUI/src/com/android/systemui/qrcodescanner/dagger/QRCodeScannerModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/qr/ui/model/QRCodeScannerModule.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qrcodescanner.dagger
+package com.android.systemui.qs.tiles.impl.qr.ui.model
 
 import com.android.systemui.Flags
 import com.android.systemui.qs.QsEventLogger
@@ -22,16 +22,16 @@
 import com.android.systemui.qs.shared.model.TileCategory
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.QRCodeScannerTile
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel
 import com.android.systemui.qs.tiles.impl.qr.domain.interactor.QRCodeScannerTileDataInteractor
 import com.android.systemui.qs.tiles.impl.qr.domain.interactor.QRCodeScannerTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.qr.domain.model.QRCodeScannerTileModel
-import com.android.systemui.qs.tiles.impl.qr.ui.QRCodeScannerTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
-import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
+import com.android.systemui.qs.tiles.impl.qr.ui.mapper.QRCodeScannerTileMapper
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
@@ -81,7 +81,7 @@
             factory: QSTileViewModelFactory.Static<QRCodeScannerTileModel>,
             mapper: QRCodeScannerTileMapper,
             stateInteractor: QRCodeScannerTileDataInteractor,
-            userActionInteractor: QRCodeScannerTileUserActionInteractor
+            userActionInteractor: QRCodeScannerTileUserActionInteractor,
         ): QSTileViewModel =
             if (Flags.qsNewTilesFuture())
                 factory.create(
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt
index 536c5f1..46ed2ff 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileDataInteractor.kt
@@ -20,8 +20,8 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.qs.ReduceBrightColorsController
 import com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
 import com.android.systemui.util.kotlin.isEnabled
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
index eff5f8f..0bc3dec 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/domain/interactor/ReduceBrightColorsTileUserActionInteractor.kt
@@ -21,11 +21,11 @@
 import android.provider.Settings
 import com.android.systemui.accessibility.extradim.ExtraDimDialogManager
 import com.android.systemui.qs.ReduceBrightColorsController
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapper.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapper.kt
index 66759cd..2e74399 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/ReduceBrightColorsTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/reducebrightness/ui/mapper/ReduceBrightColorsTileMapper.kt
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.reducebrightness.ui
+package com.android.systemui.qs.tiles.impl.reducebrightness.ui.mapper
 
 import android.content.res.Resources
 import android.service.quicksettings.Tile
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.reducebrightness.domain.model.ReduceBrightColorsTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt
index 7f17a3a..f89154d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileDataInteractor.kt
@@ -22,8 +22,8 @@
 import android.os.UserHandle
 import com.android.systemui.camera.data.repository.CameraAutoRotateRepository
 import com.android.systemui.camera.data.repository.CameraSensorPrivacyRepository
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.statusbar.policy.BatteryController
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt
index 65712c7..71aaa93 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/domain/interactor/RotationLockTileUserActionInteractor.kt
@@ -18,11 +18,11 @@
 
 import android.content.Intent
 import android.provider.Settings
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.policy.RotationLockController
 import javax.inject.Inject
 
@@ -43,7 +43,7 @@
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
-                        Intent(Settings.ACTION_AUTO_ROTATE_SETTINGS)
+                        Intent(Settings.ACTION_AUTO_ROTATE_SETTINGS),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt
index 000c702..d1db499 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/rotation/ui/mapper/RotationLockTileMapper.kt
@@ -19,10 +19,10 @@
 import android.content.res.Resources
 import android.hardware.devicestate.DeviceStateManager
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.statusbar.policy.DevicePostureController
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractor.kt
index 91e049b..1c19444 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileDataInteractor.kt
@@ -18,8 +18,8 @@
 
 import android.os.UserHandle
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
 import com.android.systemui.statusbar.policy.DataSaverController
 import javax.inject.Inject
@@ -30,13 +30,12 @@
 /** Observes data saver state changes providing the [DataSaverTileModel]. */
 class DataSaverTileDataInteractor
 @Inject
-constructor(
-    private val dataSaverController: DataSaverController,
-) : QSTileDataInteractor<DataSaverTileModel> {
+constructor(private val dataSaverController: DataSaverController) :
+    QSTileDataInteractor<DataSaverTileModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<DataSaverTileModel> =
         ConflatedCallbackFlow.conflatedCallbackFlow {
             val initialValue = dataSaverController.isDataSaverEnabled
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
index 63a9f59..16fb9f7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/interactor/DataSaverTileUserActionInteractor.kt
@@ -24,12 +24,12 @@
 import com.android.systemui.animation.DialogTransitionAnimator
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.saver.domain.DataSaverDialogDelegate
 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.settings.UserFileManager
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapper.kt
similarity index 88%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapper.kt
index 1d5cf29..e15c098 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/domain/DataSaverTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/saver/ui/mapper/DataSaverTileMapper.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.saver.domain
+package com.android.systemui.qs.tiles.impl.saver.ui.mapper
 
 import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt
index 597825c..7e2f1bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileDataInteractor.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor
 
 import android.os.UserHandle
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository
 import javax.inject.Inject
@@ -28,13 +28,12 @@
 /** Observes screen record state changes providing the [ScreenRecordModel]. */
 class ScreenRecordTileDataInteractor
 @Inject
-constructor(
-    private val screenRecordRepository: ScreenRecordRepository,
-) : QSTileDataInteractor<ScreenRecordModel> {
+constructor(private val screenRecordRepository: ScreenRecordRepository) :
+    QSTileDataInteractor<ScreenRecordModel> {
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<ScreenRecordModel> = screenRecordRepository.screenRecordState
 
     override fun availability(user: UserHandle): Flow<Boolean> = flowOf(true)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
index 9453447..b7dc632 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/interactor/ScreenRecordTileUserActionInteractor.kt
@@ -28,9 +28,9 @@
 import com.android.systemui.mediaprojection.MediaProjectionMetricsLogger
 import com.android.systemui.plugins.ActivityStarter
 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.screenrecord.RecordingController
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/mapper/ScreenRecordTileMapper.kt
similarity index 93%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/mapper/ScreenRecordTileMapper.kt
index 0a61e3c..b0c9d12 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/ScreenRecordTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/screenrecord/domain/ui/mapper/ScreenRecordTileMapper.kt
@@ -14,14 +14,14 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.screenrecord.domain.ui
+package com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.mapper
 
 import android.content.res.Resources
 import android.text.TextUtils
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.res.R
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.shade.ShadeDisplayAware
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyToggleTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractor.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyToggleTileDataInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractor.kt
index a8e9c56..f033e6a 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/SensorPrivacyToggleTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileDataInteractor.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.sensorprivacy
+package com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor
 
 import android.hardware.SensorPrivacyManager.Sensors.CAMERA
 import android.hardware.SensorPrivacyManager.Sensors.MICROPHONE
@@ -22,12 +22,12 @@
 import android.os.UserHandle
 import android.provider.DeviceConfig
 import android.util.Log
-import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
 import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
+import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
@@ -55,7 +55,7 @@
 
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<SensorPrivacyToggleTileModel> =
         conflatedCallbackFlow {
                 val callback =
@@ -85,14 +85,14 @@
                 return@withContext DeviceConfig.getBoolean(
                     DeviceConfig.NAMESPACE_PRIVACY,
                     deviceConfigName,
-                    true
+                    true,
                 )
             } catch (exception: IllegalArgumentException) {
                 Log.w(
                     TAG,
                     "isDeviceConfigSet for sensorId $sensorId: " +
                         "Defaulting to true due to exception. ",
-                    exception
+                    exception,
                 )
                 return@withContext true
             }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractor.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractor.kt
index d7f64d1..decf432 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/SensorPrivacyToggleTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/domain/interactor/SensorPrivacyToggleTileUserActionInteractor.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.sensorprivacy.domain
+package com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor
 
 import android.content.Intent
 import android.hardware.SensorPrivacyManager.Sensors.Sensor
@@ -23,11 +23,11 @@
 import android.safetycenter.SafetyCenterManager
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.policy.IndividualSensorPrivacyController
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapper.kt
similarity index 85%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapper.kt
index f54f46c..e9d5f52 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyToggleTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/mapper/SensorPrivacyToggleTileMapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,14 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.sensorprivacy.ui
+package com.android.systemui.qs.tiles.impl.sensorprivacy.ui.mapper
 
 import android.content.res.Resources
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import dagger.assisted.Assisted
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyTileResources.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/model/SensorPrivacyTileResources.kt
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyTileResources.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/model/SensorPrivacyTileResources.kt
index 2a9fd07..e65ae00 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/SensorPrivacyTileResources.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/sensorprivacy/ui/model/SensorPrivacyTileResources.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,12 +14,13 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.sensorprivacy.ui
+package com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model
 
 import com.android.systemui.res.R
 
 sealed interface SensorPrivacyTileResources {
     fun getIconRes(isBlocked: Boolean): Int
+
     fun getTileLabelRes(): Int
 
     data object CameraPrivacyTileResources : SensorPrivacyTileResources {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt
index 925b913..17c2f83 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileDataInteractor.kt
@@ -21,9 +21,9 @@
 import android.content.res.Configuration
 import android.os.UserHandle
 import com.android.systemui.common.coroutine.ConflatedCallbackFlow
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
+import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.statusbar.policy.BatteryController
 import com.android.systemui.statusbar.policy.ConfigurationController
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt
index 8897828..8af5fed 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/UiModeNightTileUserActionInteractor.kt
@@ -20,11 +20,11 @@
 import android.content.Intent
 import android.provider.Settings
 import com.android.systemui.dagger.qualifiers.Background
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
+import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel
 import javax.inject.Inject
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.withContext
@@ -51,7 +51,7 @@
                 is QSTileUserAction.LongClick -> {
                     qsTileIntentUserActionHandler.handle(
                         action.expandable,
-                        Intent(Settings.ACTION_DARK_THEME_SETTINGS)
+                        Intent(Settings.ACTION_DARK_THEME_SETTINGS),
                     )
                 }
                 is QSTileUserAction.ToggleClick -> {}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/model/UiModeNightTileModel.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/model/UiModeNightTileModel.kt
similarity index 89%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/model/UiModeNightTileModel.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/model/UiModeNightTileModel.kt
index 4fa1306..edb899b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/model/UiModeNightTileModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/interactor/model/UiModeNightTileModel.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.uimodenight.domain.model
+package com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model
 
 import java.time.LocalTime
 
@@ -31,5 +31,5 @@
     val nightModeCustomType: Int,
     val is24HourFormat: Boolean,
     val customNightModeEnd: LocalTime,
-    val customNightModeStart: LocalTime
+    val customNightModeStart: LocalTime,
 )
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapper.kt
similarity index 92%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapper.kt
index 5933d65..91c0451 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/domain/UiModeNightTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/uimodenight/ui/mapper/UiModeNightTileMapper.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.uimodenight.domain
+package com.android.systemui.qs.tiles.impl.uimodenight.ui.mapper
 
 import android.app.UiModeManager
 import android.content.res.Resources
 import android.content.res.Resources.Theme
 import android.text.TextUtils
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import java.time.LocalTime
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractor.kt
index a2a9e87a..eabeb5d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileDataInteractor.kt
@@ -17,8 +17,8 @@
 package com.android.systemui.qs.tiles.impl.work.domain.interactor
 
 import android.os.UserHandle
-import com.android.systemui.qs.tiles.base.interactor.DataUpdateTrigger
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileDataInteractor
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
 import com.android.systemui.statusbar.phone.ManagedProfileController
 import com.android.systemui.util.kotlin.hasActiveWorkProfile
@@ -29,12 +29,11 @@
 /** Observes data saver state changes providing the [WorkModeTileModel]. */
 class WorkModeTileDataInteractor
 @Inject
-constructor(
-    private val profileController: ManagedProfileController,
-) : QSTileDataInteractor<WorkModeTileModel> {
+constructor(private val profileController: ManagedProfileController) :
+    QSTileDataInteractor<WorkModeTileModel> {
     override fun tileData(
         user: UserHandle,
-        triggers: Flow<DataUpdateTrigger>
+        triggers: Flow<DataUpdateTrigger>,
     ): Flow<WorkModeTileModel> =
         profileController.hasActiveWorkProfile.map { hasActiveWorkProfile: Boolean ->
             if (hasActiveWorkProfile) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt
index 45ae09e..42cc996 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/domain/interactor/WorkModeTileUserActionInteractor.kt
@@ -18,11 +18,11 @@
 
 import android.content.Intent
 import android.provider.Settings
-import com.android.systemui.qs.tiles.base.actions.QSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.interactor.QSTileInput
-import com.android.systemui.qs.tiles.base.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.actions.QSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileUserActionInteractor
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
 import com.android.systemui.statusbar.phone.ManagedProfileController
 import javax.inject.Inject
 
@@ -45,7 +45,7 @@
                     if (data is WorkModeTileModel.HasActiveProfile) {
                         qsTileIntentUserActionHandler.handle(
                             action.expandable,
-                            Intent(Settings.ACTION_MANAGED_PROFILE_SETTINGS)
+                            Intent(Settings.ACTION_MANAGED_PROFILE_SETTINGS),
                         )
                     }
                 }
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapper.kt
similarity index 91%
rename from packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt
rename to packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapper.kt
index 5b462ba..a67c76d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/WorkModeTileMapper.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/impl/work/ui/mapper/WorkModeTileMapper.kt
@@ -14,17 +14,17 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.work.ui
+package com.android.systemui.qs.tiles.impl.work.ui.mapper
 
 import android.app.admin.DevicePolicyManager
 import android.app.admin.DevicePolicyResources.Strings.SystemUi.QS_WORK_PROFILE_LABEL
 import android.content.res.Resources
 import android.service.quicksettings.Tile
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.qs.tiles.base.interactor.QSTileDataToStateMapper
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.ui.model.QSTileDataToStateMapper
 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
 import com.android.systemui.res.R
 import com.android.systemui.shade.ShadeDisplayAware
 import javax.inject.Inject
diff --git a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayCoreStartable.kt b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayCoreStartable.kt
index bc15bbb..263ef09e 100644
--- a/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayCoreStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/reardisplay/RearDisplayCoreStartable.kt
@@ -20,6 +20,8 @@
 import android.hardware.devicestate.DeviceStateManager
 import android.hardware.devicestate.feature.flags.Flags
 import androidx.annotation.VisibleForTesting
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Application
@@ -28,8 +30,11 @@
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.Job
-import kotlinx.coroutines.flow.launchIn
-import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.launch
 
 /**
  * Provides a {@link com.android.systemui.statusbar.phone.SystemUIDialog} to be shown on the inner
@@ -46,6 +51,7 @@
     private val rearDisplayStateInteractor: RearDisplayStateInteractor,
     private val rearDisplayInnerDialogDelegateFactory: RearDisplayInnerDialogDelegate.Factory,
     @Application private val scope: CoroutineScope,
+    private val keyguardUpdateMonitor: KeyguardUpdateMonitor,
 ) : CoreStartable, AutoCloseable {
 
     companion object {
@@ -53,6 +59,16 @@
     }
 
     @VisibleForTesting var stateChangeListener: Job? = null
+    private val keyguardVisible = MutableStateFlow(false)
+    private val keyguardVisibleFlow = keyguardVisible.asStateFlow()
+
+    @VisibleForTesting
+    val keyguardCallback =
+        object : KeyguardUpdateMonitorCallback() {
+            override fun onKeyguardVisibilityChanged(visible: Boolean) {
+                keyguardVisible.value = visible
+            }
+        }
 
     override fun close() {
         stateChangeListener?.cancel()
@@ -62,28 +78,39 @@
         if (Flags.deviceStateRdmV2()) {
             var dialog: SystemUIDialog? = null
 
-            stateChangeListener =
-                rearDisplayStateInteractor.state
-                    .map {
-                        when (it) {
-                            is RearDisplayStateInteractor.State.Enabled -> {
-                                val rearDisplayContext =
-                                    context.createDisplayContext(it.innerDisplay)
-                                val delegate =
-                                    rearDisplayInnerDialogDelegateFactory.create(
-                                        rearDisplayContext,
-                                        deviceStateManager::cancelStateRequest,
-                                    )
-                                dialog = delegate.createDialog().apply { show() }
-                            }
+            keyguardUpdateMonitor.registerCallback(keyguardCallback)
 
-                            is RearDisplayStateInteractor.State.Disabled -> {
-                                dialog?.dismiss()
-                                dialog = null
+            stateChangeListener =
+                scope.launch {
+                    combine(rearDisplayStateInteractor.state, keyguardVisibleFlow) {
+                            rearDisplayState,
+                            keyguardVisible ->
+                            Pair(rearDisplayState, keyguardVisible)
+                        }
+                        .collectLatest { (rearDisplayState, keyguardVisible) ->
+                            when (rearDisplayState) {
+                                is RearDisplayStateInteractor.State.Enabled -> {
+                                    if (!keyguardVisible) {
+                                        val rearDisplayContext =
+                                            context.createDisplayContext(
+                                                rearDisplayState.innerDisplay
+                                            )
+                                        val delegate =
+                                            rearDisplayInnerDialogDelegateFactory.create(
+                                                rearDisplayContext,
+                                                deviceStateManager::cancelStateRequest,
+                                            )
+                                        dialog = delegate.createDialog().apply { show() }
+                                    }
+                                }
+
+                                is RearDisplayStateInteractor.State.Disabled -> {
+                                    dialog?.dismiss()
+                                    dialog = null
+                                }
                             }
                         }
-                    }
-                    .launchIn(scope)
+                }
         }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
index 4be35f1..5b97175 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/LauncherProxyService.java
@@ -78,6 +78,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.app.displaylib.PerDisplayRepository;
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.app.AssistUtils;
 import com.android.internal.app.IVoiceInteractionSessionListener;
@@ -89,6 +90,7 @@
 import com.android.systemui.contextualeducation.GestureType;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.display.data.repository.DisplayRepository;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
 import com.android.systemui.keyguard.KeyguardWmStateRefactor;
@@ -109,6 +111,7 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shade.ShadeViewController;
 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
+import com.android.systemui.shade.shared.flag.ShadeWindowGoesAround;
 import com.android.systemui.shared.recents.ILauncherProxy;
 import com.android.systemui.shared.recents.ISystemUiProxy;
 import com.android.systemui.shared.system.QuickStepContract;
@@ -123,8 +126,6 @@
 import com.android.wm.shell.shared.desktopmode.DesktopModeStatus;
 import com.android.wm.shell.sysui.ShellInterface;
 
-import dagger.Lazy;
-
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
@@ -136,6 +137,8 @@
 import javax.inject.Inject;
 import javax.inject.Provider;
 
+import dagger.Lazy;
+
 /**
  * Class to send information from SysUI to Launcher with a binder.
  */
@@ -156,7 +159,9 @@
     private final Executor mMainExecutor;
     private final ShellInterface mShellInterface;
     private final Lazy<ShadeViewController> mShadeViewControllerLazy;
-    private SysUiState mSysUiState;
+    private final PerDisplayRepository<SysUiState> mPerDisplaySysUiStateRepository;
+    private final DisplayRepository mDisplayRepository;
+    private SysUiState mDefaultDisplaySysUIState;
     private final Handler mHandler;
     private final Lazy<NavigationBarController> mNavBarControllerLazy;
     private final ScreenPinningRequest mScreenPinningRequest;
@@ -586,9 +591,12 @@
 
             // Force-update the systemui state flags
             updateSystemUiStateFlags();
-            // TODO b/398011576 - send the state for all displays.
-            notifySystemUiStateFlags(mSysUiState.getFlags(), Display.DEFAULT_DISPLAY);
-
+            if (ShadeWindowGoesAround.isEnabled()) {
+               notifySysUiStateFlagsForAllDisplays();
+            } else {
+                notifySystemUiStateFlags(mDefaultDisplaySysUIState.getFlags(),
+                        Display.DEFAULT_DISPLAY);
+            }
             notifyConnectionChanged();
         }
 
@@ -614,6 +622,18 @@
         }
     };
 
+    /** Propagates the flags for all displays to be notified to Launcher. */
+    @VisibleForTesting
+    public void notifySysUiStateFlagsForAllDisplays() {
+        var displays = mDisplayRepository.getDisplayIds().getValue();
+        for (int displayId : displays) {
+            var state = mPerDisplaySysUiStateRepository.get(displayId);
+            if (state != null) {
+                notifySystemUiStateFlags(state.getFlags(), displayId);
+            }
+        }
+    }
+
     private final StatusBarWindowCallback mStatusBarWindowCallback = this::onStatusBarStateChanged;
 
     // This is the death handler for the binder from the launcher service
@@ -671,7 +691,7 @@
             ScreenPinningRequest screenPinningRequest,
             NavigationModeController navModeController,
             NotificationShadeWindowController statusBarWinController,
-            SysUiState sysUiState,
+            PerDisplayRepository<SysUiState> perDisplaySysUiStateRepository,
             Provider<SceneInteractor> sceneInteractor,
             Provider<ShadeInteractor> shadeInteractor,
             UserTracker userTracker,
@@ -686,7 +706,8 @@
             Optional<UnfoldTransitionProgressForwarder> unfoldTransitionProgressForwarder,
             BroadcastDispatcher broadcastDispatcher,
             Optional<BackAnimation> backAnimation,
-            ProcessWrapper processWrapper
+            ProcessWrapper processWrapper,
+            DisplayRepository displayRepository
     ) {
         // b/241601880: This component should only be running for primary users or
         // secondaryUsers when visibleBackgroundUsers are supported.
@@ -718,10 +739,10 @@
                 com.android.internal.R.string.config_recentsComponentName));
         mQuickStepIntent = new Intent(ACTION_QUICKSTEP)
                 .setPackage(mRecentsComponentName.getPackageName());
-        // TODO b/398011576 - Here we're still only handling the default display state. We should
-        //  have a callback for any sysuiState change.
-        mSysUiState = sysUiState;
-        mSysUiState.addCallback(mSysUiStateCallback);
+        mPerDisplaySysUiStateRepository = perDisplaySysUiStateRepository;
+        mDisplayRepository = displayRepository;
+        mDefaultDisplaySysUIState = perDisplaySysUiStateRepository.get(Display.DEFAULT_DISPLAY);
+        mDefaultDisplaySysUIState.addCallback(mSysUiStateCallback);
         mUiEventLogger = uiEventLogger;
         mDisplayTracker = displayTracker;
         mUnfoldTransitionProgressForwarder = unfoldTransitionProgressForwarder;
@@ -770,7 +791,7 @@
                 if (mLauncherProxy != null) {
                     try {
                         if (DesktopModeStatus.canEnterDesktopMode(mContext)
-                                && (sysUiState.getFlags()
+                                && (mDefaultDisplaySysUIState.getFlags()
                                 & SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE) != 0) {
                             return;
                         }
@@ -795,7 +816,7 @@
     }
 
     public void onVoiceSessionWindowVisibilityChanged(boolean visible) {
-        mSysUiState.setFlag(SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING, visible)
+        mDefaultDisplaySysUIState.setFlag(SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING, visible)
                 .commitUpdate(mContext.getDisplayId());
     }
 
@@ -804,23 +825,42 @@
         startConnectionToCurrentUser();
     }
 
-    private void updateSystemUiStateFlags() {
+    private void updateSysUIStateForNavbars() {
+        if (ShadeWindowGoesAround.isEnabled()) {
+            var displays = mDisplayRepository.getDisplayIds().getValue();
+            for (int displayId : displays) {
+                updateSysUIStateForNavbarWithDisplayId(displayId);
+            }
+        } else {
+            updateSysUIStateForNavbarWithDisplayId(Display.DEFAULT_DISPLAY);
+        }
+    }
+
+    private void updateSysUIStateForNavbarWithDisplayId(int displayId) {
         final NavigationBar navBarFragment =
-                mNavBarControllerLazy.get().getDefaultNavigationBar();
+                mNavBarControllerLazy.get().getNavigationBar(displayId);
         final NavigationBarView navBarView =
-                mNavBarControllerLazy.get().getNavigationBarView(mContext.getDisplayId());
+                mNavBarControllerLazy.get().getNavigationBarView(displayId);
         if (SysUiState.DEBUG) {
             Log.d(TAG_OPS, "Updating sysui state flags: navBarFragment=" + navBarFragment
                     + " navBarView=" + navBarView
                     + " shadeViewController=" + mShadeViewControllerLazy.get());
         }
 
+        final SysUiState displaySysuiState = mPerDisplaySysUiStateRepository.get(displayId);
+        if (displaySysuiState == null) return;
+
         if (navBarFragment != null) {
             navBarFragment.updateSystemUiStateFlags();
         }
         if (navBarView != null) {
-            navBarView.updateDisabledSystemUiStateFlags(mSysUiState);
+            navBarView.updateDisabledSystemUiStateFlags(displaySysuiState);
         }
+    }
+
+    /** Force updates SystemUI state flags prior to sending them to Launcher. */
+    public void updateSystemUiStateFlags() {
+        updateSysUIStateForNavbars();
         mShadeViewControllerLazy.get().updateSystemUiStateFlags();
         if (mStatusBarWinController != null) {
             mStatusBarWinController.notifyStateChangedCallbacks();
@@ -845,7 +885,7 @@
     private void onStatusBarStateChanged(boolean keyguardShowing, boolean keyguardOccluded,
             boolean keyguardGoingAway, boolean bouncerShowing, boolean isDozing,
             boolean panelExpanded, boolean isDreaming, boolean communalShowing) {
-        mSysUiState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
+        mDefaultDisplaySysUIState.setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
                         keyguardShowing && !keyguardOccluded)
                 .setFlag(SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
                         keyguardShowing && keyguardOccluded)
@@ -1122,7 +1162,7 @@
             new WakefulnessLifecycle.Observer() {
                 @Override
                 public void onStartedWakingUp() {
-                    mSysUiState
+                    mDefaultDisplaySysUIState
                             .setFlag(SYSUI_STATE_AWAKE, true)
                             .setFlag(SYSUI_STATE_WAKEFULNESS_TRANSITION, true)
                             .commitUpdate(mContext.getDisplayId());
@@ -1130,7 +1170,7 @@
 
                 @Override
                 public void onFinishedWakingUp() {
-                    mSysUiState
+                    mDefaultDisplaySysUIState
                             .setFlag(SYSUI_STATE_AWAKE, true)
                             .setFlag(SYSUI_STATE_WAKEFULNESS_TRANSITION, false)
                             .commitUpdate(mContext.getDisplayId());
@@ -1138,7 +1178,7 @@
 
                 @Override
                 public void onStartedGoingToSleep() {
-                    mSysUiState
+                    mDefaultDisplaySysUIState
                             .setFlag(SYSUI_STATE_AWAKE, false)
                             .setFlag(SYSUI_STATE_WAKEFULNESS_TRANSITION, true)
                             .commitUpdate(mContext.getDisplayId());
@@ -1146,7 +1186,7 @@
 
                 @Override
                 public void onFinishedGoingToSleep() {
-                    mSysUiState
+                    mDefaultDisplaySysUIState
                             .setFlag(SYSUI_STATE_AWAKE, false)
                             .setFlag(SYSUI_STATE_WAKEFULNESS_TRANSITION, false)
                             .commitUpdate(mContext.getDisplayId());
@@ -1247,7 +1287,7 @@
         pw.print("  mActiveNavBarRegion="); pw.println(mActiveNavBarRegion);
         pw.print("  mNavBarMode="); pw.println(mNavBarMode);
         pw.print("  mIsPrevServiceCleanedUp="); pw.println(mIsPrevServiceCleanedUp);
-        mSysUiState.dump(pw, args);
+        mDefaultDisplaySysUIState.dump(pw, args);
     }
 
     public interface LauncherProxyListener {
diff --git a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
index c092c2f..9023c62 100644
--- a/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/recordissue/RecordIssueModule.kt
@@ -22,15 +22,15 @@
 import com.android.systemui.qs.shared.model.TileCategory
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.RecordIssueTile
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
-import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingDataInteractor
-import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingMapper
-import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingModel
-import com.android.systemui.qs.tiles.impl.irecording.IssueRecordingUserActionInteractor
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
-import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel
+import com.android.systemui.qs.tiles.impl.irecording.data.model.IssueRecordingModel
+import com.android.systemui.qs.tiles.impl.irecording.domain.interactor.IssueRecordingDataInteractor
+import com.android.systemui.qs.tiles.impl.irecording.domain.interactor.IssueRecordingUserActionInteractor
+import com.android.systemui.qs.tiles.impl.irecording.ui.mapper.IssueRecordingMapper
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
@@ -59,7 +59,7 @@
                 uiConfig =
                     QSTileUIConfig.Resource(
                         iconRes = R.drawable.qs_record_issue_icon_off,
-                        labelRes = R.string.qs_record_issue_label
+                        labelRes = R.string.qs_record_issue_label,
                     ),
                 instanceId = uiEventLogger.getNewInstanceId(),
                 category = TileCategory.UTILITIES,
@@ -73,7 +73,7 @@
             factory: QSTileViewModelFactory.Static<IssueRecordingModel>,
             mapper: IssueRecordingMapper,
             stateInteractor: IssueRecordingDataInteractor,
-            userActionInteractor: IssueRecordingUserActionInteractor
+            userActionInteractor: IssueRecordingUserActionInteractor,
         ): QSTileViewModel =
             if (Flags.qsNewTilesFuture())
                 factory.create(
diff --git a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
index c9712fc..ba5b4ff 100644
--- a/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/rotationlock/RotationLockNewModule.kt
@@ -20,15 +20,15 @@
 import com.android.systemui.qs.QsEventLogger
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.shared.model.TileCategory
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
 import com.android.systemui.qs.tiles.impl.rotation.domain.interactor.RotationLockTileDataInteractor
 import com.android.systemui.qs.tiles.impl.rotation.domain.interactor.RotationLockTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.rotation.domain.model.RotationLockTileModel
 import com.android.systemui.qs.tiles.impl.rotation.ui.mapper.RotationLockTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
@@ -73,7 +73,7 @@
             factory: QSTileViewModelFactory.Static<RotationLockTileModel>,
             mapper: RotationLockTileMapper,
             stateInteractor: RotationLockTileDataInteractor,
-            userActionInteractor: RotationLockTileUserActionInteractor
+            userActionInteractor: RotationLockTileUserActionInteractor,
         ): QSTileViewModel =
             factory.create(
                 TileSpec.create(ROTATION_TILE_SPEC),
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
index 9a9c576..b4cc055 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/ScreenRecordModule.kt
@@ -24,14 +24,14 @@
 import com.android.systemui.qs.shared.model.TileCategory
 import com.android.systemui.qs.tileimpl.QSTileImpl
 import com.android.systemui.qs.tiles.ScreenRecordTile
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
 import com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor.ScreenRecordTileDataInteractor
 import com.android.systemui.qs.tiles.impl.screenrecord.domain.interactor.ScreenRecordTileUserActionInteractor
-import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.ScreenRecordTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.impl.screenrecord.domain.ui.mapper.ScreenRecordTileMapper
 import com.android.systemui.res.R
 import com.android.systemui.screenrecord.data.model.ScreenRecordModel
 import com.android.systemui.screenrecord.data.repository.ScreenRecordRepository
@@ -86,7 +86,7 @@
             factory: QSTileViewModelFactory.Static<ScreenRecordModel>,
             mapper: ScreenRecordTileMapper,
             stateInteractor: ScreenRecordTileDataInteractor,
-            userActionInteractor: ScreenRecordTileUserActionInteractor
+            userActionInteractor: ScreenRecordTileUserActionInteractor,
         ): QSTileViewModel =
             factory.create(
                 TileSpec.create(SCREEN_RECORD_TILE_SPEC),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
index f45971b..9940ae5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
@@ -16,12 +16,15 @@
 
 package com.android.systemui.statusbar
 
+import android.annotation.SuppressLint
 import android.app.ActivityManager
 import android.content.res.Resources
+import android.os.Build
 import android.os.SystemProperties
 import android.os.Trace
 import android.os.Trace.TRACE_TAG_APP
 import android.util.IndentingPrintWriter
+import android.util.Log
 import android.util.MathUtils
 import android.view.CrossWindowBlurListeners
 import android.view.CrossWindowBlurListeners.CROSS_WINDOW_BLUR_SUPPORTED
@@ -45,7 +48,7 @@
     private val crossWindowBlurListeners: CrossWindowBlurListeners,
     dumpManager: DumpManager
 ) : Dumpable {
-    val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius).toFloat();
+    val minBlurRadius = resources.getDimensionPixelSize(R.dimen.min_window_blur_radius).toFloat()
     val maxBlurRadius = if (Flags.notificationShadeBlur()) {
         blurConfig.maxBlurRadiusPx
     } else {
@@ -55,6 +58,9 @@
     private var lastAppliedBlur = 0
     private var earlyWakeupEnabled = false
 
+    /** When this is true, early wakeup flag is not reset on surface flinger when blur drops to 0 */
+    private var persistentEarlyWakeupRequired = false
+
     init {
         dumpManager.registerDumpable(this)
     }
@@ -86,16 +92,13 @@
      */
     fun prepareBlur(viewRootImpl: ViewRootImpl?, radius: Int) {
         if (viewRootImpl == null || !viewRootImpl.surfaceControl.isValid ||
-            !supportsBlursOnWindows() || earlyWakeupEnabled
+            !shouldBlur(radius) || earlyWakeupEnabled
         ) {
             return
         }
         if (lastAppliedBlur == 0 && radius != 0) {
-            Trace.asyncTraceForTrackBegin(
-                    TRACE_TAG_APP, TRACK_NAME, "eEarlyWakeup (prepareBlur)", 0)
-            earlyWakeupEnabled = true
             createTransaction().use {
-                it.setEarlyWakeupStart()
+                earlyWakeupStart(it, "eEarlyWakeup (prepareBlur)")
                 it.apply()
             }
         }
@@ -113,22 +116,18 @@
             return
         }
         createTransaction().use {
-            if (supportsBlursOnWindows()) {
+            if (shouldBlur(radius)) {
                 it.setBackgroundBlurRadius(viewRootImpl.surfaceControl, radius)
                 if (!earlyWakeupEnabled && lastAppliedBlur == 0 && radius != 0) {
-                    Trace.asyncTraceForTrackBegin(
-                        TRACE_TAG_APP,
-                        TRACK_NAME,
-                        "eEarlyWakeup (applyBlur)",
-                        0
-                    )
-                    it.setEarlyWakeupStart()
-                    earlyWakeupEnabled = true
+                    earlyWakeupStart(it, "eEarlyWakeup (applyBlur)")
                 }
-                if (earlyWakeupEnabled && lastAppliedBlur != 0 && radius == 0) {
-                    it.setEarlyWakeupEnd()
-                    Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, TRACK_NAME, 0)
-                    earlyWakeupEnabled = false
+                if (
+                    earlyWakeupEnabled &&
+                        lastAppliedBlur != 0 &&
+                        radius == 0 &&
+                        !persistentEarlyWakeupRequired
+                ) {
+                    earlyWakeupEnd(it, "applyBlur")
                 }
                 lastAppliedBlur = radius
             }
@@ -137,11 +136,39 @@
         }
     }
 
+    private fun v(verboseLog: String) {
+        if (isLoggable) Log.v(TAG, verboseLog)
+    }
+
+    @SuppressLint("MissingPermission")
+    private fun earlyWakeupStart(transaction: SurfaceControl.Transaction, traceMethodName: String) {
+        v("earlyWakeupStart from $traceMethodName")
+        Trace.asyncTraceForTrackBegin(TRACE_TAG_APP, TRACK_NAME, traceMethodName, 0)
+        transaction.setEarlyWakeupStart()
+        earlyWakeupEnabled = true
+    }
+
+    @SuppressLint("MissingPermission")
+    private fun earlyWakeupEnd(transaction: SurfaceControl.Transaction, loggingContext: String) {
+        v("earlyWakeupEnd from $loggingContext")
+        transaction.setEarlyWakeupEnd()
+        Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, TRACK_NAME, 0)
+        earlyWakeupEnabled = false
+    }
+
     @VisibleForTesting
     open fun createTransaction(): SurfaceControl.Transaction {
         return SurfaceControl.Transaction()
     }
 
+    private fun shouldBlur(radius: Int): Boolean {
+        return supportsBlursOnWindows() ||
+                ((Flags.notificationShadeBlur() || Flags.bouncerUiRevamp()) &&
+                        supportsBlursOnWindowsBase() &&
+                        lastAppliedBlur > 0 &&
+                        radius == 0)
+    }
+
     /**
      * If this device can render blurs.
      *
@@ -149,8 +176,11 @@
      * @return {@code true} when supported.
      */
     open fun supportsBlursOnWindows(): Boolean {
+        return supportsBlursOnWindowsBase() && crossWindowBlurListeners.isCrossWindowBlurEnabled
+    }
+
+    private fun supportsBlursOnWindowsBase(): Boolean {
         return CROSS_WINDOW_BLUR_SUPPORTED && ActivityManager.isHighEndGfx() &&
-                crossWindowBlurListeners.isCrossWindowBlurEnabled() &&
                 !SystemProperties.getBoolean("persist.sysui.disableBlur", false)
     }
 
@@ -166,7 +196,39 @@
         }
     }
 
+    /**
+     * Enables/disables the early wakeup flag on surface flinger. Keeps the early wakeup flag on
+     * until it reset by passing false to this method.
+     */
+    fun setPersistentEarlyWakeup(persistentWakeup: Boolean, viewRootImpl: ViewRootImpl?) {
+        persistentEarlyWakeupRequired = persistentWakeup
+        if (viewRootImpl == null || !supportsBlursOnWindows()) return
+        if (persistentEarlyWakeupRequired) {
+            if (earlyWakeupEnabled) return
+            createTransaction().use {
+                earlyWakeupStart(it, "setEarlyWakeup")
+                it.apply()
+            }
+        } else {
+            if (!earlyWakeupEnabled) return
+            if (lastAppliedBlur > 0) {
+                Log.w(
+                    TAG,
+                    "resetEarlyWakeup invoked when lastAppliedBlur $lastAppliedBlur is " +
+                        "non-zero, this means that the early wakeup signal was reset while blur" +
+                        " was still active",
+                )
+            }
+            createTransaction().use {
+                earlyWakeupEnd(it, "resetEarlyWakeup")
+                it.apply()
+            }
+        }
+    }
+
     companion object {
         const val TRACK_NAME = "BlurUtils"
+        private const val TAG = "BlurUtils"
+        private val isLoggable = Log.isLoggable(TAG, Log.VERBOSE) || Build.isDebuggable()
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
index 05ef164..d2f424a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
@@ -394,7 +394,7 @@
                 // Only drag down on sensitive views, otherwise the ExpandHelper will take this
                 return if (NotificationBundleUi.isEnabled)
                     view.entryAdapter?.isSensitive?.value == true
-                else view.entry.isSensitive.value
+                else view.entryLegacy.isSensitive.value
             }
         }
         return false
@@ -569,7 +569,7 @@
             if (NotificationBundleUi.isEnabled) {
                 userId = expandView.entryAdapter?.sbn?.userId!!
             } else {
-                userId = expandView.entry.sbn.userId
+                userId = expandView.entryLegacy.sbn.userId
             }
         }
         var fullShadeNeedsBouncer =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 339f898..9bf3d5d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -47,7 +47,6 @@
 import android.net.Uri;
 import android.os.Looper;
 import android.os.Process;
-import android.os.SystemClock;
 import android.os.UserHandle;
 import android.os.UserManager;
 import android.provider.Settings;
@@ -78,6 +77,7 @@
 import com.android.systemui.settings.UserTracker;
 import com.android.systemui.shared.system.SysUiStatsLog;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime;
 import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
 import com.android.systemui.statusbar.notification.row.shared.LockscreenOtpRedaction;
@@ -920,7 +920,9 @@
     // notification's "when" time, or the notification entry creation time
     private long getEarliestNotificationTime(NotificationEntry notif) {
         long notifWhenWallClock = notif.getSbn().getNotification().getWhen();
-        long creationTimeDelta = SystemClock.uptimeMillis() - notif.getCreationTime();
+        long creationTimeDelta = UseElapsedRealtimeForCreationTime.getCurrentTime()
+                - notif.getCreationTime();
+
         long creationTimeWallClock = System.currentTimeMillis() - creationTimeDelta;
         return Math.min(notifWhenWallClock, creationTimeWallClock);
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 041ed65..485d5b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -169,7 +169,7 @@
                         if (NotificationBundleUi.isEnabled()) {
                             releaseNotificationIfKeptForRemoteInputHistory(row.getEntryAdapter());
                         } else {
-                            releaseNotificationIfKeptForRemoteInputHistory(row.getEntry());
+                            releaseNotificationIfKeptForRemoteInputHistory(row.getEntryLegacy());
                         }
                     }
                     return started;
@@ -189,8 +189,8 @@
                     statusBarNotification = row.getEntryAdapter().getSbn();
                 }
             } else {
-                if (row.getEntry() != null) {
-                    statusBarNotification = row.getEntry().getSbn();
+                if (row.getEntryLegacy() != null) {
+                    statusBarNotification = row.getEntryLegacy().getSbn();
                 }
             }
             if (statusBarNotification == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
index 81685ab..472dc82 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
@@ -435,6 +435,7 @@
                 }
             }
         }
+        initBlurListeners()
     }
 
     private fun initBlurListeners() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index f88c618..c2a87cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -675,7 +675,7 @@
         }
         StatusBarIconView icon = NotificationBundleUi.isEnabled()
                 ? row.getEntryAdapter().getIcons().getShelfIcon()
-                : row.getEntry().getIcons().getShelfIcon();
+                : row.getEntryLegacy().getIcons().getShelfIcon();
         float shelfIconPosition = getTranslationY() + icon.getTop() + icon.getTranslationY();
         if (shelfIconPosition < maxTop && !mAmbientState.isFullyHidden()) {
             int top = (int) (maxTop - shelfIconPosition);
@@ -689,7 +689,7 @@
     private void updateContinuousClipping(final ExpandableNotificationRow row) {
         StatusBarIconView icon = NotificationBundleUi.isEnabled()
                 ? row.getEntryAdapter().getIcons().getShelfIcon()
-                : row.getEntry().getIcons().getShelfIcon();
+                : row.getEntryLegacy().getIcons().getShelfIcon();
         boolean needsContinuousClipping = ViewState.isAnimatingY(icon) && !mAmbientState.isDozing();
         boolean isContinuousClipping = icon.getTag(TAG_CONTINUOUS_CLIPPING) != null;
         if (needsContinuousClipping && !isContinuousClipping) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
index 6cebcd9..6d3c12d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/OWNERS
@@ -18,10 +18,10 @@
 per-file *Notification* = file:notification/OWNERS
 # Files that control blur effects on shade
 per-file *NotificationShadeDepth* = set noparent
-per-file *NotificationShadeDepth* = shanh@google.com, rahulbanerjee@google.com
+per-file *NotificationShadeDepth* = shanh@google.com, rahulbanerjee@google.com, tracyzhou@google.com
 per-file *NotificationShadeDepth* = file:../keyguard/OWNERS
 per-file *Blur* = set noparent
-per-file *Blur* = shanh@google.com, rahulbanerjee@google.com
+per-file *Blur* = shanh@google.com, rahulbanerjee@google.com, tracyzhou@google.com
 # Not setting noparent here, since *Mode* matches many other classes (e.g., *ViewModel*)
 per-file *Mode* = file:notification/OWNERS
 per-file *SmartReply* = set noparent
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
index 7e70312..9cae6c1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/call/ui/viewmodel/CallChipViewModel.kt
@@ -17,10 +17,13 @@
 package com.android.systemui.statusbar.chips.call.ui.viewmodel
 
 import android.app.PendingIntent
+import android.content.ComponentName
 import android.content.Context
 import android.view.View
 import com.android.internal.jank.Cuj
 import com.android.systemui.animation.ActivityTransitionAnimator
+import com.android.systemui.animation.ComposableControllerFactory
+import com.android.systemui.animation.DelegateTransitionAnimatorController
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.dagger.SysUISingleton
@@ -48,7 +51,10 @@
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.mapNotNull
 import kotlinx.coroutines.flow.stateIn
 
 /** View model for the ongoing phone call chip shown in the status bar. */
@@ -63,14 +69,63 @@
     private val activityStarter: ActivityStarter,
     @StatusBarChipsLog private val logger: LogBuffer,
 ) : OngoingActivityChipViewModel {
+    /** The transition cookie used to register and unregister launch and return animations. */
+    private val cookie =
+        ActivityTransitionAnimator.TransitionCookie("${CallChipViewModel::class.java}")
+
+    /**
+     * Used internally to determine when a launch or return animation is in progress, as these
+     * require special handling.
+     */
+    private val transitionState: MutableStateFlow<TransitionState> =
+        MutableStateFlow(TransitionState.NoTransition)
+
+    // Since we're combining the chip state and the transition state flows, getting the old value by
+    // using [pairwise()] would confuse things. This is because if the calculation is triggered by
+    // a change in transition state, the chip state will still show the previous and current values,
+    // making it difficult to figure out what actually changed. Instead we cache the old value here,
+    // so that at each update we can keep track of what actually changed.
+    private var latestState: OngoingCallModel = OngoingCallModel.NoCall
+    private var latestTransitionState: TransitionState = TransitionState.NoTransition
+
     private val chipWithReturnAnimation: StateFlow<OngoingActivityChipModel> =
         if (StatusBarChipsReturnAnimations.isEnabled) {
-            interactor.ongoingCallState
-                .map { state ->
-                    when (state) {
-                        is OngoingCallModel.NoCall -> OngoingActivityChipModel.Inactive()
+            combine(interactor.ongoingCallState, transitionState) { newState, newTransitionState ->
+                    val oldState = latestState
+                    latestState = newState
+                    val oldTransitionState = latestTransitionState
+                    latestTransitionState = newTransitionState
+
+                    logger.log(
+                        TAG,
+                        LogLevel.DEBUG,
+                        {},
+                        {
+                            "Call chip state updated: oldState=$oldState newState=$newState " +
+                                "oldTransitionState=$oldTransitionState " +
+                                "newTransitionState=$newTransitionState"
+                        },
+                    )
+
+                    when (newState) {
+                        is OngoingCallModel.NoCall ->
+                            OngoingActivityChipModel.Inactive(
+                                transitionManager = getTransitionManager(newState)
+                            )
+
                         is OngoingCallModel.InCall ->
-                            prepareChip(state, systemClock, isHidden = state.isAppVisible)
+                            prepareChip(
+                                newState,
+                                systemClock,
+                                isHidden =
+                                    shouldChipBeHidden(
+                                        oldState = oldState,
+                                        newState = newState,
+                                        oldTransitionState = oldTransitionState,
+                                        newTransitionState = newTransitionState,
+                                    ),
+                                transitionState = newTransitionState,
+                            )
                     }
                 }
                 .stateIn(
@@ -112,11 +167,18 @@
             chipLegacy
         }
 
+    /**
+     * The controller factory that the call chip uses to register and unregister its transition
+     * animations.
+     */
+    private var transitionControllerFactory: ComposableControllerFactory? = null
+
     /** Builds an [OngoingActivityChipModel.Active] from all the relevant information. */
     private fun prepareChip(
         state: OngoingCallModel.InCall,
         systemClock: SystemClock,
         isHidden: Boolean,
+        transitionState: TransitionState = TransitionState.NoTransition,
     ): OngoingActivityChipModel.Active {
         val key = state.notificationKey
         val contentDescription = getContentDescription(state.appName)
@@ -149,6 +211,7 @@
                 onClickListenerLegacy = getOnClickListener(state.intent),
                 clickBehavior = getClickBehavior(state.intent),
                 isHidden = isHidden,
+                transitionManager = getTransitionManager(state, transitionState),
             )
         } else {
             val startTimeInElapsedRealtime =
@@ -161,6 +224,7 @@
                 onClickListenerLegacy = getOnClickListener(state.intent),
                 clickBehavior = getClickBehavior(state.intent),
                 isHidden = isHidden,
+                transitionManager = getTransitionManager(state, transitionState),
             )
         }
     }
@@ -191,9 +255,21 @@
                 onClick = { expandable ->
                     StatusBarChipsModernization.unsafeAssertInNewMode()
                     val animationController =
-                        expandable.activityTransitionController(
-                            Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP
-                        )
+                        if (
+                            !StatusBarChipsReturnAnimations.isEnabled ||
+                                transitionControllerFactory == null
+                        ) {
+                            expandable.activityTransitionController(
+                                Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP
+                            )
+                        } else {
+                            // When return animations are enabled, we use a long-lived registration
+                            // with controllers created on-demand by the animation library instead
+                            // of explicitly creating one at the time of the click. By not passing
+                            // a controller here, we let the framework do its work. Otherwise, the
+                            // explicit controller would take precedence and override the other one.
+                            null
+                        }
                     activityStarter.postStartActivityDismissingKeyguard(intent, animationController)
                 }
             )
@@ -210,6 +286,125 @@
         )
     }
 
+    private fun getTransitionManager(
+        state: OngoingCallModel,
+        transitionState: TransitionState = TransitionState.NoTransition,
+    ): OngoingActivityChipModel.TransitionManager? {
+        if (!StatusBarChipsReturnAnimations.isEnabled) return null
+        return if (state is OngoingCallModel.NoCall) {
+            OngoingActivityChipModel.TransitionManager(
+                unregisterTransition = { activityStarter.unregisterTransition(cookie) }
+            )
+        } else {
+            val component = (state as OngoingCallModel.InCall).intent?.intent?.component
+            if (component != null) {
+                val factory = getTransitionControllerFactory(component)
+                OngoingActivityChipModel.TransitionManager(
+                    factory,
+                    registerTransition = {
+                        activityStarter.registerTransition(cookie, factory, scope)
+                    },
+                    // Make the chip invisible at the beginning of the return transition to avoid
+                    // it flickering.
+                    hideChipForTransition = transitionState is TransitionState.ReturnRequested,
+                )
+            } else {
+                // Without a component we can't instantiate a controller factory, and without a
+                // factory registering an animation is impossible. In this case, the transition
+                // manager is empty and inert.
+                OngoingActivityChipModel.TransitionManager()
+            }
+        }
+    }
+
+    private fun getTransitionControllerFactory(
+        component: ComponentName
+    ): ComposableControllerFactory {
+        var factory = transitionControllerFactory
+        if (factory?.component == component) return factory
+
+        factory =
+            object :
+                ComposableControllerFactory(
+                    cookie,
+                    component,
+                    launchCujType = Cuj.CUJ_STATUS_BAR_APP_LAUNCH_FROM_CALL_CHIP,
+                    returnCujType = Cuj.CUJ_STATUS_BAR_APP_RETURN_TO_CALL_CHIP,
+                ) {
+                override suspend fun createController(
+                    forLaunch: Boolean
+                ): ActivityTransitionAnimator.Controller {
+                    transitionState.value =
+                        if (forLaunch) {
+                            TransitionState.LaunchRequested
+                        } else {
+                            TransitionState.ReturnRequested
+                        }
+
+                    val controller =
+                        expandable
+                            .mapNotNull {
+                                it?.activityTransitionController(
+                                    launchCujType,
+                                    cookie,
+                                    component,
+                                    returnCujType,
+                                    isEphemeral = false,
+                                )
+                            }
+                            .first()
+
+                    return object : DelegateTransitionAnimatorController(controller) {
+                        override val isLaunching: Boolean
+                            get() = forLaunch
+
+                        override fun onTransitionAnimationStart(isExpandingFullyAbove: Boolean) {
+                            delegate.onTransitionAnimationStart(isExpandingFullyAbove)
+                            transitionState.value =
+                                if (isLaunching) {
+                                    TransitionState.Launching
+                                } else {
+                                    TransitionState.Returning
+                                }
+                        }
+
+                        override fun onTransitionAnimationEnd(isExpandingFullyAbove: Boolean) {
+                            delegate.onTransitionAnimationEnd(isExpandingFullyAbove)
+                            transitionState.value = TransitionState.NoTransition
+                        }
+
+                        override fun onTransitionAnimationCancelled(
+                            newKeyguardOccludedState: Boolean?
+                        ) {
+                            delegate.onTransitionAnimationCancelled(newKeyguardOccludedState)
+                            transitionState.value = TransitionState.NoTransition
+                        }
+                    }
+                }
+            }
+
+        transitionControllerFactory = factory
+        return factory
+    }
+
+    /** Define the current state of this chip's transition animation. */
+    private sealed interface TransitionState {
+        /** Idle. */
+        data object NoTransition : TransitionState
+
+        /** Launch animation has been requested but hasn't started yet. */
+        data object LaunchRequested : TransitionState
+
+        /** Launch animation in progress. */
+        data object Launching : TransitionState
+
+        /** Return animation has been requested but hasn't started yet. */
+        data object ReturnRequested : TransitionState
+
+        /** Return animation in progress. */
+        data object Returning : TransitionState
+    }
+
     companion object {
         private val phoneIcon =
             Icon.Resource(
@@ -217,5 +412,42 @@
                 ContentDescription.Resource(R.string.ongoing_call_content_description),
             )
         private val TAG = "CallVM".pad()
+
+        /** Determines whether or not an active call chip should be hidden. */
+        private fun shouldChipBeHidden(
+            oldState: OngoingCallModel,
+            newState: OngoingCallModel.InCall,
+            oldTransitionState: TransitionState,
+            newTransitionState: TransitionState,
+        ): Boolean {
+            // The app is in the background and no transitions are ongoing (during transitions,
+            // [isAppVisible] must always be true). Show the chip.
+            if (!newState.isAppVisible) return false
+
+            // The call has just started and is visible. Hide the chip.
+            if (oldState is OngoingCallModel.NoCall) return true
+
+            // The state went from the app not being visible to visible. This happens when the chip
+            // is tapped and a launch animation is about to start. Keep the chip showing.
+            if (!(oldState as OngoingCallModel.InCall).isAppVisible) return false
+
+            // The app was and remains visible, but the transition state has changed. A launch or
+            // return animation has been requested or is ongoing. Keep the chip showing.
+            if (
+                newTransitionState is TransitionState.LaunchRequested ||
+                    newTransitionState is TransitionState.Launching ||
+                    newTransitionState is TransitionState.ReturnRequested ||
+                    newTransitionState is TransitionState.Returning
+            ) {
+                return false
+            }
+
+            // The app was and remains visible, so we generally want to hide the chip. The only
+            // exception is if a return transition has just ended. In this case, the transition
+            // state changes shortly before the app visibility does. If we hide the chip between
+            // these two updates, this results in a flicker. We bridge the gap by keeping the chip
+            // showing.
+            return oldTransitionState != TransitionState.Returning
+        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
index 4edb23d..b94e7b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChip.kt
@@ -25,23 +25,28 @@
 import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
+import androidx.compose.foundation.layout.widthIn
 import androidx.compose.foundation.shape.RoundedCornerShape
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
 import androidx.compose.ui.layout.layout
 import androidx.compose.ui.platform.LocalContext
 import androidx.compose.ui.res.dimensionResource
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.semantics
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.viewinterop.AndroidView
 import com.android.compose.animation.Expandable
+import com.android.compose.modifiers.thenIf
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.ui.compose.Icon
 import com.android.systemui.common.ui.compose.load
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.StatusBarIconView
+import com.android.systemui.statusbar.chips.StatusBarChipsReturnAnimations
 import com.android.systemui.statusbar.chips.ui.model.ColorsModel
 import com.android.systemui.statusbar.chips.ui.model.OngoingActivityChipModel
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
@@ -77,34 +82,7 @@
                 }
             is OngoingActivityChipModel.ClickBehavior.None -> null
         }
-
-    Expandable(
-        color = Color(model.colors.background(LocalContext.current).defaultColor),
-        shape =
-            RoundedCornerShape(dimensionResource(id = R.dimen.ongoing_activity_chip_corner_radius)),
-        modifier =
-            modifier.height(dimensionResource(R.dimen.ongoing_appops_chip_height)).semantics {
-                if (contentDescription != null) {
-                    this.contentDescription = contentDescription
-                }
-            },
-        borderStroke = borderStroke,
-        onClick = onClick,
-    ) {
-        ChipBody(model, iconViewStore, isClickable = onClick != null)
-    }
-}
-
-@Composable
-private fun ChipBody(
-    model: OngoingActivityChipModel.Active,
-    iconViewStore: NotificationIconContainerViewBinder.IconViewStore?,
-    isClickable: Boolean,
-    modifier: Modifier = Modifier,
-) {
-    val hasEmbeddedIcon =
-        model.icon is OngoingActivityChipModel.ChipIcon.StatusBarView ||
-            model.icon is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon
+    val isClickable = onClick != null
 
     val chipSidePadding = dimensionResource(id = R.dimen.ongoing_activity_chip_side_padding)
     val minWidth =
@@ -116,12 +94,19 @@
             dimensionResource(id = R.dimen.ongoing_activity_chip_min_text_width) + chipSidePadding
         }
 
-    Row(
-        horizontalArrangement = Arrangement.Center,
-        verticalAlignment = Alignment.CenterVertically,
+    Expandable(
+        color = Color(model.colors.background(LocalContext.current).defaultColor),
+        shape =
+            RoundedCornerShape(dimensionResource(id = R.dimen.ongoing_activity_chip_corner_radius)),
         modifier =
             modifier
-                .fillMaxHeight()
+                .height(dimensionResource(R.dimen.ongoing_appops_chip_height))
+                .semantics {
+                    if (contentDescription != null) {
+                        this.contentDescription = contentDescription
+                    }
+                }
+                .thenIf(isClickable) { Modifier.widthIn(min = minWidth) }
                 .layout { measurable, constraints ->
                     val placeable = measurable.measure(constraints)
                     layout(placeable.width, placeable.height) {
@@ -130,6 +115,47 @@
                         }
                     }
                 }
+                .graphicsLayer(
+                    alpha =
+                        if (model.transitionManager?.hideChipForTransition == true) {
+                            0f
+                        } else {
+                            1f
+                        }
+                ),
+        borderStroke = borderStroke,
+        onClick = onClick,
+        useModifierBasedImplementation = StatusBarChipsReturnAnimations.isEnabled,
+        // Some chips like the 3-2-1 countdown chip should be very small, smaller than a
+        // reasonable minimum size.
+        defaultMinSize = false,
+        transitionControllerFactory = model.transitionManager?.controllerFactory,
+    ) {
+        ChipBody(model, iconViewStore, isClickable = isClickable, minWidth = minWidth)
+    }
+}
+
+@Composable
+private fun ChipBody(
+    model: OngoingActivityChipModel.Active,
+    iconViewStore: NotificationIconContainerViewBinder.IconViewStore?,
+    isClickable: Boolean,
+    minWidth: Dp,
+    modifier: Modifier = Modifier,
+) {
+    val hasEmbeddedIcon =
+        model.icon is OngoingActivityChipModel.ChipIcon.StatusBarView ||
+            model.icon is OngoingActivityChipModel.ChipIcon.StatusBarNotificationIcon
+
+    Row(
+        horizontalArrangement = Arrangement.Center,
+        verticalAlignment = Alignment.CenterVertically,
+        modifier =
+            modifier
+                .fillMaxHeight()
+                // Set the minWidth here as well as on the Expandable so that the content within
+                // this row is still centered correctly horizontally
+                .thenIf(isClickable) { Modifier.widthIn(min = minWidth) }
                 .padding(
                     horizontal =
                         if (hasEmbeddedIcon) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
index 407849b..700e6d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/compose/OngoingActivityChips.kt
@@ -21,12 +21,14 @@
 import androidx.compose.foundation.layout.fillMaxHeight
 import androidx.compose.foundation.layout.padding
 import androidx.compose.runtime.Composable
+import androidx.compose.runtime.SideEffect
 import androidx.compose.runtime.key
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.res.dimensionResource
 import com.android.systemui.compose.modifiers.sysuiResTag
 import com.android.systemui.res.R
+import com.android.systemui.statusbar.chips.StatusBarChipsReturnAnimations
 import com.android.systemui.statusbar.chips.ui.model.MultipleOngoingActivityChipsModel
 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder
 
@@ -36,6 +38,18 @@
     iconViewStore: NotificationIconContainerViewBinder.IconViewStore?,
     modifier: Modifier = Modifier,
 ) {
+    if (StatusBarChipsReturnAnimations.isEnabled) {
+        SideEffect {
+            // Active chips must always be capable of animating to/from activities, even when they
+            // are hidden. Therefore we always register their transitions.
+            for (chip in chips.active) chip.transitionManager?.registerTransition?.invoke()
+            // Inactive chips and chips in the overflow are never shown, so they must not have any
+            // registered transition.
+            for (chip in chips.overflow) chip.transitionManager?.unregisterTransition?.invoke()
+            for (chip in chips.inactive) chip.transitionManager?.unregisterTransition?.invoke()
+        }
+    }
+
     val shownChips = chips.active.filter { !it.isHidden }
     if (shownChips.isNotEmpty()) {
         Row(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
index d37a46e..364e665 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/chips/ui/model/OngoingActivityChipModel.kt
@@ -20,6 +20,7 @@
 import android.annotation.ElapsedRealtimeLong
 import android.os.SystemClock
 import android.view.View
+import com.android.systemui.animation.ComposableControllerFactory
 import com.android.systemui.animation.Expandable
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
@@ -33,6 +34,9 @@
     /** Condensed name representing the model, used for logs. */
     abstract val logName: String
 
+    /** Object used to manage the behavior of this chip during activity launch and returns. */
+    abstract val transitionManager: TransitionManager?
+
     /**
      * This chip shouldn't be shown.
      *
@@ -40,7 +44,10 @@
      *   animated, and false if that transition should *not* be animated (i.e. the chip view should
      *   immediately disappear).
      */
-    data class Inactive(val shouldAnimate: Boolean = true) : OngoingActivityChipModel() {
+    data class Inactive(
+        val shouldAnimate: Boolean = true,
+        override val transitionManager: TransitionManager? = null,
+    ) : OngoingActivityChipModel() {
         override val logName = "Inactive(anim=$shouldAnimate)"
     }
 
@@ -61,6 +68,7 @@
         open val onClickListenerLegacy: View.OnClickListener?,
         /** Data class that determines how clicks on the chip should be handled. */
         open val clickBehavior: ClickBehavior,
+        override val transitionManager: TransitionManager?,
         /**
          * Whether this chip should be hidden. This can be the case depending on system states (like
          * which apps are in the foreground and whether there is an ongoing transition.
@@ -77,6 +85,7 @@
             override val colors: ColorsModel,
             override val onClickListenerLegacy: View.OnClickListener?,
             override val clickBehavior: ClickBehavior,
+            override val transitionManager: TransitionManager? = null,
             override val isHidden: Boolean = false,
             override val shouldAnimate: Boolean = true,
         ) :
@@ -86,6 +95,7 @@
                 colors,
                 onClickListenerLegacy,
                 clickBehavior,
+                transitionManager,
                 isHidden,
                 shouldAnimate,
             ) {
@@ -122,6 +132,7 @@
             val isEventInFuture: Boolean = false,
             override val onClickListenerLegacy: View.OnClickListener?,
             override val clickBehavior: ClickBehavior,
+            override val transitionManager: TransitionManager? = null,
             override val isHidden: Boolean = false,
             override val shouldAnimate: Boolean = true,
         ) :
@@ -131,6 +142,7 @@
                 colors,
                 onClickListenerLegacy,
                 clickBehavior,
+                transitionManager,
                 isHidden,
                 shouldAnimate,
             ) {
@@ -157,6 +169,7 @@
             @CurrentTimeMillisLong val time: Long,
             override val onClickListenerLegacy: View.OnClickListener?,
             override val clickBehavior: ClickBehavior,
+            override val transitionManager: TransitionManager? = null,
             override val isHidden: Boolean = false,
             override val shouldAnimate: Boolean = true,
         ) :
@@ -166,6 +179,7 @@
                 colors,
                 onClickListenerLegacy,
                 clickBehavior,
+                transitionManager,
                 isHidden,
                 shouldAnimate,
             ) {
@@ -185,6 +199,7 @@
             override val colors: ColorsModel,
             /** The number of seconds until an event is started. */
             val secondsUntilStarted: Long,
+            override val transitionManager: TransitionManager? = null,
             override val isHidden: Boolean = false,
             override val shouldAnimate: Boolean = true,
         ) :
@@ -194,6 +209,7 @@
                 colors,
                 onClickListenerLegacy = null,
                 clickBehavior = ClickBehavior.None,
+                transitionManager,
                 isHidden,
                 shouldAnimate,
             ) {
@@ -209,6 +225,7 @@
             val text: String,
             override val onClickListenerLegacy: View.OnClickListener? = null,
             override val clickBehavior: ClickBehavior,
+            override val transitionManager: TransitionManager? = null,
             override val isHidden: Boolean = false,
             override val shouldAnimate: Boolean = true,
         ) :
@@ -218,6 +235,7 @@
                 colors,
                 onClickListenerLegacy,
                 clickBehavior,
+                transitionManager,
                 isHidden,
                 shouldAnimate,
             ) {
@@ -271,4 +289,23 @@
         /** Clicking the chip will show the heads up notification associated with the chip. */
         data class ShowHeadsUpNotification(val onClick: () -> Unit) : ClickBehavior
     }
+
+    /** Defines the behavior of the chip with respect to activity launch and return transitions. */
+    data class TransitionManager(
+        /** The factory used to create the controllers that animate the chip. */
+        val controllerFactory: ComposableControllerFactory? = null,
+        /**
+         * Used to create a registration for this chip using [controllerFactory]. Must be
+         * idempotent.
+         */
+        val registerTransition: () -> Unit = {},
+        /** Used to remove the existing registration for this chip, if any. */
+        val unregisterTransition: () -> Unit = {},
+        /**
+         * Whether the chip should be made invisible (0 opacity) while still being composed. This is
+         * necessary to avoid flickers at the beginning of return transitions, when the chip must
+         * not be visible but must be composed in order for the animation to start.
+         */
+        val hideChipForTransition: Boolean = false,
+    )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
index 48f0245..4cf456d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityModule.kt
@@ -32,25 +32,25 @@
 import com.android.systemui.qs.tiles.InternetTile
 import com.android.systemui.qs.tiles.InternetTileNewImpl
 import com.android.systemui.qs.tiles.NfcTile
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
 import com.android.systemui.qs.tiles.dialog.InternetDetailsViewModel
-import com.android.systemui.qs.tiles.impl.airplane.domain.AirplaneModeMapper
 import com.android.systemui.qs.tiles.impl.airplane.domain.interactor.AirplaneModeTileDataInteractor
 import com.android.systemui.qs.tiles.impl.airplane.domain.interactor.AirplaneModeTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.airplane.domain.model.AirplaneModeTileModel
-import com.android.systemui.qs.tiles.impl.internet.domain.InternetTileMapper
+import com.android.systemui.qs.tiles.impl.airplane.ui.mapper.AirplaneModeTileMapper
 import com.android.systemui.qs.tiles.impl.internet.domain.interactor.InternetTileDataInteractor
 import com.android.systemui.qs.tiles.impl.internet.domain.interactor.InternetTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.internet.domain.model.InternetTileModel
-import com.android.systemui.qs.tiles.impl.saver.domain.DataSaverTileMapper
+import com.android.systemui.qs.tiles.impl.internet.ui.mapper.InternetTileMapper
 import com.android.systemui.qs.tiles.impl.saver.domain.interactor.DataSaverTileDataInteractor
 import com.android.systemui.qs.tiles.impl.saver.domain.interactor.DataSaverTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.saver.domain.model.DataSaverTileModel
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.impl.saver.ui.mapper.DataSaverTileMapper
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
@@ -161,10 +161,10 @@
         @StringKey(AIRPLANE_MODE_TILE_SPEC)
         fun provideAirplaneModeTileViewModel(
             factory: QSTileViewModelFactory.Static<AirplaneModeTileModel>,
-            mapper: AirplaneModeMapper,
+            mapper: AirplaneModeTileMapper,
             stateInteractor: AirplaneModeTileDataInteractor,
             userActionInteractor: AirplaneModeTileUserActionInteractor,
-            internetDetailsViewModelFactory: InternetDetailsViewModel.Factory
+            internetDetailsViewModelFactory: InternetDetailsViewModel.Factory,
         ): QSTileViewModel =
             factory.create(
                 TileSpec.create(AIRPLANE_MODE_TILE_SPEC),
@@ -197,7 +197,7 @@
             factory: QSTileViewModelFactory.Static<DataSaverTileModel>,
             mapper: DataSaverTileMapper,
             stateInteractor: DataSaverTileDataInteractor,
-            userActionInteractor: DataSaverTileUserActionInteractor
+            userActionInteractor: DataSaverTileUserActionInteractor,
         ): QSTileViewModel =
             factory.create(
                 TileSpec.create(DATA_SAVER_TILE_SPEC),
@@ -230,7 +230,7 @@
             mapper: InternetTileMapper,
             stateInteractor: InternetTileDataInteractor,
             userActionInteractor: InternetTileUserActionInteractor,
-            internetDetailsViewModelFactory: InternetDetailsViewModel.Factory
+            internetDetailsViewModelFactory: InternetDetailsViewModel.Factory,
         ): QSTileViewModel =
             factory.create(
                 TileSpec.create(INTERNET_TILE_SPEC),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
index 7964950..499e3ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/core/MultiDisplayStatusBarOrchestratorStore.kt
@@ -16,10 +16,10 @@
 
 package com.android.systemui.statusbar.core
 
+import com.android.app.displaylib.PerDisplayRepository
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.repository.DisplayRepository
-import com.android.systemui.display.data.repository.DisplayScopeRepository
 import com.android.systemui.statusbar.data.repository.StatusBarModeRepositoryStore
 import com.android.systemui.statusbar.data.repository.StatusBarPerDisplayStoreImpl
 import com.android.systemui.statusbar.phone.AutoHideControllerStore
@@ -40,7 +40,7 @@
     private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
     private val initializerStore: StatusBarInitializerStore,
     private val autoHideControllerStore: AutoHideControllerStore,
-    private val displayScopeRepository: DisplayScopeRepository,
+    private val displayScopeRepository: PerDisplayRepository<CoroutineScope>,
     private val statusBarWindowStateRepositoryStore: StatusBarWindowStateRepositoryStore,
 ) :
     StatusBarPerDisplayStoreImpl<StatusBarOrchestrator>(
@@ -59,10 +59,10 @@
         val statusBarWindowController =
             statusBarWindowControllerStore.forDisplay(displayId) ?: return null
         val autoHideController = autoHideControllerStore.forDisplay(displayId) ?: return null
+        val displayScope = displayScopeRepository[displayId] ?: return null
         return factory.create(
             displayId,
-            // TODO: b/398825844 - Handle nullness to prevent leaking CoroutineScope.
-            displayScopeRepository.scopeForDisplay(displayId),
+            displayScope,
             statusBarWindowStateRepositoryStore.forDisplay(displayId),
             statusBarModeRepository,
             statusBarInitializer,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
index 3c0d6c3..b257c2b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/LightBarControllerStore.kt
@@ -16,11 +16,11 @@
 
 package com.android.systemui.statusbar.data.repository
 
+import com.android.app.displaylib.PerDisplayRepository
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.repository.DisplayRepository
-import com.android.systemui.display.data.repository.DisplayScopeRepository
 import com.android.systemui.display.data.repository.PerDisplayStore
 import com.android.systemui.statusbar.phone.LightBarController
 import com.android.systemui.statusbar.phone.LightBarControllerImpl
@@ -41,7 +41,7 @@
     @Background backgroundApplicationScope: CoroutineScope,
     displayRepository: DisplayRepository,
     private val factory: LightBarControllerImpl.Factory,
-    private val displayScopeRepository: DisplayScopeRepository,
+    private val displayScopeRepository: PerDisplayRepository<CoroutineScope>,
     private val statusBarModeRepositoryStore: StatusBarModeRepositoryStore,
     private val darkIconDispatcherStore: DarkIconDispatcherStore,
 ) :
@@ -55,13 +55,9 @@
         val darkIconDispatcher = darkIconDispatcherStore.forDisplay(displayId) ?: return null
         val statusBarModePerDisplayRepository =
             statusBarModeRepositoryStore.forDisplay(displayId) ?: return null
+        val displayScope = displayScopeRepository[displayId] ?: return null
         return factory
-            .create(
-                displayId,
-                displayScopeRepository.scopeForDisplay(displayId),
-                darkIconDispatcher,
-                statusBarModePerDisplayRepository,
-            )
+            .create(displayId, displayScope, darkIconDispatcher, statusBarModePerDisplayRepository)
             .also { it.start() }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
index 32dc840..f3c6855 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/PrivacyDotViewControllerStore.kt
@@ -16,11 +16,11 @@
 
 package com.android.systemui.statusbar.data.repository
 
+import com.android.app.displaylib.PerDisplayRepository
 import com.android.systemui.CoreStartable
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.display.data.repository.DisplayRepository
-import com.android.systemui.display.data.repository.DisplayScopeRepository
 import com.android.systemui.display.data.repository.PerDisplayStore
 import com.android.systemui.display.data.repository.SingleDisplayStore
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
@@ -44,7 +44,7 @@
     @Background backgroundApplicationScope: CoroutineScope,
     displayRepository: DisplayRepository,
     private val factory: PrivacyDotViewControllerImpl.Factory,
-    private val displayScopeRepository: DisplayScopeRepository,
+    private val displayScopeRepository: PerDisplayRepository<CoroutineScope>,
     private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
     private val contentInsetsProviderStore: StatusBarContentInsetsProviderStore,
 ) :
@@ -58,11 +58,8 @@
         val configurationController =
             statusBarConfigurationControllerStore.forDisplay(displayId) ?: return null
         val contentInsetsProvider = contentInsetsProviderStore.forDisplay(displayId) ?: return null
-        return factory.create(
-            displayScopeRepository.scopeForDisplay(displayId),
-            configurationController,
-            contentInsetsProvider,
-        )
+        val displayScope = displayScopeRepository[displayId] ?: return null
+        return factory.create(displayScope, configurationController, contentInsetsProvider)
     }
 
     override suspend fun onDisplayRemovalAction(instance: PrivacyDotViewController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt
index 3168a22..cb1002a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/data/repository/StatusBarPerDisplayConfigurationStateRepository.kt
@@ -17,14 +17,14 @@
 package com.android.systemui.statusbar.data.repository
 
 import android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR
+import com.android.app.displaylib.PerDisplayInstanceProvider
+import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
+import com.android.app.displaylib.PerDisplayRepository
+import com.android.app.displaylib.SingleInstanceRepositoryImpl
 import com.android.systemui.common.ui.ConfigurationState
 import com.android.systemui.common.ui.ConfigurationStateImpl
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.display.data.repository.DisplayWindowPropertiesRepository
-import com.android.systemui.display.data.repository.PerDisplayInstanceProvider
-import com.android.systemui.display.data.repository.PerDisplayInstanceRepositoryImpl
-import com.android.systemui.display.data.repository.PerDisplayRepository
-import com.android.systemui.display.data.repository.SingleInstanceRepositoryImpl
 import com.android.systemui.statusbar.core.StatusBarConnectedDisplays
 import dagger.Lazy
 import dagger.Module
@@ -39,7 +39,6 @@
     private val statusBarConfigurationControllerStore: StatusBarConfigurationControllerStore,
     private val factory: ConfigurationStateImpl.Factory,
 ) : PerDisplayInstanceProvider<ConfigurationState> {
-
     override fun createInstance(displayId: Int): ConfigurationState? {
         val displayWindowProperties =
             displayWindowPropertiesRepository.get(displayId, TYPE_STATUS_BAR) ?: return null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
index 8be9e41..fed9417 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClicker.java
@@ -23,6 +23,7 @@
 
 import com.android.systemui.DejankUtils;
 import com.android.systemui.power.domain.interactor.PowerInteractor;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
@@ -44,13 +45,20 @@
     private final Optional<Bubbles> mBubblesOptional;
     private final NotificationActivityStarter mNotificationActivityStarter;
 
-    private ExpandableNotificationRow.OnDragSuccessListener mOnDragSuccessListener =
-            new ExpandableNotificationRow.OnDragSuccessListener() {
-                @Override
-                public void onDragSuccess(NotificationEntry entry) {
-                    mNotificationActivityStarter.onDragSuccess(entry);
-                }
-            };
+    private ExpandableNotificationRow.OnDragSuccessListener mOnDragSuccessListener
+            = new ExpandableNotificationRow.OnDragSuccessListener() {
+        @Override
+        public void onDragSuccess(NotificationEntry entry) {
+            NotificationBundleUi.assertInLegacyMode();
+            mNotificationActivityStarter.onDragSuccess(entry);
+        }
+
+        @Override
+        public void onDragSuccess(EntryAdapter entryAdapter) {
+            NotificationBundleUi.isUnexpectedlyInLegacyMode();
+            entryAdapter.onDragSuccess();
+        }
+    };
 
     private NotificationClicker(
             NotificationClickerLogger logger,
@@ -73,7 +81,6 @@
         mPowerInteractor.wakeUpIfDozing("NOTIFICATION_CLICK", PowerManager.WAKE_REASON_GESTURE);
 
         final ExpandableNotificationRow row = (ExpandableNotificationRow) v;
-        final NotificationEntry entry = row.getEntry();
         mLogger.logOnClick(row.getLoggingKey());
 
         // Check if the notification is displaying the menu, if so slide notification back
@@ -101,16 +108,16 @@
         DejankUtils.postAfterTraversal(() -> row.setJustClicked(false));
 
         if (NotificationBundleUi.isEnabled()) {
-            if (!row.getEntryAdapter().isBubbleCapable() && mBubblesOptional.isPresent()) {
+            if (!row.getEntryAdapter().isBubble() && mBubblesOptional.isPresent()) {
                 mBubblesOptional.get().collapseStack();
             }
+            row.getEntryAdapter().onEntryClicked(row);
         } else {
-            if (!row.getEntry().isBubble() && mBubblesOptional.isPresent()) {
+            if (!row.getEntryLegacy().isBubble() && mBubblesOptional.isPresent()) {
                 mBubblesOptional.get().collapseStack();
             }
+            mNotificationActivityStarter.onNotificationClicked(row.getEntryLegacy(), row);
         }
-
-        mNotificationActivityStarter.onNotificationClicked(entry, row);
     }
 
     private boolean isMenuVisible(ExpandableNotificationRow row) {
@@ -121,16 +128,19 @@
      * Attaches the click listener to the row if appropriate.
      */
     public void register(ExpandableNotificationRow row, StatusBarNotification sbn) {
+        boolean isBubble = NotificationBundleUi.isEnabled()
+                ? row.getEntryAdapter().isBubble()
+                : row.getEntryLegacy().isBubble();
         Notification notification = sbn.getNotification();
         if (notification.contentIntent != null || notification.fullScreenIntent != null
-                || row.getEntry().isBubble()) {
+                || isBubble) {
             if (NotificationBundleUi.isEnabled()) {
                 row.setBubbleClickListener(
                         v -> row.getEntryAdapter().onNotificationBubbleIconClicked());
             } else {
                 row.setBubbleClickListener(v ->
                         mNotificationActivityStarter.onNotificationBubbleIconClicked(
-                                row.getEntry()));
+                                row.getEntryLegacy()));
             }
             row.setOnClickListener(this);
             row.setOnDragSuccessListener(mOnDragSuccessListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
index 874a059..8163128 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationTransitionAnimatorController.kt
@@ -74,7 +74,6 @@
         const val ANIMATION_DURATION_TOP_ROUNDING = 100L
     }
 
-    private val notificationEntry = notification.entry
     private val notificationKey = notification.key
 
     override val isLaunching: Boolean = true
@@ -160,7 +159,7 @@
     private val headsUpNotificationRow: ExpandableNotificationRow?
         get() {
             val pipelineParent = if (NotificationBundleUi.isEnabled)
-                notification.entryAdapter?.parent else notificationEntry.parent
+                notification.entryAdapter?.parent else notification.entryLegacy.parent
             val summaryEntry = (pipelineParent as? GroupEntry)?.summary
             return when {
                 headsUpManager.isHeadsUpEntry(notificationKey) -> notification
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
index d06f24f..ba40010 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/OWNERS
@@ -17,3 +17,4 @@
 yurilin@google.com
 
 per-file MediaNotificationProcessor.java = ethibodeau@google.com
+per-file MagicActionBackgroundDrawable.kt = dupin@google.com
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
index f653573..8fc6cbe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntry.java
@@ -69,10 +69,13 @@
         return mUnmodifiableChildren;
     }
 
+    void clearChildren() {
+        mChildren.clear();
+    }
+
     /**
      * @return Null because bundles do not have an associated NotificationEntry.
      */
-
     @Nullable
     @Override
     public NotificationEntry getRepresentativeEntry() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt
index 26c302b..be17ae56c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/BundleEntryAdapter.kt
@@ -22,6 +22,7 @@
 import android.service.notification.StatusBarNotification
 import android.util.Log
 import com.android.systemui.statusbar.notification.icon.IconPack
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
 import kotlinx.coroutines.flow.StateFlow
 
@@ -97,7 +98,7 @@
         return false
     }
 
-    override fun isBubbleCapable(): Boolean {
+    override fun isBubble(): Boolean {
         return false
     }
 
@@ -113,10 +114,23 @@
         return false
     }
 
+    override fun getPeopleNotificationType(): Int {
+        return TYPE_NON_PERSON
+    }
+
+    override fun isPromotedOngoing(): Boolean {
+        return false
+    }
+
     override fun isFullScreenCapable(): Boolean {
         return false
     }
 
+    override fun onDragSuccess() {
+        // do nothing. these should not be draggable
+        Log.wtf(TAG, "onDragSuccess() called")
+    }
+
     override fun onNotificationBubbleIconClicked() {
         // do nothing. these cannot be a bubble
         Log.wtf(TAG, "onNotificationBubbleIconClicked() called")
@@ -126,6 +140,16 @@
         // do nothing. these have no actions
         Log.wtf(TAG, "onNotificationActionClicked() called")
     }
+
+    override fun getDismissState(): NotificationEntry.DismissState {
+        // TODO(b/394483200): setDismissState is only called in NotifCollection so it does not
+        // work on bundles yet
+        return NotificationEntry.DismissState.NOT_DISMISSED
+    }
+
+    override fun onEntryClicked(row: ExpandableNotificationRow) {
+        // TODO(b/396446620): should anything happen when you click on a bundle?
+    }
 }
 
 private const val TAG = "BundleEntryAdapter"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
index 3118ce5..3757ebf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/EntryAdapter.java
@@ -23,6 +23,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.systemui.statusbar.notification.icon.IconPack;
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
 
 import kotlinx.coroutines.flow.StateFlow;
@@ -124,7 +125,7 @@
 
     boolean canDragAndDrop();
 
-    boolean isBubbleCapable();
+    boolean isBubble();
 
     @Nullable String getStyle();
 
@@ -132,10 +133,19 @@
 
     boolean isAmbient();
 
+    @PeopleNotificationIdentifier.Companion.PeopleNotificationType int getPeopleNotificationType();
+
+    /**
+     * Returns whether this row represents promoted ongoing notification.
+     */
+    boolean isPromotedOngoing();
+
     default boolean isFullScreenCapable() {
         return false;
     }
 
+    void onDragSuccess();
+
     /**
      * Process a click on a notification bubble icon
      */
@@ -145,5 +155,9 @@
      * Processes a click on a notification action
      */
     void onNotificationActionClicked();
+
+    NotificationEntry.DismissState getDismissState();
+
+    void onEntryClicked(ExpandableNotificationRow row);
 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java
index caa7abb..8f7f61f6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListEntry.java
@@ -34,7 +34,7 @@
     }
 
     /**
-     * The SystemClock.uptimeMillis() when this object was created. In general, this means the
+     * The SystemClock.elapsedRealtime() when this object was created. In general, this means the
      * moment when NotificationManager notifies our listener about the existence of this entry.
      *
      * This value will not change if the notification is updated, although it will change if the
@@ -65,13 +65,4 @@
     @Nullable public PipelineEntry getPreviousParent() {
         return mPreviousAttachState.getParent();
     }
-
-    /**
-     * Stores the current attach state into {@link #getPreviousAttachState()}} and then starts a
-     * fresh attach state (all entries will be null/default-initialized).
-     */
-    void beginNewAttachState() {
-        mPreviousAttachState.clone(mAttachState);
-        mAttachState.reset();
-    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
index 9795edf..b7fe39e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollection.java
@@ -522,7 +522,7 @@
     }
 
     private void onNotificationsInitialized() {
-        mInitializedTimestamp = mClock.uptimeMillis();
+        mInitializedTimestamp = UseElapsedRealtimeForCreationTime.getCurrentTime(mClock);
     }
 
     private void postNotification(
@@ -532,7 +532,8 @@
 
         if (entry == null) {
             // A new notification!
-            entry = new NotificationEntry(sbn, ranking, mClock.uptimeMillis());
+            entry = new NotificationEntry(sbn, ranking,
+                    UseElapsedRealtimeForCreationTime.getCurrentTime(mClock));
             mEventQueue.add(new InitEntryEvent(entry));
             mEventQueue.add(new BindEntryEvent(entry, sbn));
             mNotificationSet.put(sbn.getKey(), entry);
@@ -861,7 +862,7 @@
     // messages from system server.
     private void crashIfNotInitializing(RuntimeException exception) {
         final boolean isRecentlyInitialized = mInitializedTimestamp == 0
-                || mClock.uptimeMillis() - mInitializedTimestamp
+                || UseElapsedRealtimeForCreationTime.getCurrentTime(mClock) - mInitializedTimestamp
                         < INITIALIZATION_FORGIVENESS_WINDOW;
 
         if (isRecentlyInitialized) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollectionCache.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollectionCache.kt
index 1f8d365..698fed3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollectionCache.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifCollectionCache.kt
@@ -89,9 +89,9 @@
                 return true
             }
 
-            // Using uptimeMillis since it's guaranteed to be monotonic, as we don't want a
+            // Using elapsedRealtime since it's guaranteed to be monotonic, as we don't want a
             // timezone/clock change to break us
-            val now = systemClock.uptimeMillis()
+            val now = UseElapsedRealtimeForCreationTime.getCurrentTime(systemClock)
 
             // Cannot purge the same entry from two threads simultaneously
             synchronized(key) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index d031d83..4558017 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -251,7 +251,7 @@
     /**
      * @param sbn the StatusBarNotification from system server
      * @param ranking also from system server
-     * @param creationTime SystemClock.uptimeMillis of when we were created
+     * @param creationTime SystemClock.elapsedRealtime of when we were created
      */
     public NotificationEntry(
             @NonNull StatusBarNotification sbn,
@@ -508,7 +508,7 @@
 
             ArrayList<NotificationEntry> children = new ArrayList<>();
             for (ExpandableNotificationRow child : rowChildren) {
-                children.add(child.getEntry());
+                children.add(child.getEntryLegacy());
             }
 
             return children;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt
index 1168c64..a23c5a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntryAdapter.kt
@@ -121,7 +121,7 @@
         return false
     }
 
-    override fun isBubbleCapable(): Boolean {
+    override fun isBubble(): Boolean {
         return entry.isBubble
     }
 
@@ -137,10 +137,22 @@
         return entry.ranking.isAmbient
     }
 
+    override fun getPeopleNotificationType(): Int {
+        return peopleNotificationIdentifier.getPeopleNotificationType(entry)
+    }
+
+    override fun isPromotedOngoing(): Boolean {
+        return entry.isPromotedOngoing
+    }
+
     override fun isFullScreenCapable(): Boolean {
         return entry.sbn.notification.fullScreenIntent != null
     }
 
+    override fun onDragSuccess() {
+        notificationActivityStarter.onDragSuccess(entry)
+    }
+
     override fun onNotificationBubbleIconClicked() {
         notificationActivityStarter.onNotificationBubbleIconClicked(entry)
     }
@@ -148,4 +160,12 @@
     override fun onNotificationActionClicked() {
         notificationActionClickManager.onNotificationActionClicked(entry)
     }
+
+    override fun getDismissState(): NotificationEntry.DismissState {
+        return entry.dismissState
+    }
+
+    override fun onEntryClicked(row: ExpandableNotificationRow) {
+        notificationActivityStarter.onNotificationClicked(entry, row)
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java
index 872cd68..e9c4efc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineEntry.java
@@ -101,4 +101,13 @@
     public void setBucket(@PriorityBucket int bucket) {
         mBucket = bucket;
     }
+
+    /**
+     * Stores the current attach state into {@link #getPreviousAttachState()}} and then starts a
+     * fresh attach state (all entries will be null/default-initialized).
+     */
+    void beginNewAttachState() {
+        mPreviousAttachState.clone(mAttachState);
+        mAttachState.reset();
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
index 238ba8d..fe2bd34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ShadeListBuilder.java
@@ -289,6 +289,9 @@
 
         mIdToBundleEntry.clear();
         for (String id: mNotifBundler.getBundleIds()) {
+            if (BundleCoordinator.debugBundleUi) {
+                Log.i(TAG, "create BundleEntry with id: " + id);
+            }
             mIdToBundleEntry.put(id, new BundleEntry(id));
         }
     }
@@ -562,6 +565,11 @@
             entry.beginNewAttachState();
         }
 
+        for (BundleEntry be : mIdToBundleEntry.values()) {
+            be.beginNewAttachState();
+            be.clearChildren();
+            // BundleEntry has not representative summary so we do not need to clear it here.
+        }
         mNotifList.clear();
     }
 
@@ -570,7 +578,7 @@
             List<PipelineEntry> out,
             List<NotifFilter> filters) {
         Trace.beginSection("ShadeListBuilder.filterNotifs");
-        final long now = mSystemClock.uptimeMillis();
+        final long now = UseElapsedRealtimeForCreationTime.getCurrentTime(mSystemClock);
         for (PipelineEntry entry : entries) {
             if (entry instanceof GroupEntry) {
                 final GroupEntry groupEntry = (GroupEntry) entry;
@@ -614,7 +622,8 @@
 
                 GroupEntry group = mGroups.get(topLevelKey);
                 if (group == null) {
-                    group = new GroupEntry(topLevelKey, mSystemClock.uptimeMillis());
+                    group = new GroupEntry(topLevelKey,
+                            UseElapsedRealtimeForCreationTime.getCurrentTime(mSystemClock));
                     mGroups.put(topLevelKey, group);
                 }
                 if (group.getParent() == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/UseElapsedRealtimeForCreationTime.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/UseElapsedRealtimeForCreationTime.kt
new file mode 100644
index 0000000..23f90f3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/UseElapsedRealtimeForCreationTime.kt
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+import android.app.Flags
+import com.android.systemui.util.time.SystemClock
+
+/** A helper class for replacing uptimeMillis with elapsedRealtime for entry creation times */
+public object UseElapsedRealtimeForCreationTime {
+    @JvmStatic
+    fun getCurrentTime(clock: SystemClock): Long {
+        if (Flags.notifEntryCreationTimeUseElapsedRealtime()) {
+            return clock.elapsedRealtime()
+        }
+        return clock.uptimeMillis()
+    }
+
+    @JvmStatic
+    fun getCurrentTime(): Long {
+        if (Flags.notifEntryCreationTimeUseElapsedRealtime()) {
+            return android.os.SystemClock.elapsedRealtime()
+        }
+        return android.os.SystemClock.uptimeMillis()
+
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/EventBatch.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/EventBatch.java
index 2eec68b..fb7772e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/EventBatch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/EventBatch.java
@@ -25,7 +25,7 @@
  * Represents a set of notification post events for a particular notification group.
  */
 public class EventBatch {
-    /** SystemClock.uptimeMillis() */
+    /** SystemClock.elapsedRealtime() */
     final long mCreatedTimestamp;
 
     /** SBN.getGroupKey -- same for all members */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescer.java
index 96b3542..944e313 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescer.java
@@ -34,6 +34,7 @@
 import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
 import com.android.systemui.statusbar.notification.collection.PipelineDumpable;
 import com.android.systemui.statusbar.notification.collection.PipelineDumper;
+import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime;
 import com.android.systemui.util.concurrency.DelayableExecutor;
 import com.android.systemui.util.time.SystemClock;
 
@@ -182,11 +183,12 @@
     private void maybeEmitBatch(StatusBarNotification sbn) {
         final CoalescedEvent event = mCoalescedEvents.get(sbn.getKey());
         final EventBatch batch = mBatches.get(sbn.getGroupKey());
+        long now = UseElapsedRealtimeForCreationTime.getCurrentTime(mClock);
         if (event != null) {
             mLogger.logEarlyEmit(sbn.getKey(), requireNonNull(event.getBatch()).mGroupKey);
             emitBatch(requireNonNull(event.getBatch()));
         } else if (batch != null
-                && mClock.uptimeMillis() - batch.mCreatedTimestamp >= mMaxGroupLingerDuration) {
+                && now - batch.mCreatedTimestamp >= mMaxGroupLingerDuration) {
             mLogger.logMaxBatchTimeout(sbn.getKey(), batch.mGroupKey);
             emitBatch(batch);
         }
@@ -228,7 +230,8 @@
     private EventBatch getOrBuildBatch(final String groupKey) {
         EventBatch batch = mBatches.get(groupKey);
         if (batch == null) {
-            batch = new EventBatch(mClock.uptimeMillis(), groupKey);
+            batch = new EventBatch(UseElapsedRealtimeForCreationTime.getCurrentTime(mClock),
+                    groupKey);
             mBatches.put(groupKey, batch);
         }
         return batch;
@@ -268,7 +271,8 @@
         }
         events.sort(mEventComparator);
 
-        long batchAge = mClock.uptimeMillis() - batch.mCreatedTimestamp;
+        long batchAge = UseElapsedRealtimeForCreationTime.getCurrentTime(mClock)
+                - batch.mCreatedTimestamp;
         mLogger.logEmitBatch(batch.mGroupKey, batch.mMembers.size(), batchAge);
 
         mHandler.onNotificationBatchPosted(events);
@@ -298,7 +302,7 @@
 
     @Override
     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
-        long now = mClock.uptimeMillis();
+        long now = UseElapsedRealtimeForCreationTime.getCurrentTime(mClock);
 
         int eventCount = 0;
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt
index 8833ff1..4478d0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/BundleCoordinator.kt
@@ -98,9 +98,14 @@
         object : NotifBundler("NotifBundler") {
 
             // Use list instead of set to keep fixed order
-            override val bundleIds: List<String> = SYSTEM_RESERVED_IDS
+            override val bundleIds: List<String> =
+                if (debugBundleUi) SYSTEM_RESERVED_IDS + "notify"
+                else SYSTEM_RESERVED_IDS
 
             override fun getBundleIdOrNull(entry: NotificationEntry?): String? {
+                if (debugBundleUi && entry?.key?.contains("notify") == true) {
+                    return "notify"
+                }
                 return entry?.representativeEntry?.channel?.id?.takeIf { it in this.bundleIds }
             }
         }
@@ -110,4 +115,9 @@
             pipeline.setNotifBundler(bundler)
         }
     }
+
+    companion object {
+        @kotlin.jvm.JvmField
+        var debugBundleUi: Boolean = true
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
index 2f0701f..3747aba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
@@ -17,6 +17,7 @@
 package com.android.systemui.statusbar.notification.collection.coordinator
 
 import android.util.ArrayMap
+import com.android.systemui.statusbar.notification.collection.BundleEntry
 import com.android.systemui.statusbar.notification.collection.GroupEntry
 import com.android.systemui.statusbar.notification.collection.PipelineEntry
 import com.android.systemui.statusbar.notification.collection.NotifPipeline
@@ -37,9 +38,17 @@
     private fun onBeforeFinalizeFilter(entries: List<PipelineEntry>) {
         // save untruncated child counts to our internal map
         untruncatedChildCounts.clear()
-        entries.asSequence().filterIsInstance<GroupEntry>().forEach { groupEntry ->
-            untruncatedChildCounts[groupEntry] = groupEntry.children.size
-        }
+        entries.asSequence()
+            .flatMap { entry ->
+                when (entry) {
+                    is GroupEntry -> listOf(entry)
+                    is BundleEntry -> entry.children.filterIsInstance<GroupEntry>()
+                    else -> emptyList()
+                }
+            }
+            .forEach { groupEntry ->
+                untruncatedChildCounts[groupEntry] = groupEntry.children.size
+            }
     }
 
     private fun onAfterRenderGroup(group: GroupEntry, controller: NotifGroupController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
index b54f21b..20169ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinator.java
@@ -36,6 +36,7 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.systemui.statusbar.notification.collection.BundleEntry;
 import com.android.systemui.statusbar.notification.collection.GroupEntry;
+import com.android.systemui.statusbar.notification.collection.ListEntry;
 import com.android.systemui.statusbar.notification.collection.PipelineEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -241,8 +242,7 @@
                 isMemberOfDelayedGroup = shouldWaitForGroupToInflate(parent, now);
                 mIsDelayedGroupCache.put(parent, isMemberOfDelayedGroup);
             }
-
-            return !isInflated(entry) || isMemberOfDelayedGroup;
+            return !isInflated(entry) || (isMemberOfDelayedGroup != null && isMemberOfDelayedGroup);
         }
 
         @Override
@@ -308,8 +308,15 @@
     private void inflateAllRequiredViews(List<PipelineEntry> entries) {
         for (int i = 0, size = entries.size(); i < size; i++) {
             PipelineEntry entry = entries.get(i);
-            if (NotificationBundleUi.isEnabled() && entry instanceof BundleEntry) {
-                // TODO(b/399738511) Inflate bundle views.
+            if (NotificationBundleUi.isEnabled() && entry instanceof BundleEntry bundleEntry) {
+                for (ListEntry listEntry : bundleEntry.getChildren()) {
+                    if (listEntry instanceof GroupEntry groupEntry) {
+                        inflateRequiredGroupViews(groupEntry);
+                    } else {
+                        NotificationEntry notifEntry = (NotificationEntry) listEntry;
+                        inflateRequiredNotifViews(notifEntry);
+                    }
+                }
             } else if (entry instanceof GroupEntry) {
                 GroupEntry groupEntry = (GroupEntry) entry;
                 inflateRequiredGroupViews(groupEntry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
index a0a8671..f43767d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
@@ -22,7 +22,6 @@
 import com.android.internal.widget.MessagingMessage
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.Flags
 import com.android.systemui.shade.ShadeDisplayAware
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener
@@ -147,9 +146,7 @@
         traceSection("updateNotifOnUiModeChanged") {
             mPipeline?.allNotifs?.forEach { entry ->
                 entry.row?.onUiModeChanged()
-                if (Flags.notificationUndoGutsOnConfigChanged()) {
-                    mGutsManager.closeAndUndoGuts()
-                }
+                mGutsManager.closeAndUndoGuts()
             }
         }
     }
@@ -158,16 +155,7 @@
         colorUpdateLogger.logEvent("VCC.updateNotificationsOnDensityOrFontScaleChanged()")
         mPipeline?.allNotifs?.forEach { entry ->
             entry.onDensityOrFontScaleChanged()
-            if (Flags.notificationUndoGutsOnConfigChanged()) {
-                mGutsManager.closeAndUndoGuts()
-            } else {
-                // This property actually gets reset when the guts are re-inflated, so we're never
-                // actually calling onDensityOrFontScaleChanged below.
-                val exposedGuts = entry.areGutsExposed()
-                if (exposedGuts) {
-                    mGutsManager.onDensityOrFontScaleChanged(entry)
-                }
-            }
+            mGutsManager.closeAndUndoGuts()
         }
     }
 
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 bdbdc53..0466c03 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
@@ -39,9 +39,9 @@
 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.PipelineEntry;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.PipelineEntry;
 import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener;
 import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifStabilityManager;
 import com.android.systemui.statusbar.notification.collection.provider.VisualStabilityProvider;
@@ -113,6 +113,8 @@
     @VisibleForTesting
     protected static final long ALLOW_SECTION_CHANGE_TIMEOUT = 500;
 
+    private final boolean mCheckLockScreenTransitionEnabled = Flags.checkLockscreenGoneTransition();
+
     @Inject
     public VisualStabilityCoordinator(
             @Background DelayableExecutor delayableExecutor,
@@ -182,7 +184,7 @@
                     this::onTrackingHeadsUpModeChanged);
         }
 
-        if (Flags.checkLockscreenGoneTransition()) {
+        if (mCheckLockScreenTransitionEnabled) {
             if (SceneContainerFlag.isEnabled()) {
                 mJavaAdapter.alwaysCollectFlow(mKeyguardTransitionInteractor.isInTransition(
                                 Edge.create(KeyguardState.LOCKSCREEN, Scenes.Gone), null),
@@ -437,7 +439,7 @@
         boolean wasReorderingAllowed = mReorderingAllowed;
         // No need to run notification pipeline when the lockscreen is in fading animation.
         mPipelineRunAllowed = !(isPanelCollapsingOrLaunchingActivity()
-                || (Flags.checkLockscreenGoneTransition() && mLockscreenInGoneTransition));
+                || (mCheckLockScreenTransitionEnabled && mLockscreenInGoneTransition));
         mReorderingAllowed = isReorderingAllowed();
         if (wasPipelineRunAllowed != mPipelineRunAllowed
                 || wasReorderingAllowed != mReorderingAllowed) {
@@ -499,7 +501,7 @@
      * notification and we are reordering based on the user's change.
      *
      * @param entry notification entry that can change sections even if isReorderingAllowed is false
-     * @param now current time SystemClock.uptimeMillis
+     * @param now current time SystemClock.elapsedRealtime
      */
     public void temporarilyAllowSectionChanges(@NonNull NotificationEntry entry, long now) {
         final String entryKey = entry.getKey();
@@ -566,7 +568,7 @@
         pw.println("pipelineRunAllowed: " + mPipelineRunAllowed);
         pw.println("  notifPanelCollapsing: " + mNotifPanelCollapsing);
         pw.println("  launchingNotifActivity: " + mNotifPanelLaunchingActivity);
-        if (Flags.checkLockscreenGoneTransition()) {
+        if (mCheckLockScreenTransitionEnabled) {
             pw.println("  lockscreenInGoneTransition: " + mLockscreenInGoneTransition);
         }
         pw.println("reorderingAllowed: " + mReorderingAllowed);
@@ -627,7 +629,7 @@
     }
 
     private void onLockscreenInGoneTransitionChanged(boolean inGoneTransition) {
-        if (!Flags.checkLockscreenGoneTransition()) {
+        if (!mCheckLockScreenTransitionEnabled) {
             return;
         }
         if (inGoneTransition == mLockscreenInGoneTransition) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
index 07fa6ae..03b4076 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/OnUserInteractionCallbackImpl.java
@@ -20,7 +20,6 @@
 
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 
-import android.os.SystemClock;
 import android.service.notification.NotificationStats;
 
 import androidx.annotation.NonNull;
@@ -30,6 +29,7 @@
 import com.android.systemui.statusbar.notification.collection.NotifCollection;
 import com.android.systemui.statusbar.notification.collection.NotifCollection.CancellationReason;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime;
 import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
 import com.android.systemui.statusbar.notification.collection.notifcollection.DismissedByUserStats;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
@@ -85,7 +85,7 @@
     public void onImportanceChanged(NotificationEntry entry) {
         mVisualStabilityCoordinator.temporarilyAllowSectionChanges(
                 entry,
-                SystemClock.uptimeMillis());
+                UseElapsedRealtimeForCreationTime.getCurrentTime());
     }
 
     @NonNull
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java
index 776c7d5..389bb31 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifFilter.java
@@ -41,8 +41,8 @@
      *              this entry will not have any grouping nor sorting information.
      *              If this filter is registered via {@link NotifPipeline#addFinalizeFilter},
      *              this entry will have grouping and sorting information.
-     * @param now A timestamp in SystemClock.uptimeMillis that represents "now" for the purposes of
-     *            pipeline execution. This value will be the same for all pluggable calls made
+     * @param now A timestamp in SystemClock.elapsedRealtime that represents "now" for the purposes
+     *            of pipeline execution. This value will be the same for all pluggable calls made
      *            during this pipeline run, giving pluggables a stable concept of "now" to compare
      *            various entries against.
      * @return True if the notif should be removed from the list
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
index 8021d8f..a552ca5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
@@ -234,21 +234,21 @@
     fun getChildCount(): Int = controller.getChildCount()
 
     fun addChildAt(child: ShadeNode, index: Int) {
-        traceSection("ShadeNode#addChildAt") {
+        traceSection({ "ShadeNode#${controller::class.simpleName}#addChildAt" }) {
             controller.addChildAt(child.controller, index)
             child.controller.onViewAdded()
         }
     }
 
     fun moveChildTo(child: ShadeNode, index: Int) {
-        traceSection("ShadeNode#moveChildTo") {
+        traceSection({ "ShadeNode#${controller::class.simpleName}#moveChildTo" }) {
             controller.moveChildTo(child.controller, index)
             child.controller.onViewMoved()
         }
     }
 
     fun removeChild(child: ShadeNode, isTransfer: Boolean) {
-        traceSection("ShadeNode#removeChild") {
+        traceSection({ "ShadeNode#${controller::class.simpleName}#removeChild" }) {
             controller.removeChild(child.controller, isTransfer)
             child.controller.onViewRemoved()
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
index cdbe0fd..8d1e611 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/domain/interactor/HeadsUpNotificationInteractor.kt
@@ -81,7 +81,7 @@
         if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
             flowOf(emptySet())
         } else {
-            activeHeadsUpRows.map { it.map { (repo, _) -> repo }.toSet() }
+            activeHeadsUpRows.map { it.map { (repo, _) -> repo }.toSet() }.distinctUntilChanged()
         }
     }
 
@@ -90,9 +90,9 @@
         if (SceneContainerFlag.isUnexpectedlyInLegacyMode()) {
             flowOf(emptySet())
         } else {
-            activeHeadsUpRows.map {
-                it.filter { (_, isPinned) -> isPinned }.map { (repo, _) -> repo }.toSet()
-            }
+            activeHeadsUpRows
+                .map { it.filter { (_, isPinned) -> isPinned }.map { (repo, _) -> repo }.toSet() }
+                .distinctUntilChanged() // TODO(b/402428276) stop sending duplicate updates instead
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
index 147a5af..619d48f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/ui/viewbinder/NotificationIconContainerStatusBarViewBinder.kt
@@ -18,9 +18,9 @@
 
 import android.view.Display
 import androidx.lifecycle.lifecycleScope
+import com.android.app.displaylib.PerDisplayRepository
 import com.android.app.tracing.traceSection
 import com.android.systemui.common.ui.ConfigurationState
-import com.android.systemui.display.data.repository.PerDisplayRepository
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.statusbar.notification.collection.NotifCollection
 import com.android.systemui.statusbar.notification.icon.ui.viewbinder.NotificationIconContainerViewBinder.IconViewStore
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index ec8fbc0..5bdd769 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -19,7 +19,6 @@
 import android.os.Handler;
 import android.os.RemoteException;
 import android.os.ServiceManager;
-import android.os.SystemClock;
 import android.service.notification.NotificationListenerService;
 import android.util.ArrayMap;
 import android.util.ArraySet;
@@ -44,6 +43,7 @@
 import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore;
 import com.android.systemui.statusbar.notification.collection.NotifPipeline;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.UseElapsedRealtimeForCreationTime;
 import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
 import com.android.systemui.statusbar.notification.collection.notifcollection.UpdateSource;
 import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
@@ -112,7 +112,7 @@
 
         @Override
         public void run() {
-            mLastVisibilityReportUptimeMs = SystemClock.uptimeMillis();
+            mLastVisibilityReportUptimeMs = UseElapsedRealtimeForCreationTime.getCurrentTime();
 
             // 1. Loop over active entries:
             //   A. Keep list of visible notifications.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
index 2a01a14..777392d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/AODPromotedNotification.kt
@@ -19,19 +19,26 @@
 import android.app.Flags
 import android.app.Flags.notificationsRedesignTemplates
 import android.app.Notification
+import android.content.Context
 import android.graphics.PorterDuff
 import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.View.GONE
+import android.view.View.MeasureSpec.AT_MOST
+import android.view.View.MeasureSpec.EXACTLY
+import android.view.View.MeasureSpec.UNSPECIFIED
+import android.view.View.MeasureSpec.makeMeasureSpec
 import android.view.View.VISIBLE
 import android.view.ViewGroup.MarginLayoutParams
 import android.view.ViewStub
 import android.widget.Chronometer
 import android.widget.DateTimeView
+import android.widget.FrameLayout
 import android.widget.ImageView
 import android.widget.ProgressBar
 import android.widget.TextView
+import androidx.annotation.DimenRes
 import androidx.compose.foundation.BorderStroke
 import androidx.compose.foundation.border
 import androidx.compose.foundation.layout.Box
@@ -42,7 +49,9 @@
 import androidx.compose.runtime.key
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.graphics.SolidColor
+import androidx.compose.ui.platform.LocalDensity
 import androidx.compose.ui.res.dimensionResource
+import androidx.compose.ui.unit.Dp
 import androidx.compose.ui.unit.dp
 import androidx.compose.ui.viewinterop.AndroidView
 import androidx.core.view.isVisible
@@ -88,22 +97,12 @@
     }
 
     key(content.identity) {
-        val sidePaddings = dimensionResource(systemuiR.dimen.notification_side_paddings)
-        val sidePaddingValues = PaddingValues(horizontal = sidePaddings, vertical = 0.dp)
-
-        val borderStroke = BorderStroke(1.dp, SecondaryText.brush)
-
-        val borderRadius = dimensionResource(systemuiR.dimen.notification_corner_radius)
-        val borderShape = RoundedCornerShape(borderRadius)
-
-        Box(modifier = modifier.padding(sidePaddingValues)) {
-            AODPromotedNotificationView(
-                layoutResource = layoutResource,
-                content = content,
-                audiblyAlertedIconVisible = audiblyAlertedIconVisible,
-                modifier = Modifier.border(borderStroke, borderShape),
-            )
-        }
+        AODPromotedNotificationView(
+            layoutResource = layoutResource,
+            content = content,
+            audiblyAlertedIconVisible = audiblyAlertedIconVisible,
+            modifier = modifier,
+        )
     }
 }
 
@@ -114,27 +113,91 @@
     audiblyAlertedIconVisible: Boolean,
     modifier: Modifier = Modifier,
 ) {
-    AndroidView(
-        factory = { context ->
-            val view =
-                traceSection("$TAG.inflate") {
-                    LayoutInflater.from(context).inflate(layoutResource, /* root= */ null)
-                }
+    val sidePaddings = dimensionResource(systemuiR.dimen.notification_side_paddings)
+    val sidePaddingValues = PaddingValues(horizontal = sidePaddings, vertical = 0.dp)
 
-            val updater =
-                traceSection("$TAG.findViews") { AODPromotedNotificationViewUpdater(view) }
+    val boxModifier = modifier.padding(sidePaddingValues)
 
-            view.setTag(viewUpdaterTagId, updater)
+    val borderStroke = BorderStroke(1.dp, SecondaryText.brush)
 
-            view
-        },
-        update = { view ->
-            val updater = view.getTag(viewUpdaterTagId) as AODPromotedNotificationViewUpdater
+    val borderRadius = dimensionResource(systemuiR.dimen.notification_corner_radius)
+    val borderShape = RoundedCornerShape(borderRadius)
 
-            traceSection("$TAG.update") { updater.update(content, audiblyAlertedIconVisible) }
-        },
-        modifier = modifier,
-    )
+    val maxHeight =
+        with(LocalDensity.current) {
+                scaledFontHeight(systemuiR.dimen.notification_max_height_for_promoted_ongoing)
+                    .toPx()
+            }
+            .toInt()
+
+    val viewModifier = Modifier.border(borderStroke, borderShape)
+
+    Box(modifier = boxModifier) {
+        AndroidView(
+            factory = { context ->
+                val notif =
+                    traceSection("$TAG.inflate") {
+                        LayoutInflater.from(context).inflate(layoutResource, /* root= */ null)
+                    }
+                val updater =
+                    traceSection("$TAG.findViews") { AODPromotedNotificationViewUpdater(notif) }
+
+                val frame = FrameLayoutWithMaxHeight(maxHeight, context)
+                frame.addView(notif)
+                frame.setTag(viewUpdaterTagId, updater)
+
+                frame
+            },
+            update = { frame ->
+                val updater = frame.getTag(viewUpdaterTagId) as AODPromotedNotificationViewUpdater
+
+                traceSection("$TAG.update") { updater.update(content, audiblyAlertedIconVisible) }
+                frame.maxHeight = maxHeight
+            },
+            modifier = viewModifier,
+        )
+    }
+}
+
+private class FrameLayoutWithMaxHeight(maxHeight: Int, context: Context) : FrameLayout(context) {
+    var maxHeight = maxHeight
+        set(value) {
+            if (field != value) {
+                field = value
+                requestLayout()
+            }
+        }
+
+    // This mirrors the logic in NotificationContentView.onMeasure.
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        if (childCount < 1) {
+            return
+        }
+
+        val child = getChildAt(0)
+        val childLayoutHeight = child.layoutParams.height
+        val childHeightSpec =
+            if (childLayoutHeight >= 0) {
+                makeMeasureSpec(maxHeight.coerceAtMost(childLayoutHeight), EXACTLY)
+            } else {
+                makeMeasureSpec(maxHeight, AT_MOST)
+            }
+        measureChildWithMargins(child, widthMeasureSpec, 0, childHeightSpec, 0)
+        val childMeasuredHeight = child.measuredHeight
+
+        val ownHeightMode = MeasureSpec.getMode(heightMeasureSpec)
+        val ownHeightSize = MeasureSpec.getSize(heightMeasureSpec)
+
+        val ownMeasuredWidth = MeasureSpec.getSize(widthMeasureSpec)
+        val ownMeasuredHeight =
+            if (ownHeightMode != UNSPECIFIED) {
+                childMeasuredHeight.coerceAtMost(ownHeightSize)
+            } else {
+                childMeasuredHeight
+            }
+
+        setMeasuredDimension(ownMeasuredWidth, ownMeasuredHeight)
+    }
 }
 
 private val PromotedNotificationContentModel.layoutResource: Int?
@@ -521,6 +584,11 @@
     val brush = SolidColor(androidx.compose.ui.graphics.Color(colorInt))
 }
 
+@Composable
+private fun scaledFontHeight(@DimenRes dimenId: Int): Dp {
+    return dimensionResource(dimenId) * LocalDensity.current.fontScale.coerceAtLeast(1f)
+}
+
 private val viewUpdaterTagId = systemuiR.id.aod_promoted_notification_view_updater_tag
 
 private const val TAG = "AODPromotedNotification"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
index d35c3b61..27b2788 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationContentExtractor.kt
@@ -21,6 +21,7 @@
 import android.app.Notification.BigTextStyle
 import android.app.Notification.CallStyle
 import android.app.Notification.EXTRA_BIG_TEXT
+import android.app.Notification.EXTRA_CALL_PERSON
 import android.app.Notification.EXTRA_CHRONOMETER_COUNT_DOWN
 import android.app.Notification.EXTRA_PROGRESS
 import android.app.Notification.EXTRA_PROGRESS_INDETERMINATE
@@ -33,6 +34,7 @@
 import android.app.Notification.EXTRA_VERIFICATION_TEXT
 import android.app.Notification.InboxStyle
 import android.app.Notification.ProgressStyle
+import android.app.Person
 import android.content.Context
 import android.graphics.drawable.Icon
 import com.android.systemui.Flags
@@ -108,12 +110,12 @@
         contentBuilder.shortCriticalText = notification.shortCriticalText()
         contentBuilder.lastAudiblyAlertedMs = entry.lastAudiblyAlertedMs
         contentBuilder.profileBadgeResId = null // TODO
-        contentBuilder.title = notification.resolveTitle(recoveredBuilder.style)
-        contentBuilder.text = notification.resolveText(recoveredBuilder.style)
+        contentBuilder.title = notification.title(recoveredBuilder.style)
+        contentBuilder.text = notification.text(recoveredBuilder.style)
         contentBuilder.skeletonLargeIcon = notification.skeletonLargeIcon(imageModelProvider)
         contentBuilder.oldProgress = notification.oldProgress()
 
-        val colorsFromNotif = recoveredBuilder.getColors(/* header= */ false)
+        val colorsFromNotif = recoveredBuilder.getColors(/* isHeader= */ false)
         contentBuilder.colors =
             PromotedNotificationContentModel.Colors(
                 backgroundColor = colorsFromNotif.backgroundColor,
@@ -132,20 +134,16 @@
 
     private fun Notification.bigTitle(): CharSequence? = extras?.getCharSequence(EXTRA_TITLE_BIG)
 
-    private fun Notification.Style.bigTitleOverridesTitle(): Boolean {
-        return when (this) {
+    private fun Notification.callPerson(): Person? =
+        extras?.getParcelable(EXTRA_CALL_PERSON, Person::class.java)
+
+    private fun Notification.title(style: Notification.Style?): CharSequence? {
+        return when (style) {
             is BigTextStyle,
             is BigPictureStyle,
-            is InboxStyle -> true
-            else -> false
-        }
-    }
-
-    private fun Notification.resolveTitle(style: Notification.Style?): CharSequence? {
-        return if (style?.bigTitleOverridesTitle() == true) {
-            bigTitle()
-        } else {
-            null
+            is InboxStyle -> bigTitle()
+            is CallStyle -> callPerson()?.name
+            else -> null
         } ?: title()
     }
 
@@ -153,13 +151,10 @@
 
     private fun Notification.bigText(): CharSequence? = extras?.getCharSequence(EXTRA_BIG_TEXT)
 
-    private fun Notification.Style.bigTextOverridesText(): Boolean = this is BigTextStyle
-
-    private fun Notification.resolveText(style: Notification.Style?): CharSequence? {
-        return if (style?.bigTextOverridesText() == true) {
-            bigText()
-        } else {
-            null
+    private fun Notification.text(style: Notification.Style?): CharSequence? {
+        return when (style) {
+            is BigTextStyle -> bigText()
+            else -> null
         } ?: text()
     }
 
@@ -204,16 +199,18 @@
         extras?.getBoolean(EXTRA_PROGRESS_INDETERMINATE)
 
     private fun Notification.extractWhen(): When? {
+        val whenTime = getWhen()
+
         return when {
             showsChronometer() -> {
                 When.Chronometer(
                     elapsedRealtimeMillis =
-                        `when` + systemClock.elapsedRealtime() - systemClock.currentTimeMillis(),
+                        whenTime + systemClock.elapsedRealtime() - systemClock.currentTimeMillis(),
                     isCountDown = chronometerCountDown(),
                 )
             }
 
-            showsTime() -> When.Time(currentTimeMillis = `when`)
+            showsTime() -> When.Time(currentTimeMillis = whenTime)
 
             else -> null
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt
index 4689347..5f9678a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/PromotedNotificationLogger.kt
@@ -63,7 +63,7 @@
             INFO,
             {
                 str1 = entry.logKey
-                str2 = content.toString()
+                str2 = content.toRedactedString()
             },
             { "extraction succeeded: $str2 for $str1" },
         )
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
index 0c2859f..57b0720 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/promoted/shared/model/PromotedNotificationContentModel.kt
@@ -25,6 +25,8 @@
 import com.android.internal.widget.NotificationProgressModel
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips
 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi
+import com.android.systemui.statusbar.notification.row.ImageResult
+import com.android.systemui.statusbar.notification.row.LazyImage
 import com.android.systemui.statusbar.notification.row.shared.ImageModel
 
 /**
@@ -152,6 +154,54 @@
         Ineligible,
     }
 
+    fun toRedactedString(): String {
+        return ("PromotedNotificationContentModel(" +
+            "identity=$identity, " +
+            "wasPromotedAutomatically=$wasPromotedAutomatically, " +
+            "smallIcon=${smallIcon?.toRedactedString()}, " +
+            "appName=$appName, " +
+            "subText=${subText?.toRedactedString()}, " +
+            "shortCriticalText=$shortCriticalText, " +
+            "time=$time, " +
+            "lastAudiblyAlertedMs=$lastAudiblyAlertedMs, " +
+            "profileBadgeResId=$profileBadgeResId, " +
+            "title=${title?.toRedactedString()}, " +
+            "text=${text?.toRedactedString()}, " +
+            "skeletonLargeIcon=${skeletonLargeIcon?.toRedactedString()}, " +
+            "oldProgress=$oldProgress, " +
+            "colors=$colors, " +
+            "style=$style, " +
+            "personIcon=${personIcon?.toRedactedString()}, " +
+            "personName=${personName?.toRedactedString()}, " +
+            "verificationIcon=$verificationIcon, " +
+            "verificationText=$verificationText, " +
+            "newProgress=$newProgress)")
+    }
+
+    private fun CharSequence.toRedactedString(): String = "[$length]"
+
+    private fun ImageModel.toRedactedString(): String {
+        return when (this) {
+            is LazyImage -> this.toRedactedString()
+            else -> this.toString()
+        }
+    }
+
+    private fun LazyImage.toRedactedString(): String {
+        return ("LazyImage(" +
+            "icon=[${icon.javaClass.simpleName}], " +
+            "sizeClass=$sizeClass, " +
+            "transform=$transform, " +
+            "result=${result?.toRedactedString()})")
+    }
+
+    private fun ImageResult.toRedactedString(): String {
+        return when (this) {
+            is ImageResult.Empty -> this.toString()
+            is ImageResult.Image -> "Image(drawable=[${drawable.javaClass.simpleName}])"
+        }
+    }
+
     companion object {
         @JvmStatic
         fun featureFlagEnabled(): Boolean =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 6892226..b0b08a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -40,6 +40,7 @@
 import com.android.app.animation.Interpolators;
 import com.android.internal.jank.InteractionJankMonitor;
 import com.android.internal.jank.InteractionJankMonitor.Configuration;
+import com.android.systemui.Flags;
 import com.android.systemui.Gefingerpoken;
 import com.android.systemui.common.shared.colors.SurfaceEffectColors;
 import com.android.systemui.res.R;
@@ -101,7 +102,8 @@
     private ValueAnimator mBackgroundColorAnimator;
     private float mAppearAnimationFraction = -1.0f;
     private float mAppearAnimationTranslation;
-    private int mNormalColor;
+    protected int mNormalColor;
+    protected int mOpaqueColor;
     private boolean mIsBelowSpeedBump;
     private long mLastActionUpTime;
 
@@ -130,17 +132,13 @@
 
     protected void updateColors() {
         if (notificationRowTransparency()) {
-            if (mIsBlurSupported) {
-                mNormalColor = SurfaceEffectColors.surfaceEffect1(getContext());
-            } else {
-                mNormalColor = mContext.getColor(
-                        com.android.internal.R.color.materialColorSurfaceContainer);
-            }
+            mNormalColor = SurfaceEffectColors.surfaceEffect1(getContext());
+            mOpaqueColor = mContext.getColor(
+                    com.android.internal.R.color.materialColorSurfaceContainer);
         } else {
             mNormalColor = mContext.getColor(
                     com.android.internal.R.color.materialColorSurfaceContainerHigh);
         }
-        setBackgroundToNormalColor();
         mTintedRippleColor = mContext.getColor(
                 R.color.notification_ripple_tinted_color);
         mNormalRippleColor = mContext.getColor(
@@ -151,12 +149,6 @@
         mOverrideAmount = 0.0f;
     }
 
-    private void setBackgroundToNormalColor() {
-        if (mBackgroundNormal != null) {
-            mBackgroundNormal.setNormalColor(mNormalColor);
-        }
-    }
-
     /**
      * Reload background colors from resources and invalidate views.
      */
@@ -186,7 +178,6 @@
         mBackgroundNormal = findViewById(R.id.backgroundNormal);
         mFakeShadow = findViewById(R.id.fake_shadow);
         mShadowHidden = mFakeShadow.getVisibility() != VISIBLE;
-        setBackgroundToNormalColor();
         initBackground();
         updateBackgroundTint();
         updateOutlineAlpha();
@@ -709,7 +700,11 @@
         if (withTint && mBgTint != NO_COLOR) {
             return mBgTint;
         } else {
-            return mNormalColor;
+            if (Flags.notificationRowTransparency()) {
+                return usesTransparentBackground() ? mNormalColor : mOpaqueColor;
+            } else {
+                return mNormalColor;
+            }
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 8da2f76..2a3b266 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -22,9 +22,9 @@
 import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_EXPANDED;
 import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED;
 
+import static com.android.systemui.Flags.notificationRowAccessibilityExpanded;
 import static com.android.systemui.Flags.notificationRowTransparency;
 import static com.android.systemui.Flags.notificationsPinnedHunInShade;
-import static com.android.systemui.Flags.notificationRowAccessibilityExpanded;
 import static com.android.systemui.flags.Flags.ENABLE_NOTIFICATIONS_SIMULATE_SLOW_MEASURE;
 import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
 import static com.android.systemui.statusbar.notification.collection.NotificationEntry.DismissState.PARENT_DISMISSED;
@@ -41,6 +41,7 @@
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.graphics.Canvas;
+import android.graphics.Color;
 import android.graphics.Path;
 import android.graphics.Point;
 import android.graphics.Rect;
@@ -82,6 +83,7 @@
 
 import com.android.app.animation.Interpolators;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.graphics.ColorUtils;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -421,9 +423,10 @@
                 }
                 onExpansionChanged(true /* userAction */, wasExpanded);
             } else {
-                final boolean wasExpanded = mGroupExpansionManager.isGroupExpanded(mEntry);
-                boolean nowExpanded = mGroupExpansionManager.toggleGroupExpansion(mEntry);
-                mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
+                final boolean wasExpanded =
+                        mGroupExpansionManager.isGroupExpanded(getEntryLegacy());
+                boolean nowExpanded = mGroupExpansionManager.toggleGroupExpansion(getEntryLegacy());
+                mOnExpandClickListener.onExpandClicked(getEntryLegacy(), v, nowExpanded);
                 if (shouldLogExpandClickMetric) {
                     mMetricsLogger.action(
                             MetricsEvent.ACTION_NOTIFICATION_GROUP_EXPANDER, nowExpanded);
@@ -453,7 +456,7 @@
             if (NotificationBundleUi.isEnabled()) {
                 mOnExpandClickListener.onExpandClicked(this, mEntryAdapter, nowExpanded);
             } else {
-                mOnExpandClickListener.onExpandClicked(mEntry, v, nowExpanded);
+                mOnExpandClickListener.onExpandClicked(getEntryLegacy(), v, nowExpanded);
             }
             if (shouldLogExpandClickMetric) {
                 mMetricsLogger.action(MetricsEvent.ACTION_NOTIFICATION_EXPANDER, nowExpanded);
@@ -558,7 +561,7 @@
         if (NotificationBundleUi.isEnabled()) {
             return mKey;
         } else {
-            return mEntry.getKey();
+            return getEntryLegacy().getKey();
         }
     }
 
@@ -661,15 +664,20 @@
      */
     public boolean getIsNonblockable() {
         NotificationBundleUi.assertInLegacyMode();
-        if (mEntry == null) {
+        if (getEntryLegacy() == null) {
             return true;
         }
-        return !mEntry.isBlockable();
+        return !getEntryLegacy().isBlockable();
     }
 
     private boolean isConversation() {
-        return mPeopleNotificationIdentifier.getPeopleNotificationType(mEntry)
-                != PeopleNotificationIdentifier.TYPE_NON_PERSON;
+        if (NotificationBundleUi.isEnabled()) {
+            return getEntryAdapter().getPeopleNotificationType()
+                    != PeopleNotificationIdentifier.TYPE_NON_PERSON;
+        } else {
+            return mPeopleNotificationIdentifier.getPeopleNotificationType(getEntryLegacy())
+                    != PeopleNotificationIdentifier.TYPE_NON_PERSON;
+        }
     }
 
     public void onNotificationUpdated() {
@@ -679,7 +687,7 @@
             Trace.beginSection("ExpNotRow#onNotifUpdated (leaf)");
         }
         for (NotificationContentView l : mLayouts) {
-            l.onNotificationUpdated(mEntry);
+            l.onNotificationUpdated(getEntry());
         }
         mShowingPublicInitialized = false;
         if (mMenuRow != null) {
@@ -746,7 +754,7 @@
      */
     public void updateBubbleButton() {
         for (NotificationContentView l : mLayouts) {
-            l.updateBubbleButton(mEntry);
+            l.updateBubbleButton(getEntry());
         }
     }
 
@@ -777,7 +785,7 @@
                 return mEntryAdapter.getContrastedColor(mContext, mIsMinimized && !isExpanded(),
                         getBackgroundColorWithoutTint());
             } else {
-                return mEntry.getContrastedColor(mContext, mIsMinimized && !isExpanded(),
+                return getEntryLegacy().getContrastedColor(mContext, mIsMinimized && !isExpanded(),
                         getBackgroundColorWithoutTint());
             }
         }
@@ -885,7 +893,7 @@
         if (NotificationBundleUi.isEnabled()) {
             targetSdk = mEntryAdapter.getTargetSdk();
         } else {
-            targetSdk = mEntry.targetSdk;
+            targetSdk = getEntryLegacy().targetSdk;
         }
 
         boolean beforeN = targetSdk < Build.VERSION_CODES.N;
@@ -901,7 +909,7 @@
         if (NotificationBundleUi.isEnabled()) {
             summarization = mEntryAdapter.getSummarization();
         } else {
-            summarization = mEntry.getRanking().getSummarization();
+            summarization = getEntryLegacy().getRanking().getSummarization();
         }
 
         if (customView && beforeS && !mIsSummaryWithChildren) {
@@ -945,7 +953,25 @@
         layout.setHeights(smallHeight, headsUpHeight, maxExpandedHeight);
     }
 
+    /**
+     * Check {@link NotificationBundleUi#isEnabled()}
+     * and use {@link #getEntryAdapter()} when true
+     * and {@link #getEntryLegacy()} when false.
+     */
     @NonNull
+    @Deprecated
+    public NotificationEntry getEntryLegacy() {
+        NotificationBundleUi.assertInLegacyMode();
+        return mEntry;
+    }
+
+    /**
+     * Check {@link NotificationBundleUi#isEnabled()}
+     * and use {@link #getEntryAdapter()} when true
+     * and {@link #getEntryLegacy()} when false.
+     */
+    @NonNull
+    @Deprecated
     public NotificationEntry getEntry() {
         return mEntry;
     }
@@ -979,7 +1005,7 @@
         } else if (isAboveShelf() != wasAboveShelf) {
             mAboveShelfChangedListener.onAboveShelfStateChanged(!wasAboveShelf);
         }
-        updateColors();
+        updateBackgroundTint();
     }
 
     /**
@@ -1481,8 +1507,8 @@
     public void setBubbleClickListener(@Nullable OnClickListener l) {
         mBubbleClickListener = l;
         // ensure listener is passed to the content views
-        mPrivateLayout.updateBubbleButton(mEntry);
-        mPublicLayout.updateBubbleButton(mEntry);
+        mPrivateLayout.updateBubbleButton(getEntry());
+        mPublicLayout.updateBubbleButton(getEntry());
     }
 
     /**
@@ -1554,7 +1580,7 @@
             return initializationTime != -1
                     && SystemClock.elapsedRealtime() > initializationTime + INITIALIZATION_DELAY;
         } else {
-            return getEntry().hasFinishedInitialization();
+            return getEntryLegacy().hasFinishedInitialization();
         }
     }
 
@@ -1633,14 +1659,14 @@
         if (NotificationBundleUi.isEnabled()) {
             mEntryAdapter.prepareForInflation();
         } else {
-            mEntry.getSbn().clearPackageContext();
+            getEntryLegacy().getSbn().clearPackageContext();
         }
         // TODO: Move content inflation logic out of this call
         RowContentBindParams params = mRowContentBindStage.getStageParams(mEntry);
         params.setNeedsReinflation(true);
 
         var rebindEndCallback = mRebindingTracker.trackRebinding(NotificationBundleUi.isEnabled()
-                ? mEntryAdapter.getKey() : mEntry.getKey());
+                ? mEntryAdapter.getKey() : getEntryLegacy().getKey());
         mRowContentBindStage.requestRebind(mEntry, (e) -> rebindEndCallback.onFinished());
         Trace.endSection();
     }
@@ -1678,21 +1704,36 @@
 
     @Override
     protected void setBackgroundTintColor(int color) {
+        if (notificationRowTransparency()) {
+            boolean isColorized = false;
+            if (NotificationBundleUi.isEnabled()) {
+                if (mEntryAdapter != null) {
+                    isColorized = mEntryAdapter.isColorized();
+                }
+            } else {
+                if (mEntry != null) {
+                    isColorized = mEntry.getSbn().getNotification().isColorized();
+                }
+            }
+            boolean isTransparent = usesTransparentBackground();
+            if (isColorized) {
+                // For colorized notifications, use a color that matches the tint color at 90% alpha
+                // when the row is transparent.
+                color = ColorUtils.setAlphaComponent(
+                        color, (int) (0xFF * (isTransparent ? 0.9f : 1)));
+            } else {
+                // For non-colorized notifications, use the semi-transparent normal color token
+                // when the row is transparent, and the opaque color token otherwise.
+                if (!isTransparent && mBgTint == NO_COLOR) {
+                    color = mOpaqueColor;
+                }
+            }
+        }
         super.setBackgroundTintColor(color);
         NotificationContentView view = getShowingLayout();
         if (view != null) {
             view.setBackgroundTintColor(color);
         }
-        if (notificationRowTransparency() && mBackgroundNormal != null) {
-            if (NotificationBundleUi.isEnabled() && mEntryAdapter != null) {
-                mBackgroundNormal.setBgIsColorized(mEntryAdapter.isColorized());
-            } else {
-                if (mEntry != null) {
-                    mBackgroundNormal.setBgIsColorized(
-                            mEntry.getSbn().getNotification().isColorized());
-                }
-            }
-        }
     }
 
     public void closeRemoteInput() {
@@ -1750,7 +1791,11 @@
 
     /** @return true if the User has dismissed this notif's parent */
     public boolean isParentDismissed() {
-        return getEntry().getDismissState() == PARENT_DISMISSED;
+        if (NotificationBundleUi.isEnabled()) {
+            return getEntryAdapter().getDismissState() == PARENT_DISMISSED;
+        } else {
+            return getEntryLegacy().getDismissState() == PARENT_DISMISSED;
+        }
     }
 
     @Override
@@ -2310,7 +2355,9 @@
     }
 
     @VisibleForTesting
-    protected void setEntry(NotificationEntry entry) {
+    @Deprecated
+    protected void setEntryLegacy(NotificationEntry entry) {
+        NotificationBundleUi.assertInLegacyMode();
         mEntry = entry;
     }
 
@@ -2403,7 +2450,7 @@
         if (NotificationBundleUi.isEnabled()) {
             return traceTag + "(" + getEntryAdapter().getStyle() + ")";
         } else {
-            return traceTag + "(" + getEntry().getNotificationStyle() + ")";
+            return traceTag + "(" + getEntryLegacy().getNotificationStyle() + ")";
         }
     }
 
@@ -2473,7 +2520,11 @@
      */
     public void dragAndDropSuccess() {
         if (mOnDragSuccessListener != null) {
-            mOnDragSuccessListener.onDragSuccess(getEntry());
+            if (NotificationBundleUi.isEnabled()) {
+                mOnDragSuccessListener.onDragSuccess(getEntryAdapter());
+            } else {
+                mOnDragSuccessListener.onDragSuccess(getEntryLegacy());
+            }
         }
     }
 
@@ -2908,7 +2959,7 @@
         if (NotificationBundleUi.isEnabled()) {
             return getEntryAdapter().getIcons().getShelfIcon();
         } else {
-            return mEntry.getIcons().getShelfIcon();
+            return getEntryLegacy().getIcons().getShelfIcon();
         }
     }
 
@@ -3016,7 +3067,7 @@
                     mGroupExpansionManager.setGroupExpanded(mEntryAdapter, userExpanded);
                 }
             } else {
-                mGroupExpansionManager.setGroupExpanded(mEntry, userExpanded);
+                mGroupExpansionManager.setGroupExpanded(getEntryLegacy(), userExpanded);
             }
             onExpansionChanged(true /* userAction */, wasExpanded);
             return;
@@ -3113,7 +3164,7 @@
                     mChildrenContainer.setOnKeyguard(onKeyguard);
                 }
             }
-            updateColors();
+            updateBackgroundTint();
         }
     }
 
@@ -3159,7 +3210,7 @@
     public boolean canShowHeadsUp() {
         boolean canEntryHun = NotificationBundleUi.isEnabled()
                 ? mEntryAdapter.canPeek()
-                : mEntry.isStickyAndNotDemoted();
+                : getEntryLegacy().isStickyAndNotDemoted();
         if (mOnKeyguard && !isDozing() && !isBypassEnabled() &&
                 (!canEntryHun
                         || (!mIgnoreLockscreenConstraints && mSaveSpaceOnLockscreen))) {
@@ -3181,13 +3232,13 @@
         if (NotificationBundleUi.isEnabled()) {
             return mGroupExpansionManager.isGroupExpanded(mEntryAdapter);
         }
-        return mGroupExpansionManager.isGroupExpanded(mEntry);
+        return mGroupExpansionManager.isGroupExpanded(getEntryLegacy());
     }
 
     private boolean isGroupRoot() {
         return NotificationBundleUi.isEnabled()
                 ? mGroupMembershipManager.isGroupRoot(mEntryAdapter)
-                : mGroupMembershipManager.isGroupSummary(mEntry);
+                : mGroupMembershipManager.isGroupSummary(getEntryLegacy());
     }
 
     private void onAttachedChildrenCountChanged() {
@@ -3209,7 +3260,8 @@
             if (NotificationBundleUi.isEnabled()) {
                 mPublicLayout.setNotificationWhen(mEntryAdapter.getWhen());
             } else {
-                mPublicLayout.setNotificationWhen(mEntry.getSbn().getNotification().getWhen());
+                mPublicLayout.setNotificationWhen(
+                        getEntryLegacy().getSbn().getNotification().getWhen());
             }
         }
         getShowingLayout().updateBackgroundColor(false /* animate */);
@@ -3243,12 +3295,19 @@
             return false;
         }
 
-        final NotificationEntry entry = mEntry;
-        if (entry == null) {
-            return false;
+        if (NotificationBundleUi.isEnabled()) {
+            final EntryAdapter entryAdapter = mEntryAdapter;
+            if (entryAdapter == null) {
+                return false;
+            }
+            return entryAdapter.isPromotedOngoing();
+        } else {
+            final NotificationEntry entry = mEntry;
+            if (entry == null) {
+                return false;
+            }
+            return entry.isPromotedOngoing();
         }
-
-        return entry.isPromotedOngoing();
     }
 
     private boolean isPromotedNotificationExpanded(boolean allowOnKeyguard) {
@@ -3537,7 +3596,8 @@
             return mEntryAdapter.isClearable()
                     && (!shouldShowPublic() || !mSensitiveHiddenInGeneral);
         } else {
-            return mEntry.isClearable() && (!shouldShowPublic() || !mSensitiveHiddenInGeneral);
+            return getEntryLegacy().isClearable()
+                    && (!shouldShowPublic() || !mSensitiveHiddenInGeneral);
         }
     }
 
@@ -3551,7 +3611,7 @@
             if (!NotificationBundleUi.isEnabled()) {
                 // this is only called if row.getParent() instanceof NotificationStackScrollLayout,
                 // so there is never a group to expand
-                mGroupExpansionManager.setGroupExpanded(mEntry, true);
+                mGroupExpansionManager.setGroupExpanded(getEntryLegacy(), true);
             }
         }
         notifyHeightChanged(/* needsAnimation= */ false);
@@ -3784,7 +3844,7 @@
                 return true;
             }
         } else {
-            if (getEntry().getSbn().getNotification().isColorized()) {
+            if (getEntryLegacy().getSbn().getNotification().isColorized()) {
                 return true;
             }
         }
@@ -3951,12 +4011,19 @@
             }
         } else if (isChildInGroup()) {
             final int childColor = getShowingLayout().getBackgroundColorForExpansionState();
-            // Only show a background if the group is expanded OR if it is expanding / collapsing
-            // and has a custom background color.
-            final boolean showBackground = isGroupExpanded()
-                    || ((mNotificationParent.isGroupExpansionChanging()
-                    || mNotificationParent.isUserLocked()) && childColor != 0);
-            mShowNoBackground = !showBackground;
+            if ((Flags.notificationRowTransparency() || notificationsRedesignTemplates())
+                    && childColor == Color.TRANSPARENT) {
+                // If child is not customizing its background color, switch from the parent to
+                // the child background when the expansion finishes.
+                mShowNoBackground = !mNotificationParent.mShowNoBackground;
+            } else {
+                // Only show a background if the group is expanded OR if it is
+                // expanding / collapsing and has a custom background color.
+                final boolean showBackground = isGroupExpanded()
+                        || ((mNotificationParent.isGroupExpansionChanging()
+                        || mNotificationParent.isUserLocked()) && childColor != 0);
+                mShowNoBackground = !showBackground;
+            }
         } else {
             // Only children or parents ever need no background.
             mShowNoBackground = false;
@@ -4255,7 +4322,7 @@
 
     public boolean isMediaRow() {
         NotificationBundleUi.assertInLegacyMode();
-        return mEntry.getSbn().getNotification().isMediaNotification();
+        return getEntryLegacy().getSbn().getNotification().isMediaNotification();
     }
 
     public void setAboveShelf(boolean aboveShelf) {
@@ -4359,6 +4426,12 @@
          * @param entry NotificationEntry that succeed to drop on proper target window.
          */
         void onDragSuccess(NotificationEntry entry);
+
+        /**
+         * @param entryAdapter The EntryAdapter that successfully dropped on the proper
+         *            target window
+         */
+        void onDragSuccess(EntryAdapter entryAdapter);
     }
 
     /**
@@ -4377,11 +4450,7 @@
     public void dump(PrintWriter pwOriginal, String[] args) {
         IndentingPrintWriter pw = DumpUtilsKt.asIndenting(pwOriginal);
         // Skip super call; dump viewState ourselves
-        if (NotificationBundleUi.isEnabled()) {
-            pw.println("Notification: " + mEntryAdapter.getKey());
-        } else {
-            pw.println("Notification: " + mEntry.getKey());
-        }
+        pw.println("Notification: " + getKey());
         DumpUtilsKt.withIncreasedIndent(pw, () -> {
             pw.println(this);
             pw.print("visibility: " + getVisibility());
@@ -4618,7 +4687,7 @@
         if (NotificationBundleUi.isEnabled()) {
             mLaunchAnimationRunning = launchAnimationRunning;
         } else {
-            getEntry().setExpandAnimationRunning(launchAnimationRunning);
+            getEntryLegacy().setExpandAnimationRunning(launchAnimationRunning);
         }
     }
 
@@ -4627,12 +4696,14 @@
         if (NotificationBundleUi.isEnabled()) {
             return mLaunchAnimationRunning;
         } else {
-            return getEntry().isExpandAnimationRunning();
+            return getEntryLegacy().isExpandAnimationRunning();
         }
     }
 
     @Override
     protected boolean usesTransparentBackground() {
+        // Row background should be opaque when it's displayed as a heads-up notification or
+        // displayed on keyguard.
         return super.usesTransparentBackground() && !mIsHeadsUp && !mOnKeyguard;
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
index ac55930..49d715c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowController.java
@@ -20,6 +20,7 @@
 import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.notification.NotificationUtils.logKey;
+import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
 
 import android.net.Uri;
 import android.os.UserHandle;
@@ -35,8 +36,8 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.statusbar.IStatusBarService;
+import com.android.systemui.Flags;
 import com.android.systemui.flags.FeatureFlagsClassic;
-import com.android.systemui.flags.Flags;
 import com.android.systemui.plugins.FalsingManager;
 import com.android.systemui.plugins.PluginManager;
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
@@ -45,11 +46,8 @@
 import com.android.systemui.statusbar.SmartReplyController;
 import com.android.systemui.statusbar.notification.ColorUpdateLogger;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
-import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory;
-import com.android.systemui.statusbar.notification.collection.EntryAdapterFactoryImpl;
 import com.android.systemui.statusbar.notification.collection.PipelineEntry;
-import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
 import com.android.systemui.statusbar.notification.collection.provider.NotificationDismissibilityProvider;
 import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
 import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
@@ -60,7 +58,6 @@
 import com.android.systemui.statusbar.notification.row.dagger.AppName;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationKey;
 import com.android.systemui.statusbar.notification.row.dagger.NotificationRowScope;
-import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider;
 import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
 import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainerLogger;
 import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
@@ -69,6 +66,7 @@
 import com.android.systemui.statusbar.policy.SmartReplyConstants;
 import com.android.systemui.statusbar.policy.dagger.RemoteInputViewSubcomponent;
 import com.android.systemui.util.time.SystemClock;
+import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor;
 
 import com.google.android.msdl.data.model.MSDLToken;
 import com.google.android.msdl.domain.MSDLPlayer;
@@ -125,6 +123,7 @@
     private final MSDLPlayer mMSDLPlayer;
     private final NotificationSettingsController mSettingsController;
     private final EntryAdapterFactory mEntryAdapterFactory;
+    private final WindowRootViewBlurInteractor mWindowRootViewBlurInteractor;
 
     @VisibleForTesting
     final NotificationSettingsController.Listener mSettingsListener =
@@ -139,7 +138,7 @@
                         }
                         final int viewUserId = NotificationBundleUi.isEnabled()
                             ? mView.getEntryAdapter().getSbn().getUserId()
-                            : mView.getEntry().getSbn().getUserId();
+                            : mView.getEntryLegacy().getSbn().getUserId();
                         if (viewUserId == UserHandle.USER_ALL || viewUserId == userId) {
                             mView.getPrivateLayout().setBubblesEnabledForUser(
                                     BUBBLES_SETTING_ENABLED_VALUE.equals(value));
@@ -291,7 +290,8 @@
             UiEventLogger uiEventLogger,
             MSDLPlayer msdlPlayer,
             NotificationRebindingTracker notificationRebindingTracker,
-            EntryAdapterFactory entryAdapterFactory) {
+            EntryAdapterFactory entryAdapterFactory,
+            WindowRootViewBlurInteractor windowRootViewBlurInteractor) {
         mView = view;
         mListContainer = listContainer;
         mRemoteInputViewSubcomponentFactory = rivSubcomponentFactory;
@@ -329,6 +329,7 @@
         mUiEventLogger = uiEventLogger;
         mMSDLPlayer = msdlPlayer;
         mEntryAdapterFactory = entryAdapterFactory;
+        mWindowRootViewBlurInteractor = windowRootViewBlurInteractor;
     }
 
     /**
@@ -367,7 +368,8 @@
         );
         mView.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
         if (mAllowLongPress) {
-            if (mFeatureFlags.isEnabled(Flags.NOTIFICATION_DRAG_TO_CONTENTS)) {
+            if (mFeatureFlags.isEnabled(
+                    com.android.systemui.flags.Flags.NOTIFICATION_DRAG_TO_CONTENTS)) {
                 mView.setDragController(mDragController);
             }
 
@@ -395,7 +397,7 @@
                         mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener);
                     }
                 } else {
-                    mView.getEntry().setInitializationTime(mClock.elapsedRealtime());
+                    mView.getEntryLegacy().setInitializationTime(mClock.elapsedRealtime());
                     mSettingsController.addCallback(BUBBLES_SETTING_URI, mSettingsListener);
                 }
                 mPluginManager.addPluginListener(mView,
@@ -416,6 +418,11 @@
                 mSettingsController.removeCallback(BUBBLES_SETTING_URI, mSettingsListener);
             }
         });
+
+        if (Flags.notificationRowTransparency()) {
+            collectFlow(mView, mWindowRootViewBlurInteractor.isBlurCurrentlySupported(),
+                    mView::setIsBlurSupported);
+        }
     }
 
     private final StatusBarStateController.StateListener mStatusBarStateListener =
@@ -429,7 +436,9 @@
     @Override
     @NonNull
     public String getNodeLabel() {
-        return NotificationBundleUi.isEnabled() ? mView.getLoggingKey() : logKey(mView.getEntry());
+        return NotificationBundleUi.isEnabled()
+                ? mView.getLoggingKey()
+                : logKey(mView.getEntryLegacy());
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
index 9ae2eb1..20b826a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowDragController.java
@@ -109,7 +109,7 @@
 
         StatusBarNotification sn = NotificationBundleUi.isEnabled()
                 ? enr.getEntryAdapter().getSbn()
-                : enr.getEntry().getSbn();
+                : enr.getEntryLegacy().getSbn();
         Notification notification = sn.getNotification();
         final PendingIntent contentIntent = notification.contentIntent != null
                 ? notification.contentIntent
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt
index fe3a856..a9ca635 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/MagicActionBackgroundDrawable.kt
@@ -62,6 +62,7 @@
 
     private val buttonShape = Path()
     // Color and style
+    private val outlineStaticColor = context.getColor(R.color.magic_action_button_stroke_color)
     private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
         val bgColor =
             context.getColor(
@@ -70,15 +71,17 @@
         color = bgColor
         style = Paint.Style.FILL
     }
-    private val outlinePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
-        val outlineColor =
-            context.getColor(
-                com.android.internal.R.color.materialColorOutlineVariant
-            )
-        color = outlineColor
+    private val outlineGradientPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
+        color = outlineStaticColor
         style = Paint.Style.STROKE
         strokeWidth = outlineStrokeWidth
     }
+    private val outlineSolidPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
+        color = outlineStaticColor
+        style = Paint.Style.STROKE
+        strokeWidth = outlineStrokeWidth
+    }
+
     private val outlineStartColor =
         context.getColor(
             com.android.internal.R.color.materialColorTertiaryContainer
@@ -91,21 +94,35 @@
         context.getColor(
             com.android.internal.R.color.materialColorPrimary
         )
+
     // Animation
     private var gradientAnimator: ValueAnimator
     private var rotationAngle = 20f // Start rotation at 20 degrees
+    private var fadeAnimator: ValueAnimator? = null
+    private var gradientAlpha = 255    // Fading out gradient
+    private var solidAlpha = 0         // Fading in solid color
 
     init {
         gradientAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
-            duration = 5000 // 5 seconds
+            duration = 1500
             interpolator = Interpolators.LINEAR
-            repeatCount = 1
+            repeatCount = 0
             addUpdateListener { animator ->
                 val animatedValue = animator.animatedValue as Float
                 rotationAngle = 20f + animatedValue * 360f // Rotate in a spiral
                 invalidateSelf()
             }
-            // TODO: Reset the outline color when animation ends.
+            start()
+        }
+        fadeAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
+            duration = 500
+            startDelay = 1000
+            addUpdateListener { animator ->
+                val progress = animator.animatedValue as Float
+                gradientAlpha = ((1 - progress) * 255).toInt()  // Fade out gradient
+                solidAlpha = (progress * 255).toInt()          // Fade in color
+                invalidateSelf()
+            }
             start()
         }
     }
@@ -120,14 +137,9 @@
         // Draw background
         canvas.clipPath(buttonShape)
         canvas.drawPath(buttonShape, bgPaint)
-        // Apply gradient to outline
-        canvas.drawPath(buttonShape, outlinePaint)
-        updateGradient(boundsF)
-        canvas.restore()
-    }
 
-    private fun updateGradient(boundsF: RectF) {
-        val gradient = LinearGradient(
+        // Set up outline gradient
+        val gradientShader = LinearGradient(
             boundsF.left, boundsF.top,
             boundsF.right, boundsF.bottom,
             intArrayOf(outlineStartColor, outlineMiddleColor, outlineEndColor),
@@ -137,9 +149,17 @@
         // Create a rotation matrix for the spiral effect
         val matrix = Matrix()
         matrix.setRotate(rotationAngle, boundsF.centerX(), boundsF.centerY())
-        gradient.setLocalMatrix(matrix)
+        gradientShader.setLocalMatrix(matrix)
 
-        outlinePaint.shader = gradient
+        // Apply gradient to outline
+        outlineGradientPaint.shader = gradientShader
+        outlineGradientPaint.alpha = gradientAlpha
+        canvas.drawPath(buttonShape, outlineGradientPaint)
+        // Apply solid color to outline
+        outlineSolidPaint.alpha = solidAlpha
+        canvas.drawPath(buttonShape, outlineSolidPaint)
+
+        canvas.restore()
     }
 
     override fun onBoundsChange(bounds: Rect) {
@@ -149,13 +169,15 @@
 
     override fun setAlpha(alpha: Int) {
         bgPaint.alpha = alpha
-        outlinePaint.alpha = alpha
+        outlineGradientPaint.alpha = alpha
+        outlineSolidPaint.alpha = alpha
         invalidateSelf()
     }
 
     override fun setColorFilter(colorFilter: ColorFilter?) {
         bgPaint.colorFilter = colorFilter
-        outlinePaint.colorFilter = colorFilter
+        outlineGradientPaint.colorFilter = colorFilter
+        outlineSolidPaint.colorFilter = colorFilter
         invalidateSelf()
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
index 4914e10..e4997e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBackgroundView.java
@@ -36,9 +36,9 @@
 import androidx.annotation.NonNull;
 import androidx.annotation.Nullable;
 
-import com.android.internal.graphics.ColorUtils;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.Dumpable;
+import com.android.systemui.common.shared.colors.SurfaceEffectColors;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.notification.shared.NotificationAddXOnHoverToDismiss;
 import com.android.systemui.util.DrawableDumpKt;
@@ -52,7 +52,6 @@
 public class NotificationBackgroundView extends View implements Dumpable,
         ExpandableNotificationRow.DismissButtonTargetVisibilityListener {
 
-    private static final int MAX_ALPHA = 0xFF;
     private final boolean mDontModifyCorners;
     private Drawable mBackground;
     private int mClipTopAmount;
@@ -73,8 +72,6 @@
     private final ColorStateList mLightColoredStatefulColors;
     private final ColorStateList mDarkColoredStatefulColors;
     private int mNormalColor;
-    private boolean mBgIsColorized = false;
-    private boolean mForceOpaque = false;
     private final int convexR = 9;
     private final int concaveR = 22;
 
@@ -88,13 +85,15 @@
                 R.color.notification_state_color_light);
         mDarkColoredStatefulColors = getResources().getColorStateList(
                 R.color.notification_state_color_dark);
+        if (notificationRowTransparency()) {
+            mNormalColor = SurfaceEffectColors.surfaceEffect1(getContext());
+        } else  {
+            mNormalColor = mContext.getColor(
+                    com.android.internal.R.color.materialColorSurfaceContainerHigh);
+        }
         mFocusOverlayStroke = getResources().getDimension(R.dimen.notification_focus_stroke_width);
     }
 
-    public void setNormalColor(int color) {
-        mNormalColor = color;
-    }
-
     @Override
     public void onTargetVisibilityChanged(boolean targetVisible) {
         if (NotificationAddXOnHoverToDismiss.isUnexpectedlyInLegacyMode()) {
@@ -140,21 +139,6 @@
         }
     }
 
-    /**
-     * A way to tell whether the background has been colorized.
-     */
-    public boolean isColorized() {
-        return mBgIsColorized;
-    }
-
-    /**
-     * A way to inform this class whether the background has been colorized.
-     * We need to know this, in order to *not* override that color.
-     */
-    public void setBgIsColorized(boolean b) {
-        mBgIsColorized = b;
-    }
-
     private Path calculateDismissButtonCutoutPath(Rect backgroundBounds) {
         // TODO(b/365585705): Adapt to RTL after the UX design is finalized.
 
@@ -311,28 +295,21 @@
         return ((LayerDrawable) mBackground).getDrawable(1);
     }
 
-    private void updateBaseLayerColor() {
-        // BG base layer being a drawable, there isn't a method like setColor() to color it.
-        // Instead, we set a color filter that essentially replaces every pixel of the drawable.
-        // For non-colorized notifications, this function specifies a new color token.
-        // For colorized notifications, this uses a color that matches the tint color at 90% alpha.
-        int color = isColorized()
-                ? ColorUtils.setAlphaComponent(mTintColor, (int) (MAX_ALPHA * 0.9f))
-                : mNormalColor;
-        getBaseBackgroundLayer().setColorFilter(
-                new PorterDuffColorFilter(
-                        color,
-                        PorterDuff.Mode.SRC)); // SRC operator discards the drawable's color+alpha
-    }
-
     public void setTint(int tintColor) {
         Drawable baseLayer = getBaseBackgroundLayer();
-        baseLayer.mutate().setTintMode(PorterDuff.Mode.SRC_ATOP);
-        baseLayer.setTint(tintColor);
-        mTintColor = tintColor;
         if (notificationRowTransparency()) {
-            updateBaseLayerColor();
+            // BG base layer being a drawable, there isn't a method like setColor() to color it.
+            // Instead, we set a color filter that essentially replaces every pixel of the drawable.
+            baseLayer.setColorFilter(
+                    new PorterDuffColorFilter(
+                            tintColor,
+                            // SRC operator discards the drawable's color+alpha
+                            PorterDuff.Mode.SRC));
+        } else {
+            baseLayer.mutate().setTintMode(PorterDuff.Mode.SRC_ATOP);
+            baseLayer.setTint(tintColor);
         }
+        mTintColor = tintColor;
         setStatefulColors();
         invalidate();
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index ff4b835..d97e25f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -473,7 +473,7 @@
                     result.newPublicView = createSensitiveContentMessageNotification(
                             NotificationBundleUi.isEnabled()
                                     ? row.getEntryAdapter().getSbn().getNotification()
-                                    : row.getEntry().getSbn().getNotification(),
+                                    : row.getEntryLegacy().getSbn().getNotification(),
                             builder.getStyle(),
                             systemUiContext, packageContext).createContentView();
                 } else {
@@ -814,7 +814,7 @@
                     existingWrapper.onReinflated();
                 }
             } catch (Exception e) {
-                handleInflationError(runningInflations, e, row, callback, logger,
+                handleInflationError(runningInflations, e, row, entry, callback, logger,
                         "applying view synchronously");
                 // Add a running inflation to make sure we don't trigger callbacks.
                 // Safe to do because only happens in tests.
@@ -836,7 +836,7 @@
                 String invalidReason = isValidView(v, entry, row.getResources());
                 if (invalidReason != null) {
                     handleInflationError(runningInflations, new InflationException(invalidReason),
-                            row, callback, logger, "applied invalid view");
+                            row, entry, callback, logger, "applied invalid view");
                     runningInflations.remove(inflationId);
                     return;
                 }
@@ -873,7 +873,7 @@
                     onViewApplied(newView);
                 } catch (Exception anotherException) {
                     runningInflations.remove(inflationId);
-                    handleInflationError(runningInflations, e, row,
+                    handleInflationError(runningInflations, e, row, entry,
                             callback, logger, "applying view");
                 }
             }
@@ -969,13 +969,14 @@
 
     private static void handleInflationError(
             HashMap<Integer, CancellationSignal> runningInflations, Exception e,
-            ExpandableNotificationRow row, @Nullable InflationCallback callback,
+            ExpandableNotificationRow row, NotificationEntry entry,
+            @Nullable InflationCallback callback,
             NotificationRowContentBinderLogger logger, String logContext) {
         Assert.isMainThread();
         logger.logAsyncTaskException(row.getLoggingKey(), logContext, e);
         runningInflations.values().forEach(CancellationSignal::cancel);
         if (callback != null) {
-            callback.handleInflationException(row.getEntry(), e);
+            callback.handleInflationException(entry, e);
         }
     }
 
@@ -1443,7 +1444,7 @@
                     + Integer.toHexString(sbn.getId());
             Log.e(CentralSurfaces.TAG, "couldn't inflate view for notification " + ident, e);
             if (mCallback != null) {
-                mCallback.handleInflationException(mRow.getEntry(),
+                mCallback.handleInflationException(mEntry,
                         new InflationException("Couldn't inflate contentViews" + e));
             }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index b3357d0..488aa44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -269,6 +269,7 @@
         mNotificationMaxHeight = maxHeight;
     }
 
+    // This logic is mirrored in FrameLayoutWithMaxHeight.onMeasure in AODPromotedNotification.kt.
     @Override
     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
         int heightMode = MeasureSpec.getMode(heightMeasureSpec);
@@ -600,7 +601,7 @@
         if (NotificationBundleUi.isEnabled()) {
             return mContainingNotification.getEntryAdapter().getSbn();
         } else {
-            return mContainingNotification.getEntry().getSbn();
+            return mContainingNotification.getEntryLegacy().getSbn();
         }
     }
 
@@ -1592,20 +1593,26 @@
             return;
         }
         ImageView bubbleButton = layout.findViewById(com.android.internal.R.id.bubble_button);
-        View actionContainer = layout.findViewById(com.android.internal.R.id.actions_container);
-        ViewGroup actionListMarginTarget = layout.findViewById(
-                com.android.internal.R.id.notification_action_list_margin_target);
-        if (bubbleButton == null || actionContainer == null) {
+        // With the new design, the actions_container should always be visible to act as padding
+        // when there are no actions. We're making its child visible/invisible instead.
+        View actionsContainerForVisibilityChange = layout.findViewById(
+                notificationsRedesignTemplates()
+                        ? com.android.internal.R.id.actions_container_layout
+                        : com.android.internal.R.id.actions_container);
+        if (bubbleButton == null || actionsContainerForVisibilityChange == null) {
             return;
         }
 
         if (shouldShowBubbleButton(entry)) {
+            boolean isBubble = NotificationBundleUi.isEnabled()
+                    ? mContainingNotification.getEntryAdapter().isBubble()
+                    : entry.isBubble();
             // explicitly resolve drawable resource using SystemUI's theme
-            Drawable d = mContext.getDrawable(entry.isBubble()
+            Drawable d = mContext.getDrawable(isBubble
                     ? com.android.wm.shell.R.drawable.bubble_ic_stop_bubble
                     : com.android.wm.shell.R.drawable.bubble_ic_create_bubble);
 
-            String contentDescription = mContext.getResources().getString(entry.isBubble()
+            String contentDescription = mContext.getResources().getString(isBubble
                     ? R.string.notification_conversation_unbubble
                     : R.string.notification_conversation_bubble);
 
@@ -1613,17 +1620,14 @@
             bubbleButton.setImageDrawable(d);
             bubbleButton.setOnClickListener(mContainingNotification.getBubbleClickListener());
             bubbleButton.setVisibility(VISIBLE);
-            actionContainer.setVisibility(VISIBLE);
-            // Set notification_action_list_margin_target's bottom margin to 0 when showing bubble
-            if (actionListMarginTarget != null) {
-                removeBottomMargin(actionListMarginTarget);
-            }
-            if (notificationsRedesignTemplates()) {
-                // Similar treatment for smart reply margin
-                LinearLayout smartReplyContainer = layout.findViewById(
-                        com.android.internal.R.id.smart_reply_container);
-                if (smartReplyContainer != null) {
-                    removeBottomMargin(smartReplyContainer);
+            actionsContainerForVisibilityChange.setVisibility(VISIBLE);
+            if (!notificationsRedesignTemplates()) {
+                // Set notification_action_list_margin_target's bottom margin to 0 when showing
+                // bubble
+                ViewGroup actionListMarginTarget = layout.findViewById(
+                        com.android.internal.R.id.notification_action_list_margin_target);
+                if (actionListMarginTarget != null) {
+                    removeBottomMargin(actionListMarginTarget);
                 }
             }
         } else  {
@@ -1651,12 +1655,18 @@
 
     @VisibleForTesting
     boolean shouldShowBubbleButton(NotificationEntry entry) {
-        boolean isPersonWithShortcut =
-                mPeopleIdentifier.getPeopleNotificationType(entry)
-                        >= PeopleNotificationIdentifier.TYPE_FULL_PERSON;
+        int peopleType = NotificationBundleUi.isEnabled()
+                ? mContainingNotification.getEntryAdapter().getPeopleNotificationType()
+                : mPeopleIdentifier.getPeopleNotificationType(entry);
+        Notification.BubbleMetadata bubbleMetadata = NotificationBundleUi.isEnabled()
+                ? mContainingNotification.getEntryAdapter().getSbn().getNotification()
+                        .getBubbleMetadata()
+                : entry.getBubbleMetadata();
+        boolean isPersonWithShortcut = peopleType
+                >= PeopleNotificationIdentifier.TYPE_FULL_PERSON;
         return mBubblesEnabledForUser
                 && isPersonWithShortcut
-                && entry.getBubbleMetadata() != null;
+                && bubbleMetadata != null;
     }
 
     private void applySnoozeAction(View layout) {
@@ -1664,8 +1674,13 @@
             return;
         }
         ImageView snoozeButton = layout.findViewById(com.android.internal.R.id.snooze_button);
-        View actionContainer = layout.findViewById(com.android.internal.R.id.actions_container);
-        if (snoozeButton == null || actionContainer == null) {
+        // With the new design, the actions_container should always be visible to act as padding
+        // when there are no actions. We're making its child visible/invisible instead.
+        View actionsContainerForVisibilityChange = layout.findViewById(
+                notificationsRedesignTemplates()
+                        ? com.android.internal.R.id.actions_container_layout
+                        : com.android.internal.R.id.actions_container);
+        if (snoozeButton == null || actionsContainerForVisibilityChange == null) {
             return;
         }
         // Notification.Builder can 'disable' the snooze button to prevent it from being shown here
@@ -1691,7 +1706,7 @@
         snoozeButton.setOnClickListener(
                 mContainingNotification.getSnoozeClickListener(snoozeMenuItem));
         snoozeButton.setVisibility(VISIBLE);
-        actionContainer.setVisibility(VISIBLE);
+        actionsContainerForVisibilityChange.setVisibility(VISIBLE);
     }
 
     private void applySmartReplyView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 55a5649..cdb78d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -47,7 +47,6 @@
 import com.android.internal.statusbar.IStatusBarService;
 import com.android.settingslib.notification.ConversationIconFactory;
 import com.android.systemui.CoreStartable;
-import com.android.systemui.Flags;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -235,15 +234,6 @@
         }
     }
 
-    public void onDensityOrFontScaleChanged(NotificationEntry entry) {
-        if (!Flags.notificationUndoGutsOnConfigChanged()) {
-            Log.wtf(TAG, "onDensityOrFontScaleChanged should not be called if"
-                    + " notificationUndoGutsOnConfigChanged is off");
-        }
-        setExposedGuts(entry.getGuts());
-        bindGuts(entry.getRow());
-    }
-
     /**
      * Sends an intent to open the notification settings for a particular package and optional
      * channel.
@@ -295,11 +285,6 @@
         mNotificationActivityStarter.startNotificationGutsIntent(intent, uid, row);
     }
 
-    private boolean bindGuts(final ExpandableNotificationRow row) {
-        row.ensureGutsInflated();
-        return bindGuts(row, mGutsMenuItem);
-    }
-
     @VisibleForTesting
     protected boolean bindGuts(final ExpandableNotificationRow row,
             NotificationMenuRowPlugin.MenuItem item) {
@@ -445,6 +430,7 @@
                 NotificationBundleUi.isEnabled()
                         ? !row.getEntry().isBlockable()
                         : row.getIsNonblockable(),
+                row.canViewBeDismissed(),
                 mHighPriorityProvider.isHighPriority(row.getEntry()),
                 mAssistantFeedbackController,
                 mMetricsLogger,
@@ -610,6 +596,7 @@
         return mNotificationGutsExposed;
     }
 
+    @VisibleForTesting
     public void setExposedGuts(NotificationGuts guts) {
         mNotificationGutsExposed = guts;
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
index 904911f..b6f4ffc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationInfo.java
@@ -121,6 +121,7 @@
     private boolean mIsAutomaticChosen;
     private boolean mIsSingleDefaultChannel;
     private boolean mIsNonblockable;
+    private boolean mIsDismissable;
     private NotificationEntry mEntry;
     private StatusBarNotification mSbn;
     private boolean mIsDeviceProvisioned;
@@ -161,6 +162,7 @@
         mPressedApply = true;
         mGutsContainer.closeControls(v, /* save= */ true);
     };
+    private OnClickListener mOnCloseClickListener;
 
     public NotificationInfo(Context context, AttributeSet attrs) {
         super(context, attrs);
@@ -204,6 +206,7 @@
             UiEventLogger uiEventLogger,
             boolean isDeviceProvisioned,
             boolean isNonblockable,
+            boolean isDismissable,
             boolean wasShownHighPriority,
             AssistantFeedbackController assistantFeedbackController,
             MetricsLogger metricsLogger,
@@ -228,11 +231,13 @@
         mStartingChannelImportance = mSingleNotificationChannel.getImportance();
         mWasShownHighPriority = wasShownHighPriority;
         mIsNonblockable = isNonblockable;
+        mIsDismissable = isDismissable;
         mAppUid = mSbn.getUid();
         mDelegatePkg = mSbn.getOpPkg();
         mIsDeviceProvisioned = isDeviceProvisioned;
         mShowAutomaticSetting = mAssistantFeedbackController.isFeedbackEnabled();
         mUiEventLogger = uiEventLogger;
+        mOnCloseClickListener = onCloseClick;
 
         mIsSystemRegisteredCall = mSbn.getNotification().isStyle(Notification.CallStyle.class)
                 && mINotificationManager.isInCall(mSbn.getPackageName(), mSbn.getUid());
@@ -279,6 +284,11 @@
         turnOffButton.setVisibility(turnOffButton.hasOnClickListeners() && !mIsNonblockable
                 ? VISIBLE : GONE);
 
+        View dismissButton = findViewById(R.id.inline_dismiss);
+        dismissButton.setOnClickListener(mOnCloseClickListener);
+        dismissButton.setVisibility(dismissButton.hasOnClickListeners() && mIsDismissable
+                ? VISIBLE : GONE);
+
         View done = findViewById(R.id.done);
         done.setOnClickListener(mOnDismissSettings);
         done.setAccessibilityDelegate(mGutsContainer.getAccessibilityDelegate());
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index 286f07b..c03dc27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -32,6 +32,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.provider.Settings;
+import android.service.notification.StatusBarNotification;
 import android.util.ArrayMap;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -45,9 +46,9 @@
 import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.AlphaOptimizedImageView;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.notification.row.NotificationGuts.GutsContent;
+import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
 import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
 
 import java.util.ArrayList;
@@ -260,15 +261,19 @@
             mSnoozeItem = createSnoozeItem(mContext);
         }
         mFeedbackItem = createFeedbackItem(mContext);
-        NotificationEntry entry = mParent.getEntry();
-        int personNotifType = mPeopleNotificationIdentifier.getPeopleNotificationType(entry);
+        int personNotifType = NotificationBundleUi.isEnabled()
+                ? mParent.getEntryAdapter().getPeopleNotificationType()
+                : mPeopleNotificationIdentifier.getPeopleNotificationType(mParent.getEntryLegacy());
+        StatusBarNotification sbn = NotificationBundleUi.isEnabled()
+                ? mParent.getEntryAdapter().getSbn()
+                : mParent.getEntryLegacy().getSbn();
         if (personNotifType == PeopleNotificationIdentifier.TYPE_PERSON) {
             mInfoItem = createPartialConversationItem(mContext);
         } else if (personNotifType >= PeopleNotificationIdentifier.TYPE_FULL_PERSON) {
             mInfoItem = createConversationItem(mContext);
         } else if (android.app.Flags.uiRichOngoing()
                 && Flags.permissionHelperUiRichOngoing()
-                && entry.getSbn().getNotification().isPromotedOngoing()) {
+                && sbn.getNotification().isPromotedOngoing()) {
             mInfoItem = createPromotedItem(mContext);
         } else {
             mInfoItem = createInfoItem(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
index 2f94d32..ae52db8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationRowContentBinderImpl.kt
@@ -541,7 +541,7 @@
             val ident: String = (sbn.packageName + "/0x" + Integer.toHexString(sbn.id))
             Log.e(TAG, "couldn't inflate view for notification $ident", e)
             callback?.handleInflationException(
-                if (NotificationBundleUi.isEnabled) entry else row.entry,
+                if (NotificationBundleUi.isEnabled) entry else row.entryLegacy,
                 InflationException("Couldn't inflate contentViews$e"),
             )
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
index 83897f5..cec0ae6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationSnooze.java
@@ -51,7 +51,6 @@
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.Flags;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
 import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
 import com.android.systemui.res.R;
@@ -477,7 +476,7 @@
 
     @Override
     public boolean handleCloseControls(boolean save, boolean force) {
-        if (Flags.notificationUndoGutsOnConfigChanged() && !save) {
+        if (!save) {
             // Undo changes and let the guts handle closing the view
             mSelectedOption = null;
             showSnoozeOptions(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
index 39ffdf2..01ee788 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PromotedNotificationInfo.java
@@ -68,6 +68,7 @@
             UiEventLogger uiEventLogger,
             boolean isDeviceProvisioned,
             boolean isNonblockable,
+            boolean isDismissable,
             boolean wasShownHighPriority,
             AssistantFeedbackController assistantFeedbackController,
             MetricsLogger metricsLogger, OnClickListener onCloseClick) throws RemoteException {
@@ -75,7 +76,7 @@
                 onUserInteractionCallback, channelEditorDialogController, packageDemotionInteractor,
                 pkg, notificationChannel,
                 entry, onSettingsClick, onAppSettingsClick, feedbackClickListener, uiEventLogger,
-                isDeviceProvisioned, isNonblockable, wasShownHighPriority,
+                isDeviceProvisioned, isNonblockable, isDismissable, wasShownHighPriority,
                 assistantFeedbackController, metricsLogger, onCloseClick);
 
         mNotificationManager = iNotificationManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt
index 08c1d71..03990bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationIconStyleProvider.kt
@@ -87,9 +87,15 @@
                 // It's not a system app at all.
                 return false
             } else {
-                // If there's no launch intent, it's probably a headless app.
-                val pm = context.packageManager
-                return (pm.getLaunchIntentForPackage(info.packageName) == null)
+                // If there's no launch intent, it's probably a headless app. Check for both
+                // direct-aware and -unaware intents; otherwise this will almost certainly fail
+                // for notifications posted before unlocking.
+                val packageLaunchIntent =
+                    context.packageManager.getLaunchIntentForPackage(
+                        info.packageName,
+                        /* includeDirectBootUnaware= */ true,
+                    )
+                return packageLaunchIntent == null
             }
         } else {
             // If for some reason we don't have the app info, we don't know; best assume it's
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt
index 4082a5b..2c5b9f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/icon/NotificationRowIconViewInflaterFactory.kt
@@ -61,7 +61,7 @@
         row: ExpandableNotificationRow,
         context: Context,
     ): NotificationIconProvider {
-        val sbn = if (NotificationBundleUi.isEnabled) row.entryAdapter?.sbn else  row.entry.sbn
+        val sbn = if (NotificationBundleUi.isEnabled) row.entryAdapter?.sbn else row.entryLegacy.sbn
         if (sbn == null) {
             return object : NotificationIconProvider {
                 override fun shouldShowAppIcon(): Boolean {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/ActivatableNotificationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/ActivatableNotificationViewBinder.kt
index 8984f2c..f0b5c36 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/ActivatableNotificationViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewbinder/ActivatableNotificationViewBinder.kt
@@ -50,15 +50,6 @@
                 view.registerListenersWhileAttached(touchHandler)
             }
         }
-        view.repeatWhenAttached {
-            repeatOnLifecycle(Lifecycle.State.STARTED) {
-                launch {
-                    viewModel.isBlurSupported.collect { supported ->
-                        view.setIsBlurSupported(supported)
-                    }
-                }
-            }
-        }
     }
 
     private suspend fun ActivatableNotificationView.registerListenersWhileAttached(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModel.kt
index 9a86ffb..2d2fd60 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModel.kt
@@ -17,7 +17,6 @@
 package com.android.systemui.statusbar.notification.row.ui.viewmodel
 
 import com.android.systemui.accessibility.domain.interactor.AccessibilityInteractor
-import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
 import dagger.Module
 import dagger.Provides
 import kotlinx.coroutines.flow.Flow
@@ -27,26 +26,21 @@
 interface ActivatableNotificationViewModel : ExpandableOutlineViewModel {
     /** Does the view react to touches? */
     val isTouchable: Flow<Boolean>
-    val isBlurSupported: Flow<Boolean>
 
     companion object {
         operator fun invoke(
             a11yInteractor: AccessibilityInteractor,
-            windowRootViewBlurInteractor: WindowRootViewBlurInteractor
         ): ActivatableNotificationViewModel =
-            ActivatableNotificationViewModelImpl(a11yInteractor, windowRootViewBlurInteractor)
+            ActivatableNotificationViewModelImpl(a11yInteractor)
     }
 }
 
 private class ActivatableNotificationViewModelImpl(
     a11yInteractor: AccessibilityInteractor,
-    windowRootViewBlurInteractor: WindowRootViewBlurInteractor,
 ) : ActivatableNotificationViewModel {
     override val isTouchable: Flow<Boolean> =
         // If a11y touch exploration is enabled, then the activatable view should ignore touches
         a11yInteractor.isTouchExplorationEnabled.map { !it }
-    override val isBlurSupported: Flow<Boolean> =
-        windowRootViewBlurInteractor.isBlurCurrentlySupported
 }
 
 @Module
@@ -54,7 +48,6 @@
     @Provides
     fun provideViewModel(
         a11yInteractor: AccessibilityInteractor,
-        windowRootViewBlurInteractor: WindowRootViewBlurInteractor
     ) =
-        ActivatableNotificationViewModel(a11yInteractor, windowRootViewBlurInteractor)
+        ActivatableNotificationViewModel(a11yInteractor)
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
index f492b25..e266dad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigPictureTemplateViewWrapper.java
@@ -50,7 +50,7 @@
         resolveViews();
         updateImageTag(NotificationBundleUi.isEnabled()
                 ? row.getEntryAdapter().getSbn()
-                : row.getEntry().getSbn());
+                : row.getEntryLegacy().getSbn());
     }
 
     private void resolveViews() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java
index dec674c..71bb9a2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationBigTextTemplateViewWrapper.java
@@ -47,7 +47,7 @@
         // the transformation types and we need to have our values set by then.
         resolveViews(NotificationBundleUi.isEnabled()
                 ? row.getEntryAdapter().getSbn()
-                : row.getEntry().getSbn());
+                : row.getEntryLegacy().getSbn());
         super.onContentUpdated(row);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
index 585051a..e6dadcd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationHeaderViewWrapper.java
@@ -225,7 +225,7 @@
         super.onContentUpdated(row);
         mIsLowPriority = NotificationBundleUi.isEnabled()
                 ? row.getEntryAdapter().isAmbient()
-                : row.getEntry().isAmbient();
+                : row.getEntryLegacy().isAmbient();
         mTransformLowPriorityTitle = !row.isChildInGroup() && !row.isSummaryWithChildren();
         ArraySet<View> previousViews = mTransformationHelper.getAllTransformingViews();
 
@@ -236,7 +236,7 @@
         updateCropToPaddingForImageViews();
         Notification n = NotificationBundleUi.isEnabled()
                 ? row.getEntryAdapter().getSbn().getNotification()
-                : row.getEntry().getSbn().getNotification();
+                : row.getEntryLegacy().getSbn().getNotification();
         mIcon.setTag(ImageTransformState.ICON_TAG, n.getSmallIcon());
 
         // We need to reset all views that are no longer transforming in case a view was previously
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index 99db1db..19321dc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -327,7 +327,7 @@
         // the transformation types and we need to have our values set by then.
         resolveTemplateViews(NotificationBundleUi.isEnabled()
                 ? row.getEntryAdapter().getSbn()
-                : row.getEntry().getSbn());
+                : row.getEntryLegacy().getSbn());
         super.onContentUpdated(row);
         // With the modern templates, a large icon visually overlaps the header, so we can't
         // hide the header, we must show it.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 64babb2..35e286c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -83,7 +83,7 @@
             if (NotificationBundleUi.isEnabled()
                     ? row.getEntryAdapter().getSbn().getNotification().isStyle(
                     Notification.DecoratedCustomViewStyle.class)
-                    : row.getEntry().getSbn().getNotification().isStyle(
+                    : row.getEntryLegacy().getSbn().getNotification().isStyle(
                     Notification.DecoratedCustomViewStyle.class)) {
                 return new NotificationDecoratedCustomViewWrapper(ctx, v, row);
             }
@@ -141,7 +141,7 @@
         // Apps targeting Q should fix their dark mode bugs.
         int targetSdk = NotificationBundleUi.isEnabled()
                 ? mRow.getEntryAdapter().getTargetSdk()
-                : mRow.getEntry().targetSdk;
+                : mRow.getEntryLegacy().targetSdk;
         if (targetSdk >= Build.VERSION_CODES.Q) {
             return false;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
index f663ea0..a75330b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewbinder/NotificationShelfViewBinder.kt
@@ -18,6 +18,7 @@
 
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.app.tracing.traceSection
+import com.android.systemui.Flags
 import com.android.systemui.plugins.FalsingManager
 import com.android.systemui.scene.shared.flag.SceneContainerFlag
 import com.android.systemui.statusbar.NotificationShelf
@@ -47,6 +48,10 @@
                 launch { viewModel.isAlignedToEnd.collect(::setAlignedToEnd) }
             }
 
+            if (Flags.notificationRowTransparency()) {
+                launch { viewModel.isBlurSupported.collect(shelf::setIsBlurSupported) }
+            }
+
             registerViewListenersWhileAttached(shelf, viewModel)
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt
index 96cdda6..9eb1ece 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModel.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.statusbar.NotificationShelf
 import com.android.systemui.statusbar.notification.row.ui.viewmodel.ActivatableNotificationViewModel
 import com.android.systemui.statusbar.notification.shelf.domain.interactor.NotificationShelfInteractor
+import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.flowOf
@@ -32,6 +33,7 @@
 @Inject
 constructor(
     private val interactor: NotificationShelfInteractor,
+    windowRootViewBlurInteractor: WindowRootViewBlurInteractor,
     activatableViewModel: ActivatableNotificationViewModel,
 ) : ActivatableNotificationViewModel by activatableViewModel {
     /** Is the shelf allowed to be clickable when it has content? */
@@ -51,6 +53,8 @@
         }
     }
 
+    val isBlurSupported: Flow<Boolean> = windowRootViewBlurInteractor.isBlurCurrentlySupported
+
     /** Notifies that the user has clicked the shelf. */
     fun onShelfClicked() {
         interactor.goToLockedShadeFromShelf()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index abfb862..fc7b24e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -696,10 +696,13 @@
         return mPulsing;
     }
 
+    public boolean isPulsing(String entryKey) {
+        boolean isHeadsUp = mHeadsUpRepository.isHeadsUpEntry(entryKey);
+        return mPulsing && isHeadsUp;
+    }
+
     public boolean isPulsing(NotificationEntry entry) {
-        boolean isHeadsUp = NotificationBundleUi.isEnabled()
-                ? mHeadsUpRepository.isHeadsUpEntry(entry.getKey())
-                : entry.isHeadsUpEntry();
+        boolean isHeadsUp = entry.isHeadsUpEntry();
         return mPulsing && isHeadsUp;
     }
 
@@ -750,7 +753,10 @@
      * @return whether a row is dozing and not pulsing right now
      */
     public boolean isDozingAndNotPulsing(ExpandableNotificationRow row) {
-        return isDozing() && !isPulsing(row.getEntry());
+        boolean isPulsing = NotificationBundleUi.isEnabled()
+                ? isPulsing(row.getKey())
+                : isPulsing(row.getEntryLegacy());
+        return isDozing() && !isPulsing;
     }
 
     /**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
index 3f05cef..7d489a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt
@@ -65,6 +65,13 @@
     val swipedRowMultiplier =
         MAGNETIC_TRANSLATION_MULTIPLIERS[MAGNETIC_TRANSLATION_MULTIPLIERS.size / 2]
 
+    /**
+     * An offset applied to input translation that increases on subsequent re-attachments of a
+     * detached magnetic view. This helps keep computations consistent when the drag gesture input
+     * and the swiped notification don't share the same origin point after a re-attaching animation.
+     */
+    private var translationOffset = 0f
+
     override fun onDensityChange(density: Float) {
         magneticDetachThreshold =
             density * MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP
@@ -78,6 +85,7 @@
         sectionsManager: NotificationSectionsManager,
     ) {
         if (currentState == State.IDLE) {
+            translationOffset = 0f
             updateMagneticAndRoundableTargets(swipingRow, stackScrollLayout, sectionsManager)
             currentState = State.TARGETS_SET
         } else {
@@ -127,35 +135,36 @@
 
         val canTargetBeDismissed =
             currentMagneticListeners.swipedListener()?.canRowBeDismissed() ?: false
+        val correctedTranslation = translation - translationOffset
         when (currentState) {
             State.IDLE -> {
                 logger.logMagneticRowTranslationNotSet(currentState, row.getLoggingKey())
                 return false
             }
             State.TARGETS_SET -> {
-                pullTargets(translation, canTargetBeDismissed)
+                pullTargets(correctedTranslation, canTargetBeDismissed)
                 currentState = State.PULLING
             }
             State.PULLING -> {
-                updateRoundness(translation)
+                updateRoundness(correctedTranslation)
                 if (canTargetBeDismissed) {
-                    pullDismissibleRow(translation)
+                    pullDismissibleRow(correctedTranslation)
                 } else {
-                    pullTargets(translation, canSwipedBeDismissed = false)
+                    pullTargets(correctedTranslation, canSwipedBeDismissed = false)
                 }
             }
             State.DETACHED -> {
-                translateDetachedRow(translation)
+                translateDetachedRow(correctedTranslation)
             }
         }
         return true
     }
 
-    private fun updateRoundness(translation: Float) {
+    private fun updateRoundness(translation: Float, animate: Boolean = false) {
         val normalizedTranslation = abs(swipedRowMultiplier * translation) / magneticDetachThreshold
         notificationRoundnessManager.setRoundnessForAffectedViews(
             /* roundness */ normalizedTranslation.coerceIn(0f, MAX_PRE_DETACH_ROUNDNESS),
-            /* animate */ false,
+            animate,
         )
     }
 
@@ -186,7 +195,7 @@
                 it.setMagneticTranslation(targetTranslation)
             }
         }
-        playPullHaptics(mappedTranslation = swipedRowMultiplier * translation, canSwipedBeDismissed)
+        // TODO(b/399633875): Enable pull haptics after we have a clear and polished haptics design
     }
 
     private fun playPullHaptics(mappedTranslation: Float, canSwipedBeDismissed: Boolean) {
@@ -241,9 +250,9 @@
         val targetTranslation = swipedRowMultiplier * translation
         val crossedThreshold = abs(targetTranslation) <= magneticAttachThreshold
         if (crossedThreshold) {
-            attachNeighbors(translation)
-            updateRoundness(translation)
-            currentMagneticListeners.swipedListener()?.let { attach(it, translation) }
+            translationOffset += translation
+            updateRoundness(translation = 0f, animate = true)
+            currentMagneticListeners.swipedListener()?.let { attach(it) }
             currentState = State.PULLING
         } else {
             val swiped = currentMagneticListeners.swipedListener()
@@ -251,30 +260,17 @@
         }
     }
 
-    private fun attachNeighbors(translation: Float) {
-        currentMagneticListeners.forEachIndexed { i, target ->
-            target?.let {
-                if (i != currentMagneticListeners.size / 2) {
-                    val multiplier = MAGNETIC_TRANSLATION_MULTIPLIERS[i]
-                    target.cancelMagneticAnimations()
-                    target.triggerMagneticForce(
-                        endTranslation = translation * multiplier,
-                        attachForce,
-                    )
-                }
-            }
-        }
-    }
-
-    private fun attach(listener: MagneticRowListener, toPosition: Float) {
+    private fun attach(listener: MagneticRowListener) {
         listener.cancelMagneticAnimations()
-        listener.triggerMagneticForce(toPosition, attachForce)
+        listener.triggerMagneticForce(endTranslation = 0f, attachForce)
         msdlPlayer.playToken(MSDLToken.SWIPE_THRESHOLD_INDICATOR)
     }
 
     override fun onMagneticInteractionEnd(row: ExpandableNotificationRow, velocity: Float?) {
+        translationOffset = 0f
         if (row.isSwipedTarget()) {
             when (currentState) {
+                State.TARGETS_SET -> currentState = State.IDLE
                 State.PULLING -> {
                     snapNeighborsBack(velocity)
                     currentState = State.IDLE
@@ -300,6 +296,7 @@
     override fun resetRoundness() = notificationRoundnessManager.clear()
 
     override fun reset() {
+        translationOffset = 0f
         currentMagneticListeners.forEach {
             it?.cancelMagneticAnimations()
             it?.cancelTranslationAnimations()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
index c3b9024..344dab4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticRowListener.kt
@@ -24,16 +24,12 @@
     /**
      * Set a translation due to a magnetic attachment.
      *
-     * The request to set a View's translation may occur while a magnetic animation is running. In
-     * such a case, the [trackEagerly] argument will determine if we decide to eagerly track the
-     * incoming translation or not. If true, the ongoing animation will update its target position
-     * and continue to animate only if the incoming translation produces a delta higher than a touch
-     * slop threshold. Otherwise, the animation will be cancelled and the View translation will be
-     * set directly. If [trackEagerly] is false, we respect the animation and only update the
-     * animated target.
+     * If a magnetic animation is running, [trackEagerly] decides if the new translation is applied
+     * immediately or if the animation finishes first. When applying the translation immediately,
+     * the change in translation must be greater than a touch slop threshold.
      *
      * @param[translation] Incoming gesture translation.
-     * @param[trackEagerly] Whether we eagerly track the incoming translation directly or not.
+     * @param[trackEagerly] Whether we eagerly track the incoming translation or not.
      */
     fun setMagneticTranslation(translation: Float, trackEagerly: Boolean = true)
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
index 315d37e..f9d8c8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java
@@ -444,7 +444,7 @@
         mIsConversation = isConversation;
         StatusBarNotification notification = NotificationBundleUi.isEnabled()
                 ? mContainingNotification.getEntryAdapter().getSbn()
-                : mContainingNotification.getEntry().getSbn();
+                : mContainingNotification.getEntryLegacy().getSbn();
         if (notification == null) {
             return;
         }
@@ -615,7 +615,7 @@
         RemoteViews header;
         StatusBarNotification notification = NotificationBundleUi.isEnabled()
                 ? mContainingNotification.getEntryAdapter().getSbn()
-                : mContainingNotification.getEntry().getSbn();
+                : mContainingNotification.getEntryLegacy().getSbn();
         if (notification == null) {
             return;
         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
index 96f0e6f..b5562ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
@@ -167,7 +167,7 @@
             view === promoHeaderView -> BUCKET_PROMO
             view is ExpandableNotificationRow ->
                 if (NotificationBundleUi.isEnabled) view.entryAdapter?.sectionBucket
-                else view.entry.bucket
+                else view.entryLegacy.bucket
             else -> null
         }
 
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 fbbf845..9fea750 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
@@ -64,6 +64,7 @@
 import android.util.IndentingPrintWriter;
 import android.util.Log;
 import android.util.MathUtils;
+import android.util.Pair;
 import android.view.DisplayCutout;
 import android.view.InputDevice;
 import android.view.LayoutInflater;
@@ -140,6 +141,7 @@
 import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
 import com.android.systemui.statusbar.policy.ScrollAdapter;
 import com.android.systemui.statusbar.policy.SplitShadeStateController;
+import com.android.systemui.statusbar.ui.SystemBarUtilsProxy;
 import com.android.systemui.util.Assert;
 import com.android.systemui.util.ColorUtilKt;
 import com.android.systemui.util.DumpUtilsKt;
@@ -1037,10 +1039,10 @@
                 }
                 int bucket = NotificationBundleUi.isEnabled()
                         ? row.getEntryAdapter().getSectionBucket()
-                        : row.getEntry().getBucket();
+                        : row.getEntryLegacy().getBucket();
                 boolean isAmbient = NotificationBundleUi.isEnabled()
                         ? row.getEntryAdapter().isAmbient()
-                        : row.getEntry().isAmbient();
+                        : row.getEntryLegacy().isAmbient();
                 currentIndex++;
                 boolean beforeSpeedBump;
                 if (mHighPriorityBeforeSpeedBump) {
@@ -1845,7 +1847,7 @@
         } else {
             if (row.isChildInGroup()) {
                 final NotificationEntry groupSummary =
-                        mGroupMembershipManager.getGroupSummary(row.getEntry());
+                        mGroupMembershipManager.getGroupSummary(row.getEntryLegacy());
                 if (groupSummary != null) {
                     row = groupSummary.getRow();
                 }
@@ -1998,16 +2000,16 @@
             if ((bottom - top >= mMinInteractionHeight || !requireMinHeight)
                     && touchY >= top && touchY <= bottom && touchX >= left && touchX <= right) {
                 if (slidingChild instanceof ExpandableNotificationRow row) {
-                    NotificationEntry entry = row.getEntry();
                     boolean isEntrySummaryForTopHun;
                     if (NotificationBundleUi.isEnabled()) {
                         isEntrySummaryForTopHun = Objects.equals(
                                 ((ExpandableNotificationRow) slidingChild).getNotificationParent(),
                                 mTopHeadsUpRow);
                     } else {
+                        NotificationEntry entry = row.getEntryLegacy();
                         isEntrySummaryForTopHun = mTopHeadsUpRow != null &&
-                                mGroupMembershipManager.getGroupSummary(mTopHeadsUpRow.getEntry())
-                                == entry;
+                                mGroupMembershipManager.getGroupSummary(
+                                        mTopHeadsUpRow.getEntryLegacy()) == entry;
                     }
                     if (!mIsExpanded && row.isHeadsUp() && row.isPinned()
                             && mTopHeadsUpRow != row
@@ -3007,7 +3009,7 @@
             ExpandableNotificationRow childRow = (ExpandableNotificationRow) child;
             return NotificationBundleUi.isEnabled()
                     ? mGroupMembershipManager.isChildInGroup(childRow.getEntryAdapter())
-                    : mGroupMembershipManager.isChildInGroup(childRow.getEntry());
+                    : mGroupMembershipManager.isChildInGroup(childRow.getEntryLegacy());
         }
         return false;
     }
@@ -6000,7 +6002,6 @@
      *                 LockscreenShadeTransitionController resets fraction to 0
      *                 where it remains until the next lockscreen-to-shade transition.
      */
-    @Override
     public void setFractionToShade(float fraction) {
         mAmbientState.setFractionToShade(fraction);
         updateContentHeight();  // Recompute stack height with different section gap.
@@ -6472,7 +6473,7 @@
             @SelectedRows int selection) {
         int bucket = NotificationBundleUi.isEnabled()
                 ? row.getEntryAdapter().getSectionBucket()
-                : row.getEntry().getBucket();
+                : row.getEntryLegacy().getBucket();
         switch (selection) {
             case ROWS_ALL:
                 return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index e6a25b7..612c19f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -655,11 +655,11 @@
                 public void onChildSnappedBack(View animView, float targetLeft) {
                     mView.onSwipeEnd();
                     if (animView instanceof ExpandableNotificationRow row) {
-                        if (row.isPinned() && !canChildBeDismissed(row)
-                                && NotificationBundleUi.isEnabled()
+                        boolean cannotFullScreen = NotificationBundleUi.isEnabled()
                                 ? !row.getEntryAdapter().isFullScreenCapable()
-                                : (row.getEntry().getSbn().getNotification().fullScreenIntent
-                                        == null)) {
+                                : (row.getEntryLegacy().getSbn().getNotification().fullScreenIntent
+                                        == null);
+                        if (row.isPinned() && !canChildBeDismissed(row) && cannotFullScreen) {
                             mHeadsUpManager.removeNotification(
                                     row.getKey(),
                                     /* removeImmediately= */ true,
@@ -1742,7 +1742,6 @@
      *                 they remain until the next lockscreen-to-shade transition.
      */
     public void setTransitionToFullShadeAmount(float fraction) {
-        SceneContainerFlag.assertInLegacyMode();
         mView.setFractionToShade(fraction);
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
index fcb63df..e5071d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
@@ -413,7 +413,7 @@
                         (currentNotification as? ExpandableNotificationRow)?.entryAdapter
                     counter.incrementForBucket(entryAdapter?.sectionBucket)
                 } else {
-                    val entry = (currentNotification as? ExpandableNotificationRow)?.entry
+                    val entry = (currentNotification as? ExpandableNotificationRow)?.entryLegacy
                     counter.incrementForBucket(entry?.bucket)
                 }
             }
@@ -470,7 +470,7 @@
             calculateGapAndDividerHeight(stack, previousView, current = view, visibleIndex)
         val canPeek = view is ExpandableNotificationRow &&
                 if (NotificationBundleUi.isEnabled) view.entryAdapter?.canPeek() == true
-                else view.entry.isStickyAndNotDemoted
+                else view.entryLegacy.isStickyAndNotDemoted
 
         var size =
             if (onLockscreen) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
index 33b9478..5105e55 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelper.java
@@ -33,7 +33,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.jank.InteractionJankMonitor;
-import com.android.systemui.Flags;
 import com.android.systemui.SwipeHelper;
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FeatureFlags;
@@ -192,11 +191,6 @@
     @Override
     public boolean handleUpEvent(MotionEvent ev, View animView, float velocity,
             float translation) {
-        if (Flags.magneticNotificationSwipes()
-                && (mCallback.isMagneticViewDetached(animView) || swipedFastEnough())) {
-            dismiss(animView, velocity);
-            return true;
-        }
         NotificationMenuRowPlugin menuRow = getCurrentMenuRow();
         if (menuRow != null) {
             menuRow.onTouchEnd();
@@ -261,12 +255,13 @@
         int menuSnapTarget = menuRow.getMenuSnapTarget();
         boolean isNonFalseMenuRevealingGesture =
                 isMenuRevealingGestureAwayFromMenu && !isFalseGesture();
+        boolean isMagneticViewDetached = mCallback.isMagneticViewDetached(animView);
         if ((isNonDismissGestureTowardsMenu || isNonFalseMenuRevealingGesture)
                 && menuSnapTarget != 0) {
             // Menu has not been snapped to previously and this is menu revealing gesture
             snapOpen(animView, menuSnapTarget, velocity);
             menuRow.onSnapOpen();
-        } else if (isDismissGesture && !gestureTowardsMenu) {
+        } else if (isDismissGesture && (!gestureTowardsMenu || isMagneticViewDetached)) {
             dismiss(animView, velocity);
             menuRow.onDismiss();
         } else {
@@ -278,6 +273,7 @@
     private void handleSwipeFromOpenState(MotionEvent ev, View animView, float velocity,
             NotificationMenuRowPlugin menuRow) {
         boolean isDismissGesture = isDismissGesture(ev);
+        boolean isMagneticViewDetached = mCallback.isMagneticViewDetached(animView);
 
         final boolean withinSnapMenuThreshold =
                 menuRow.isWithinSnapMenuThreshold();
@@ -286,7 +282,7 @@
             // Haven't moved enough to unsnap from the menu
             menuRow.onSnapOpen();
             snapOpen(animView, menuRow.getMenuSnapTarget(), velocity);
-        } else if (isDismissGesture && !menuRow.shouldSnapBack()) {
+        } else if (isDismissGesture && (!menuRow.shouldSnapBack() || isMagneticViewDetached)) {
             // Only dismiss if we're not moving towards the menu
             dismiss(animView, velocity);
             menuRow.onDismiss();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 2821822..da14423 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -927,7 +927,7 @@
                             childState.headsUpIsVisible, row.showingPulsing(),
                             ambientState.isOnKeyguard(), NotificationBundleUi.isEnabled()
                                     ? row.getEntryAdapter().canPeek()
-                                    : row.getEntry().isStickyAndNotDemoted())) {
+                                    : row.getEntryLegacy().isStickyAndNotDemoted())) {
                         // the height of this child before clamping it to the top
                         float unmodifiedChildHeight = childState.height;
                         clampHunToTop(
@@ -984,7 +984,7 @@
                             childState.headsUpIsVisible, row.showingPulsing(),
                             ambientState.isOnKeyguard(), NotificationBundleUi.isEnabled()
                                     ? row.getEntryAdapter().canPeek()
-                                    : row.getEntry().isStickyAndNotDemoted())) {
+                                    : row.getEntryLegacy().isStickyAndNotDemoted())) {
                         // Ensure that the heads up is always visible even when scrolled off.
                         // NSSL y starts at top of screen in non-split-shade, but below the qs
                         // offset
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt
index ac89f3a..9c855e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/view/NotificationScrollView.kt
@@ -107,9 +107,6 @@
     /** sets the current expand fraction */
     fun setExpandFraction(expandFraction: Float)
 
-    /** Sets the fraction of the LockScreen -> Shade transition. */
-    fun setFractionToShade(fraction: Float)
-
     /** sets the current QS expand fraction */
     fun setQsExpandFraction(expandFraction: Float)
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
index 40739b3..653344a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewbinder/NotificationScrollViewBinder.kt
@@ -95,11 +95,6 @@
                     view.setExpandFraction(it.coerceIn(0f, 1f))
                 }
             }
-            launch {
-                viewModel.lockScreenToShadeTransitionProgress.collectTraced {
-                    view.setFractionToShade(it.coerceIn(0f, 1f))
-                }
-            }
             launch { viewModel.qsExpandFraction.collectTraced { view.setQsExpandFraction(it) } }
             launch { viewModel.blurRadius(maxBlurRadius).collect(view::setBlurRadius) }
             launch {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
index 940b2e5..c1aa5f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/NotificationScrollViewModel.kt
@@ -207,44 +207,6 @@
     val qsExpandFraction: Flow<Float> =
         shadeInteractor.qsExpansion.dumpWhileCollecting("qsExpandFraction")
 
-    /**
-     * Fraction of the LockScreen -> Shade transition. 0..1 while the transition in progress, and
-     * snaps back to 0 when it is Idle.
-     */
-    val lockScreenToShadeTransitionProgress: Flow<Float> =
-        combine(
-                shadeInteractor.shadeExpansion,
-                shadeModeInteractor.shadeMode,
-                sceneInteractor.transitionState,
-            ) { shadeExpansion, _, transitionState ->
-                when (transitionState) {
-                    is Idle -> 0f
-                    is ChangeScene ->
-                        if (
-                            transitionState.isTransitioning(
-                                from = Scenes.Lockscreen,
-                                to = Scenes.Shade,
-                            )
-                        ) {
-                            shadeExpansion
-                        } else {
-                            0f
-                        }
-
-                    is Transition.OverlayTransition ->
-                        if (
-                            transitionState.currentScene == Scenes.Lockscreen &&
-                                transitionState.isTransitioning(to = Overlays.NotificationsShade)
-                        ) {
-                            shadeExpansion
-                        } else {
-                            0f
-                        }
-                }
-            }
-            .distinctUntilChanged()
-            .dumpWhileCollecting("lockScreenToShadeTransitionProgress")
-
     val isOccluded: Flow<Boolean> =
         bouncerInteractor.bouncerExpansion
             .map { it == 1f }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
index bc53314..afe7971 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ui/viewbinder/HeadsUpNotificationViewBinder.kt
@@ -60,7 +60,7 @@
                         if (animationsEnabled) {
                             added.forEach { key ->
                                 val row = obtainView(key)
-                                val hasStatusBarChip = statusBarChips.contains(row.entry.key)
+                                val hasStatusBarChip = statusBarChips.contains(row.key)
                                 parentView.generateHeadsUpAnimation(
                                     row,
                                     /* isHeadsUp = */ true,
@@ -69,7 +69,7 @@
                             }
                             removed.forEach { key ->
                                 val row = obtainView(key)
-                                val hasStatusBarChip = statusBarChips.contains(row.entry.key)
+                                val hasStatusBarChip = statusBarChips.contains(row.key)
                                 if (!parentView.isBeingDragged()) {
                                     parentView.generateHeadsUpAnimation(
                                         row,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
index a4ee4ad..9d9f01b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -31,11 +31,11 @@
 
 import static com.android.systemui.Dependency.TIME_TICK_HANDLER_NAME;
 import static com.android.systemui.Flags.keyboardShortcutHelperRewrite;
-import static com.android.systemui.Flags.lightRevealMigration;
 import static com.android.systemui.Flags.relockWithPowerButtonImmediately;
 import static com.android.systemui.Flags.statusBarSignalPolicyRefactor;
 import static com.android.systemui.charging.WirelessChargingAnimation.UNKNOWN_BATTERY_LEVEL;
 import static com.android.systemui.flags.Flags.SHORTCUT_LIST_SEARCH_LAYOUT;
+import static com.android.systemui.shared.Flags.ambientAod;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 
 import android.annotation.Nullable;
@@ -980,7 +980,7 @@
 
             @Override
             public void onKeyguardGoingAwayChanged() {
-                if (lightRevealMigration()) {
+                if (ambientAod()) {
                     // This code path is not used if the KeyguardTransitionRepository is managing
                     // the lightreveal scrim.
                     return;
@@ -2446,7 +2446,7 @@
             return;
         }
 
-        if (lightRevealMigration()) {
+        if (ambientAod()) {
             return;
         }
 
@@ -3103,7 +3103,7 @@
 
                 @Override
                 public void onDozeAmountChanged(float linear, float eased) {
-                    if (!lightRevealMigration()
+                    if (!ambientAod()
                             && !(mLightRevealScrim.getRevealEffect() instanceof CircleReveal)) {
                         // If wakeAndUnlocking, this is handled in AuthRippleInteractor
                         if (!mBiometricUnlockController.isWakeAndUnlock()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
index 36193bd..3c14462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewController.java
@@ -49,6 +49,7 @@
 import com.android.keyguard.KeyguardUpdateMonitor;
 import com.android.keyguard.KeyguardUpdateMonitorCallback;
 import com.android.keyguard.logging.KeyguardLogger;
+import com.android.systemui.Flags;
 import com.android.systemui.battery.BatteryMeterViewController;
 import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -475,12 +476,14 @@
                 UserHandle.USER_ALL);
         updateUserSwitcher();
         onThemeChanged();
-        collectFlow(mView, mCommunalSceneInteractor.isCommunalVisible(), mCommunalConsumer,
-                mCoroutineDispatcher);
-        collectFlow(mView, mLockscreenToHubTransitionViewModel.getStatusBarAlpha(),
-                mToGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher);
-        collectFlow(mView, mHubToLockscreenTransitionViewModel.getStatusBarAlpha(),
-                mFromGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher);
+        if (!Flags.glanceableHubV2()) {
+            collectFlow(mView, mCommunalSceneInteractor.isCommunalVisible(), mCommunalConsumer,
+                    mCoroutineDispatcher);
+            collectFlow(mView, mLockscreenToHubTransitionViewModel.getStatusBarAlpha(),
+                    mToGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher);
+            collectFlow(mView, mHubToLockscreenTransitionViewModel.getStatusBarAlpha(),
+                    mFromGlanceableHubStatusBarAlphaConsumer, mCoroutineDispatcher);
+        }
         if (NewStatusBarIcons.isEnabled()) {
             ComposeView batteryComposeView = new ComposeView(mContext);
             UnifiedBatteryViewBinder.bind(
@@ -645,7 +648,7 @@
                         && !mDozing
                         && !hideForBypass
                         && !mDisableStateTracker.isDisabled()
-                        && (!mCommunalShowing || mExplicitAlpha != -1)
+                        && (Flags.glanceableHubV2() || (!mCommunalShowing || mExplicitAlpha != -1))
                         ? View.VISIBLE : View.INVISIBLE;
 
         updateViewState(newAlpha, newVisibility);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 74a42ef..f3d7202 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -29,6 +29,7 @@
 import android.animation.AnimatorListenerAdapter;
 import android.animation.ValueAnimator;
 import android.annotation.IntDef;
+import android.content.Context;
 import android.graphics.Color;
 import android.os.Handler;
 import android.util.Log;
@@ -226,6 +227,8 @@
 
     private ScrimState mState = ScrimState.UNINITIALIZED;
 
+    private Context mContext;
+
     private ScrimView mScrimInFront;
     private ScrimView mNotificationsScrim;
     private ScrimView mScrimBehind;
@@ -365,7 +368,9 @@
             @Main CoroutineDispatcher mainDispatcher,
             LargeScreenShadeInterpolator largeScreenShadeInterpolator,
             BlurConfig blurConfig,
+            @Main Context context,
             Lazy<WindowRootViewBlurInteractor> windowRootViewBlurInteractor) {
+        mContext = context;
         mScrimStateListener = lightBarController::setScrimState;
         mLargeScreenShadeInterpolator = largeScreenShadeInterpolator;
         mBlurConfig = blurConfig;
@@ -1627,16 +1632,16 @@
 
     private void updateThemeColors() {
         if (mScrimBehind == null) return;
-        int background = mScrimBehind.getContext().getColor(
+        int background = mContext.getColor(
                 com.android.internal.R.color.materialColorSurfaceDim);
-        int accent = mScrimBehind.getContext().getColor(
+        int accent = mContext.getColor(
                 com.android.internal.R.color.materialColorPrimary);
         mColors.setMainColor(background);
         mColors.setSecondaryColor(accent);
         final boolean isBackgroundLight = !ContrastColorUtil.isColorDark(background);
         mColors.setSupportsDarkText(isBackgroundLight);
 
-        int surface = mScrimBehind.getContext().getColor(
+        int surface = mContext.getColor(
                 com.android.internal.R.color.materialColorSurface);
         for (ScrimState state : ScrimState.values()) {
             state.setSurfaceColor(surface);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index 05a46cd..8389aab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -219,7 +219,7 @@
                     if (NotificationBundleUi.isEnabled()) {
                         mGroupExpansionManager.toggleGroupExpansion(row.getEntryAdapter());
                     } else {
-                        mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
+                        mGroupExpansionManager.toggleGroupExpansion(row.getEntryLegacy());
                     }
                 } else if (!row.isChildInGroup()) {
                     final boolean expandNotification;
@@ -241,7 +241,7 @@
                     if (NotificationBundleUi.isEnabled()) {
                         mGroupExpansionManager.toggleGroupExpansion(row.getEntryAdapter());
                     } else {
-                        mGroupExpansionManager.toggleGroupExpansion(row.getEntry());
+                        mGroupExpansionManager.toggleGroupExpansion(row.getEntryLegacy());
                     }
                 }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
index 0d43789..8890db3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
@@ -18,7 +18,6 @@
 import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF
 import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD
 import com.android.systemui.DejankUtils
-import com.android.systemui.Flags.lightRevealMigration
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.keyguard.KeyguardViewMediator
@@ -26,6 +25,7 @@
 import com.android.systemui.shade.ShadeViewController
 import com.android.systemui.shade.domain.interactor.PanelExpansionInteractor
 import com.android.systemui.shade.domain.interactor.ShadeLockscreenInteractor
+import com.android.systemui.shared.Flags.ambientAod
 import com.android.systemui.statusbar.CircleReveal
 import com.android.systemui.statusbar.LightRevealScrim
 import com.android.systemui.statusbar.NotificationShadeWindowController
@@ -100,7 +100,7 @@
             duration = LIGHT_REVEAL_ANIMATION_DURATION
             interpolator = Interpolators.LINEAR
             addUpdateListener {
-                if (lightRevealMigration()) return@addUpdateListener
+                if (ambientAod()) return@addUpdateListener
                 if (lightRevealScrim.revealEffect !is CircleReveal) {
                     lightRevealScrim.revealAmount = it.animatedValue as Float
                 }
@@ -116,7 +116,7 @@
             addListener(
                 object : AnimatorListenerAdapter() {
                     override fun onAnimationCancel(animation: Animator) {
-                        if (lightRevealMigration()) return
+                        if (ambientAod()) return
                         if (lightRevealScrim.revealEffect !is CircleReveal) {
                             lightRevealScrim.revealAmount = 1f
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index db1977b..93489e9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -49,6 +49,7 @@
 import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorKairosImpl
 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileUiAdapter
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModelKairos
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxyImpl
 import com.android.systemui.statusbar.pipeline.mobile.util.SubscriptionManagerProxy
@@ -94,6 +95,7 @@
             MobileRepositorySwitcherKairos.Module::class,
             MobileConnectionsRepositoryKairosImpl.Module::class,
             MobileIconsInteractorKairosImpl.Module::class,
+            MobileIconsViewModelKairos.Module::class,
             MobileConnectionRepositoryKairosFactoryImpl.Module::class,
             MobileConnectionsRepositoryKairosAdapter.Module::class,
             MobileIconsInteractorKairosAdapter.Module::class,
@@ -217,6 +219,7 @@
         fun provideFirstMobileSubShowingNetworkTypeIconProvider(
             mobileIconsViewModel: MobileIconsViewModel
         ): Supplier<Flow<Boolean>> {
+            // TODO: kairos-ify
             return Supplier<Flow<Boolean>> {
                 mobileIconsViewModel.firstMobileSubShowingNetworkTypeIcon
             }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt
index 1a8ca95..f4afc24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/FullMobileConnectionRepositoryKairos.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.kairos.BuildSpec
 import com.android.systemui.kairos.ExperimentalKairosApi
 import com.android.systemui.kairos.State
+import com.android.systemui.kairos.combine
 import com.android.systemui.kairos.flatMap
 import com.android.systemui.kairosBuilder
 import com.android.systemui.log.table.TableLogBuffer
@@ -55,9 +56,15 @@
     @Assisted private val isCarrierMerged: State<Boolean>,
 ) : MobileConnectionRepositoryKairos, KairosBuilder by kairosBuilder() {
 
+    private var dumpCache: DumpCache? = null
+
     init {
         onActivated {
             logDiffsForTable(isCarrierMerged, tableLogBuffer, columnName = "isCarrierMerged")
+            combine(isCarrierMerged, activeRepo) { isCarrierMerged, activeRepo ->
+                    DumpCache(isCarrierMerged, activeRepo)
+                }
+                .observe { dumpCache = it }
         }
     }
 
@@ -198,13 +205,6 @@
 
     override val isInEcmMode: State<Boolean> = activeRepo.flatMap { it.isInEcmMode }
 
-    private var dumpCache: DumpCache? = null
-
-    private data class DumpCache(
-        val isCarrierMerged: Boolean,
-        val activeRepo: MobileConnectionRepositoryKairos,
-    )
-
     fun dump(pw: PrintWriter) {
         val cache = dumpCache ?: return
         val ipw = IndentingPrintWriter(pw, "  ")
@@ -227,6 +227,11 @@
         ipw.decreaseIndent()
     }
 
+    private data class DumpCache(
+        val isCarrierMerged: Boolean,
+        val activeRepo: MobileConnectionRepositoryKairos,
+    )
+
     @AssistedFactory
     interface Factory {
         fun create(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt
index e468159..e6c2921 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryKairosImpl.kt
@@ -131,6 +131,8 @@
     private val mobileRepoFactory: Lazy<ConnectionRepoFactory>,
 ) : MobileConnectionsRepositoryKairos, Dumpable, KairosBuilder by kairosBuilder() {
 
+    private var dumpCache: DumpCache? = null
+
     init {
         dumpManager.registerNormalDumpable("MobileConnectionsRepositoryKairos", this)
     }
@@ -253,6 +255,7 @@
                 .asIncremental()
                 .mapValues { (subId, sub) -> mobileRepoFactory.get().create(subId) }
                 .applyLatestSpecForKey()
+                .apply { observe { dumpCache = DumpCache(it) } }
         }
 
     private val telephonyManagerState: State<Pair<Int?, Set<Int>>> = buildState {
@@ -479,10 +482,6 @@
             profileClass = profileClass,
         )
 
-    private var dumpCache: DumpCache? = null
-
-    private data class DumpCache(val repos: Map<Int, FullMobileConnectionRepositoryKairos>)
-
     override fun dump(pw: PrintWriter, args: Array<String>) {
         val cache = dumpCache ?: return
         val ipw = IndentingPrintWriter(pw, " ")
@@ -494,10 +493,16 @@
 
         ipw.println("Connections (${cache.repos.size} total):")
         ipw.increaseIndent()
-        cache.repos.values.forEach { it.dump(ipw) }
+        cache.repos.values.forEach {
+            if (it is FullMobileConnectionRepositoryKairos) {
+                it.dump(ipw)
+            }
+        }
         ipw.decreaseIndent()
     }
 
+    private data class DumpCache(val repos: Map<Int, MobileConnectionRepositoryKairos>)
+
     fun interface ConnectionRepoFactory {
         fun create(subId: Int): BuildSpec<MobileConnectionRepositoryKairos>
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
index 0eabb4ec..af4e61a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractor.kt
@@ -61,31 +61,31 @@
      * consider this connection to be serving data, and thus want to show a network type icon, when
      * data is connected. Other data connection states would typically cause us not to show the icon
      */
-    val isDataConnected: StateFlow<Boolean>
+    val isDataConnected: Flow<Boolean>
 
     /** True if we consider this connection to be in service, i.e. can make calls */
-    val isInService: StateFlow<Boolean>
+    val isInService: Flow<Boolean>
 
     /** True if this connection is emergency only */
-    val isEmergencyOnly: StateFlow<Boolean>
+    val isEmergencyOnly: Flow<Boolean>
 
     /** Observable for the data enabled state of this connection */
-    val isDataEnabled: StateFlow<Boolean>
+    val isDataEnabled: Flow<Boolean>
 
     /** True if the RAT icon should always be displayed and false otherwise. */
-    val alwaysShowDataRatIcon: StateFlow<Boolean>
+    val alwaysShowDataRatIcon: Flow<Boolean>
 
     /** Canonical representation of the current mobile signal strength as a triangle. */
-    val signalLevelIcon: StateFlow<SignalIconModel>
+    val signalLevelIcon: Flow<SignalIconModel>
 
     /** Observable for RAT type (network type) indicator */
-    val networkTypeIconGroup: StateFlow<NetworkTypeIconModel>
+    val networkTypeIconGroup: Flow<NetworkTypeIconModel>
 
     /** Whether or not to show the slice attribution */
-    val showSliceAttribution: StateFlow<Boolean>
+    val showSliceAttribution: Flow<Boolean>
 
     /** True if this connection is satellite-based */
-    val isNonTerrestrial: StateFlow<Boolean>
+    val isNonTerrestrial: Flow<Boolean>
 
     /**
      * Provider name for this network connection. The name can be one of 3 values:
@@ -95,7 +95,7 @@
      *    override in [connectionInfo.operatorAlphaShort], a value that is derived from
      *    [ServiceState]
      */
-    val networkName: StateFlow<NetworkNameModel>
+    val networkName: Flow<NetworkNameModel>
 
     /**
      * Provider name for this network connection. The name can be one of 3 values:
@@ -108,26 +108,26 @@
      * TODO(b/296600321): De-duplicate this field with [networkName] after determining the data
      *   provided is identical
      */
-    val carrierName: StateFlow<String>
+    val carrierName: Flow<String>
 
     /** True if there is only one active subscription. */
-    val isSingleCarrier: StateFlow<Boolean>
+    val isSingleCarrier: Flow<Boolean>
 
     /**
      * True if this connection is considered roaming. The roaming bit can come from [ServiceState],
      * or directly from the telephony manager's CDMA ERI number value. Note that we don't consider a
      * connection to be roaming while carrier network change is active
      */
-    val isRoaming: StateFlow<Boolean>
+    val isRoaming: Flow<Boolean>
 
     /** See [MobileIconsInteractor.isForceHidden]. */
     val isForceHidden: Flow<Boolean>
 
     /** See [MobileConnectionRepository.isAllowedDuringAirplaneMode]. */
-    val isAllowedDuringAirplaneMode: StateFlow<Boolean>
+    val isAllowedDuringAirplaneMode: Flow<Boolean>
 
     /** True when in carrier network change mode */
-    val carrierNetworkChangeActive: StateFlow<Boolean>
+    val carrierNetworkChangeActive: Flow<Boolean>
 }
 
 /** Interactor for a single mobile connection. This connection _should_ have one subscription ID */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt
index a939959..3d58f84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconInteractorKairos.kt
@@ -48,6 +48,8 @@
     /** The table log created for this connection */
     val tableLogBuffer: TableLogBuffer
 
+    val subscriptionId: Int
+
     /** The current mobile data activity */
     val activity: State<DataActivityModel>
 
@@ -146,6 +148,9 @@
     private val carrierIdOverrides: MobileIconCarrierIdOverrides =
         MobileIconCarrierIdOverridesImpl(),
 ) : MobileIconInteractorKairos, KairosBuilder by kairosBuilder() {
+    override val subscriptionId: Int
+        get() = connectionRepository.subId
+
     override val tableLogBuffer: TableLogBuffer
         get() = connectionRepository.tableLogBuffer
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorKairosAdapter.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorKairosAdapter.kt
index 87877b3..6b9c537 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorKairosAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/domain/interactor/MobileIconsInteractorKairosAdapter.kt
@@ -32,11 +32,20 @@
 import com.android.systemui.kairos.mapValues
 import com.android.systemui.kairos.toColdConflatedFlow
 import com.android.systemui.kairosBuilder
+import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.log.table.TableLogBufferFactory
+import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
 import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
 import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepositoryKairos
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.MOBILE_CONNECTION_BUFFER_SIZE
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.FullMobileConnectionRepository.Factory.Companion.tableBufferLogName
+import com.android.systemui.statusbar.pipeline.mobile.domain.model.NetworkTypeIconModel
+import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
 import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
+import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
 import com.android.systemui.statusbar.policy.data.repository.UserSetupRepository
+import com.android.systemui.utils.coroutines.flow.flatMapLatestConflated
 import dagger.Provides
 import dagger.multibindings.ElementsIntoSet
 import javax.inject.Inject
@@ -45,6 +54,8 @@
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.stateIn
 
 @ExperimentalKairosApi
@@ -60,6 +71,7 @@
     context: Context,
     mobileMappingsProxy: MobileMappingsProxy,
     private val userSetupRepo: UserSetupRepository,
+    private val logFactory: TableLogBufferFactory,
 ) : MobileIconsInteractor, KairosBuilder by kairosBuilder() {
 
     private val interactorsBySubIdK = buildIncremental {
@@ -158,7 +170,37 @@
         get() = repo.isDeviceEmergencyCallCapable
 
     override fun getMobileConnectionInteractorForSubId(subId: Int): MobileIconInteractor =
-        interactorsBySubId.value[subId] ?: error("Unknown subscription id: $subId")
+        object : MobileIconInteractor {
+            override val tableLogBuffer: TableLogBuffer =
+                logFactory.getOrCreate(tableBufferLogName(subId), MOBILE_CONNECTION_BUFFER_SIZE)
+            override val activity: Flow<DataActivityModel> = latest { activity }
+            override val mobileIsDefault: Flow<Boolean> = latest { mobileIsDefault }
+            override val isDataConnected: Flow<Boolean> = latest { isDataConnected }
+            override val isInService: Flow<Boolean> = latest { isInService }
+            override val isEmergencyOnly: Flow<Boolean> = latest { isEmergencyOnly }
+            override val isDataEnabled: Flow<Boolean> = latest { isDataEnabled }
+            override val alwaysShowDataRatIcon: Flow<Boolean> = latest { alwaysShowDataRatIcon }
+            override val signalLevelIcon: Flow<SignalIconModel> = latest { signalLevelIcon }
+            override val networkTypeIconGroup: Flow<NetworkTypeIconModel> = latest {
+                networkTypeIconGroup
+            }
+            override val showSliceAttribution: Flow<Boolean> = latest { showSliceAttribution }
+            override val isNonTerrestrial: Flow<Boolean> = latest { isNonTerrestrial }
+            override val networkName: Flow<NetworkNameModel> = latest { networkName }
+            override val carrierName: Flow<String> = latest { carrierName }
+            override val isSingleCarrier: Flow<Boolean> = latest { isSingleCarrier }
+            override val isRoaming: Flow<Boolean> = latest { isRoaming }
+            override val isForceHidden: Flow<Boolean> = latest { isForceHidden }
+            override val isAllowedDuringAirplaneMode: Flow<Boolean> = latest {
+                isAllowedDuringAirplaneMode
+            }
+            override val carrierNetworkChangeActive: Flow<Boolean> = latest {
+                carrierNetworkChangeActive
+            }
+
+            private fun <T> latest(block: MobileIconInteractor.() -> Flow<T>): Flow<T> =
+                interactorsBySubId.flatMapLatestConflated { it[subId]?.block() ?: emptyFlow() }
+        }
 
     @dagger.Module
     object Module {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt
index fa9fa4c..32ebe88 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/StackedMobileBindableIcon.kt
@@ -24,7 +24,7 @@
 import com.android.systemui.statusbar.pipeline.icons.shared.model.ModernStatusBarViewCreator
 import com.android.systemui.statusbar.pipeline.mobile.ui.binder.StackedMobileIconBinder
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
-import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModelImpl
 import com.android.systemui.statusbar.pipeline.shared.ui.view.SingleBindableStatusBarComposeIconView
 import javax.inject.Inject
 
@@ -34,7 +34,7 @@
 constructor(
     context: Context,
     mobileIconsViewModel: MobileIconsViewModel,
-    viewModelFactory: StackedMobileIconViewModel.Factory,
+    viewModelFactory: StackedMobileIconViewModelImpl.Factory,
 ) : BindableIcon {
     override val slot: String =
         context.getString(com.android.internal.R.string.status_bar_stacked_mobile)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt
index c9fc53e..fef5bfe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/binder/StackedMobileIconBinder.kt
@@ -25,7 +25,7 @@
 import com.android.systemui.lifecycle.rememberViewModel
 import com.android.systemui.lifecycle.repeatWhenAttached
 import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.MobileIconsViewModel
-import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModelImpl
 import com.android.systemui.statusbar.pipeline.shared.ui.binder.ModernStatusBarViewBinding
 import com.android.systemui.statusbar.pipeline.shared.ui.composable.StackedMobileIcon
 import com.android.systemui.statusbar.pipeline.shared.ui.view.SingleBindableStatusBarComposeIconView
@@ -34,7 +34,7 @@
     fun bind(
         view: SingleBindableStatusBarComposeIconView,
         mobileIconsViewModel: MobileIconsViewModel,
-        viewModelFactory: StackedMobileIconViewModel.Factory,
+        viewModelFactory: StackedMobileIconViewModelImpl.Factory,
     ): ModernStatusBarViewBinding {
         return SingleBindableStatusBarComposeIconView.withDefaultBinding(
             view = view,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt
index fce8c85..d2e3a14 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/LocationBasedMobileViewModelKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,14 +17,12 @@
 package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
 
 import android.graphics.Color
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.combine
 import com.android.systemui.statusbar.phone.StatusBarLocation
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
 import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.stateIn
 
 /**
  * A view model for an individual mobile icon that embeds the notion of a [StatusBarLocation]. This
@@ -35,45 +33,47 @@
  * @property location the [StatusBarLocation] of this VM.
  * @property verboseLogger an optional logger to log extremely verbose view updates.
  */
+@ExperimentalKairosApi
 abstract class LocationBasedMobileViewModelKairos(
-    val commonImpl: MobileIconViewModelCommonKairos,
+    val commonImpl: MobileIconViewModelKairosCommon,
     val location: StatusBarLocation,
     val verboseLogger: VerboseMobileViewLogger?,
-) : MobileIconViewModelCommonKairos by commonImpl {
+) : MobileIconViewModelKairosCommon by commonImpl {
     val defaultColor: Int = Color.WHITE
 
     companion object {
         fun viewModelForLocation(
-            commonImpl: MobileIconViewModelCommon,
-            interactor: MobileIconInteractor,
+            commonImpl: MobileIconViewModelKairosCommon,
+            interactor: MobileIconInteractorKairos,
             verboseMobileViewLogger: VerboseMobileViewLogger,
             location: StatusBarLocation,
-            scope: CoroutineScope,
-        ): LocationBasedMobileViewModel =
+        ): LocationBasedMobileViewModelKairos =
             when (location) {
                 StatusBarLocation.HOME ->
-                    HomeMobileIconViewModel(commonImpl, verboseMobileViewLogger)
-                StatusBarLocation.KEYGUARD -> KeyguardMobileIconViewModel(commonImpl)
-                StatusBarLocation.QS -> QsMobileIconViewModel(commonImpl)
+                    HomeMobileIconViewModelKairos(commonImpl, verboseMobileViewLogger)
+                StatusBarLocation.KEYGUARD -> KeyguardMobileIconViewModelKairos(commonImpl)
+                StatusBarLocation.QS -> QsMobileIconViewModelKairos(commonImpl)
                 StatusBarLocation.SHADE_CARRIER_GROUP ->
-                    ShadeCarrierGroupMobileIconViewModel(commonImpl, interactor, scope)
+                    ShadeCarrierGroupMobileIconViewModelKairos(commonImpl, interactor)
             }
     }
 }
 
+@ExperimentalKairosApi
 class HomeMobileIconViewModelKairos(
-    commonImpl: MobileIconViewModelCommonKairos,
+    commonImpl: MobileIconViewModelKairosCommon,
     verboseMobileViewLogger: VerboseMobileViewLogger,
 ) :
-    MobileIconViewModelCommonKairos,
+    MobileIconViewModelKairosCommon,
     LocationBasedMobileViewModelKairos(
         commonImpl,
         location = StatusBarLocation.HOME,
         verboseMobileViewLogger,
     )
 
-class QsMobileIconViewModelKairos(commonImpl: MobileIconViewModelCommonKairos) :
-    MobileIconViewModelCommonKairos,
+@ExperimentalKairosApi
+class QsMobileIconViewModelKairos(commonImpl: MobileIconViewModelKairosCommon) :
+    MobileIconViewModelKairosCommon,
     LocationBasedMobileViewModelKairos(
         commonImpl,
         location = StatusBarLocation.QS,
@@ -81,30 +81,34 @@
         verboseLogger = null,
     )
 
+@ExperimentalKairosApi
 class ShadeCarrierGroupMobileIconViewModelKairos(
-    commonImpl: MobileIconViewModelCommonKairos,
-    interactor: MobileIconInteractor,
-    scope: CoroutineScope,
+    commonImpl: MobileIconViewModelKairosCommon,
+    private val interactor: MobileIconInteractorKairos,
 ) :
-    MobileIconViewModelCommonKairos,
+    MobileIconViewModelKairosCommon,
     LocationBasedMobileViewModelKairos(
         commonImpl,
         location = StatusBarLocation.SHADE_CARRIER_GROUP,
         // Only do verbose logging for the Home location.
         verboseLogger = null,
     ) {
-    private val isSingleCarrier = interactor.isSingleCarrier
-    val carrierName = interactor.carrierName
 
-    override val isVisible: StateFlow<Boolean> =
+    private val isSingleCarrier: State<Boolean>
+        get() = interactor.isSingleCarrier
+
+    val carrierName: State<String>
+        get() = interactor.carrierName
+
+    override val isVisible: State<Boolean> =
         combine(super.isVisible, isSingleCarrier) { isVisible, isSingleCarrier ->
-                if (isSingleCarrier) false else isVisible
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), super.isVisible.value)
+            !isSingleCarrier && isVisible
+        }
 }
 
-class KeyguardMobileIconViewModelKairos(commonImpl: MobileIconViewModelCommonKairos) :
-    MobileIconViewModelCommonKairos,
+@ExperimentalKairosApi
+class KeyguardMobileIconViewModelKairos(commonImpl: MobileIconViewModelKairosCommon) :
+    MobileIconViewModelKairosCommon,
     LocationBasedMobileViewModelKairos(
         commonImpl,
         location = StatusBarLocation.KEYGUARD,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt
index cc7fc09..0a0f964 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconViewModelKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,206 +17,192 @@
 package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
 
 import com.android.systemui.Flags.statusBarStaticInoutIndicators
+import com.android.systemui.KairosBuilder
+import com.android.systemui.activated
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State as KairosState
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.flatMap
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairosBuilder
 import com.android.systemui.log.table.logDiffsForTable
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.core.NewStatusBarIcons
 import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
 import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
 import com.android.systemui.statusbar.pipeline.mobile.ui.model.MobileContentDescription
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.stateIn
 
 /** Common interface for all of the location-based mobile icon view models. */
-interface MobileIconViewModelCommonKairos : MobileIconViewModelCommon {
-    override val subscriptionId: Int
+@ExperimentalKairosApi
+interface MobileIconViewModelKairosCommon {
+    val subscriptionId: Int
+    val iconInteractor: MobileIconInteractorKairos
     /** True if this view should be visible at all. */
-    override val isVisible: StateFlow<Boolean>
-    override val icon: Flow<SignalIconModel>
-    override val contentDescription: Flow<MobileContentDescription?>
-    override val roaming: Flow<Boolean>
+    val isVisible: KairosState<Boolean>
+    val icon: KairosState<SignalIconModel>
+    val contentDescription: KairosState<MobileContentDescription?>
+    val roaming: KairosState<Boolean>
     /** The RAT icon (LTE, 3G, 5G, etc) to be displayed. Null if we shouldn't show anything */
-    override val networkTypeIcon: Flow<Icon.Resource?>
+    val networkTypeIcon: KairosState<Icon.Resource?>
     /** The slice attribution. Drawn as a background layer */
-    override val networkTypeBackground: StateFlow<Icon.Resource?>
-    override val activityInVisible: Flow<Boolean>
-    override val activityOutVisible: Flow<Boolean>
-    override val activityContainerVisible: Flow<Boolean>
+    val networkTypeBackground: KairosState<Icon.Resource?>
+    val activityInVisible: KairosState<Boolean>
+    val activityOutVisible: KairosState<Boolean>
+    val activityContainerVisible: KairosState<Boolean>
 }
 
 /**
  * View model for the state of a single mobile icon. Each [MobileIconViewModel] will keep watch over
- * a single line of service via [MobileIconInteractor] and update the UI based on that
+ * a single line of service via [MobileIconInteractorKairos] and update the UI based on that
  * subscription's information.
  *
- * There will be exactly one [MobileIconViewModel] per filtered subscription offered from
- * [MobileIconsInteractor.filteredSubscriptions].
+ * There will be exactly one [MobileIconViewModelKairos] per filtered subscription offered from
+ * [MobileIconsInteractorKairos.filteredSubscriptions].
  *
- * For the sake of keeping log spam in check, every flow funding the [MobileIconViewModelCommon]
- * interface is implemented as a [StateFlow]. This ensures that each location-based mobile icon view
- * model gets the exact same information, as well as allows us to log that unified state only once
- * per icon.
+ * For the sake of keeping log spam in check, every flow funding the
+ * [MobileIconViewModelKairosCommon] interface is implemented as a [StateFlow]. This ensures that
+ * each location-based mobile icon view model gets the exact same information, as well as allows us
+ * to log that unified state only once per icon.
  */
+@ExperimentalKairosApi
 class MobileIconViewModelKairos(
     override val subscriptionId: Int,
-    iconInteractor: MobileIconInteractor,
-    airplaneModeInteractor: AirplaneModeInteractor,
-    constants: ConnectivityConstants,
-    scope: CoroutineScope,
-) : MobileIconViewModelCommonKairos {
-    private val cellProvider by lazy {
-        CellularIconViewModelKairos(
-            subscriptionId,
-            iconInteractor,
-            airplaneModeInteractor,
-            constants,
-            scope,
-        )
+    override val iconInteractor: MobileIconInteractorKairos,
+    private val airplaneModeInteractor: AirplaneModeInteractor,
+    private val constants: ConnectivityConstants,
+    private val flags: FeatureFlagsClassic,
+) : MobileIconViewModelKairosCommon, KairosBuilder by kairosBuilder() {
+
+    private val isAirplaneMode: State<Boolean> = buildState {
+        airplaneModeInteractor.isAirplaneMode.toState()
     }
 
     private val satelliteProvider by lazy {
-        CarrierBasedSatelliteViewModelKairosImpl(
-            subscriptionId,
-            airplaneModeInteractor,
-            iconInteractor,
-            scope,
-        )
+        CarrierBasedSatelliteViewModelKairosImpl(subscriptionId, iconInteractor, isAirplaneMode)
     }
 
     /**
      * Similar to repository switching, this allows us to split up the logic of satellite/cellular
      * states, since they are different by nature
      */
-    private val vmProvider: Flow<MobileIconViewModelCommon> =
-        iconInteractor.isNonTerrestrial
-            .mapLatest { nonTerrestrial ->
-                if (nonTerrestrial) {
-                    satelliteProvider
-                } else {
-                    cellProvider
+    private val vmProvider: KairosState<MobileIconViewModelKairosCommon> = buildState {
+        iconInteractor.isNonTerrestrial.mapLatestBuild { nonTerrestrial ->
+            if (nonTerrestrial) {
+                satelliteProvider
+            } else {
+                activated {
+                    CellularIconViewModelKairos(
+                        subscriptionId,
+                        iconInteractor,
+                        airplaneModeInteractor,
+                        constants,
+                        flags,
+                    )
                 }
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), cellProvider)
+        }
+    }
 
-    override val isVisible: StateFlow<Boolean> =
-        vmProvider
-            .flatMapLatest { it.isVisible }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+    override val isVisible: KairosState<Boolean> = vmProvider.flatMap { it.isVisible }
 
-    override val icon: Flow<SignalIconModel> = vmProvider.flatMapLatest { it.icon }
+    override val icon: KairosState<SignalIconModel> = vmProvider.flatMap { it.icon }
 
-    override val contentDescription: Flow<MobileContentDescription?> =
-        vmProvider.flatMapLatest { it.contentDescription }
+    override val contentDescription: KairosState<MobileContentDescription?> =
+        vmProvider.flatMap { it.contentDescription }
 
-    override val roaming: Flow<Boolean> = vmProvider.flatMapLatest { it.roaming }
+    override val roaming: KairosState<Boolean> = vmProvider.flatMap { it.roaming }
 
-    override val networkTypeIcon: Flow<Icon.Resource?> =
-        vmProvider.flatMapLatest { it.networkTypeIcon }
+    override val networkTypeIcon: KairosState<Icon.Resource?> =
+        vmProvider.flatMap { it.networkTypeIcon }
 
-    override val networkTypeBackground: StateFlow<Icon.Resource?> =
-        vmProvider
-            .flatMapLatest { it.networkTypeBackground }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+    override val networkTypeBackground: KairosState<Icon.Resource?> =
+        vmProvider.flatMap { it.networkTypeBackground }
 
-    override val activityInVisible: Flow<Boolean> =
-        vmProvider.flatMapLatest { it.activityInVisible }
+    override val activityInVisible: KairosState<Boolean> =
+        vmProvider.flatMap { it.activityInVisible }
 
-    override val activityOutVisible: Flow<Boolean> =
-        vmProvider.flatMapLatest { it.activityOutVisible }
+    override val activityOutVisible: KairosState<Boolean> =
+        vmProvider.flatMap { it.activityOutVisible }
 
-    override val activityContainerVisible: Flow<Boolean> =
-        vmProvider.flatMapLatest { it.activityContainerVisible }
+    override val activityContainerVisible: KairosState<Boolean> =
+        vmProvider.flatMap { it.activityContainerVisible }
 }
 
 /** Representation of this network when it is non-terrestrial (e.g., satellite) */
+@ExperimentalKairosApi
 private class CarrierBasedSatelliteViewModelKairosImpl(
     override val subscriptionId: Int,
-    airplaneModeInteractor: AirplaneModeInteractor,
-    interactor: MobileIconInteractor,
-    scope: CoroutineScope,
-) : MobileIconViewModelCommon, MobileIconViewModelCommonKairos {
-    override val isVisible: StateFlow<Boolean> =
-        airplaneModeInteractor.isAirplaneMode
-            .map { !it }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+    override val iconInteractor: MobileIconInteractorKairos,
+    isAirplaneMode: KairosState<Boolean>,
+) : MobileIconViewModelKairosCommon {
+    override val isVisible: KairosState<Boolean> = isAirplaneMode.map { !it }
+    override val icon: KairosState<SignalIconModel>
+        get() = iconInteractor.signalLevelIcon
 
-    override val icon: Flow<SignalIconModel> = interactor.signalLevelIcon
-
-    override val contentDescription: Flow<MobileContentDescription?> = MutableStateFlow(null)
+    override val contentDescription: KairosState<MobileContentDescription?> = stateOf(null)
 
     /** These fields are not used for satellite icons currently */
-    override val roaming: Flow<Boolean> = flowOf(false)
-    override val networkTypeIcon: Flow<Icon.Resource?> = flowOf(null)
-    override val networkTypeBackground: StateFlow<Icon.Resource?> = MutableStateFlow(null)
-    override val activityInVisible: Flow<Boolean> = flowOf(false)
-    override val activityOutVisible: Flow<Boolean> = flowOf(false)
-    override val activityContainerVisible: Flow<Boolean> = flowOf(false)
+    override val roaming: KairosState<Boolean> = stateOf(false)
+    override val networkTypeIcon: KairosState<Icon.Resource?> = stateOf(null)
+    override val networkTypeBackground: KairosState<Icon.Resource?> = stateOf(null)
+    override val activityInVisible: KairosState<Boolean> = stateOf(false)
+    override val activityOutVisible: KairosState<Boolean> = stateOf(false)
+    override val activityContainerVisible: KairosState<Boolean> = stateOf(false)
 }
 
 /** Terrestrial (cellular) icon. */
-@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
+@ExperimentalKairosApi
 private class CellularIconViewModelKairos(
     override val subscriptionId: Int,
-    iconInteractor: MobileIconInteractor,
+    override val iconInteractor: MobileIconInteractorKairos,
     airplaneModeInteractor: AirplaneModeInteractor,
     constants: ConnectivityConstants,
-    scope: CoroutineScope,
-) : MobileIconViewModelCommon, MobileIconViewModelCommonKairos {
-    override val isVisible: StateFlow<Boolean> =
+    flags: FeatureFlagsClassic,
+) : MobileIconViewModelKairosCommon, KairosBuilder by kairosBuilder() {
+
+    override val isVisible: KairosState<Boolean> =
         if (!constants.hasDataCapabilities) {
-                flowOf(false)
-            } else {
+            stateOf(false)
+        } else {
+            buildState {
                 combine(
-                    airplaneModeInteractor.isAirplaneMode,
-                    iconInteractor.isAllowedDuringAirplaneMode,
-                    iconInteractor.isForceHidden,
-                ) { isAirplaneMode, isAllowedDuringAirplaneMode, isForceHidden ->
-                    if (isForceHidden) {
-                        false
-                    } else if (isAirplaneMode) {
-                        isAllowedDuringAirplaneMode
-                    } else {
-                        true
+                        airplaneModeInteractor.isAirplaneMode.toState(),
+                        iconInteractor.isAllowedDuringAirplaneMode,
+                        iconInteractor.isForceHidden,
+                    ) { isAirplaneMode, isAllowedDuringAirplaneMode, isForceHidden ->
+                        if (isForceHidden) {
+                            false
+                        } else if (isAirplaneMode) {
+                            isAllowedDuringAirplaneMode
+                        } else {
+                            true
+                        }
                     }
-                }
+                    .also {
+                        logDiffsForTable(it, iconInteractor.tableLogBuffer, columnName = "visible")
+                    }
             }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                iconInteractor.tableLogBuffer,
-                columnName = "visible",
-                initialValue = false,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+        }
 
-    override val icon: Flow<SignalIconModel> = iconInteractor.signalLevelIcon
+    override val icon: KairosState<SignalIconModel>
+        get() = iconInteractor.signalLevelIcon
 
-    override val contentDescription: Flow<MobileContentDescription?> =
+    override val contentDescription: KairosState<MobileContentDescription?> =
         combine(iconInteractor.signalLevelIcon, iconInteractor.networkName) { icon, nameModel ->
-                when (icon) {
-                    is SignalIconModel.Cellular ->
-                        MobileContentDescription.Cellular(
-                            nameModel.name,
-                            icon.levelDescriptionRes(),
-                        )
-                    else -> null
-                }
+            when (icon) {
+                is SignalIconModel.Cellular ->
+                    MobileContentDescription.Cellular(nameModel.name, icon.levelDescriptionRes())
+                else -> null
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+        }
 
     private fun SignalIconModel.Cellular.levelDescriptionRes() =
         when (level) {
@@ -241,7 +227,7 @@
             else -> R.string.accessibility_no_signal
         }
 
-    private val showNetworkTypeIcon: Flow<Boolean> =
+    private val showNetworkTypeIcon: KairosState<Boolean> =
         combine(
                 iconInteractor.isDataConnected,
                 iconInteractor.isDataEnabled,
@@ -252,77 +238,72 @@
                 alwaysShow ||
                     (!carrierNetworkChange && (dataEnabled && dataConnected && mobileIsDefault))
             }
-            .distinctUntilChanged()
-            .logDiffsForTable(
-                iconInteractor.tableLogBuffer,
-                columnName = "showNetworkTypeIcon",
-                initialValue = false,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+            .also {
+                onActivated {
+                    logDiffsForTable(
+                        it,
+                        iconInteractor.tableLogBuffer,
+                        columnName = "showNetworkTypeIcon",
+                    )
+                }
+            }
 
-    override val networkTypeIcon: Flow<Icon.Resource?> =
+    override val networkTypeIcon: KairosState<Icon.Resource?> =
         combine(iconInteractor.networkTypeIconGroup, showNetworkTypeIcon) {
-                networkTypeIconGroup,
-                shouldShow ->
-                val desc =
-                    if (networkTypeIconGroup.contentDescription != 0)
-                        ContentDescription.Resource(networkTypeIconGroup.contentDescription)
-                    else null
-                val icon =
-                    if (networkTypeIconGroup.iconId != 0)
-                        Icon.Resource(networkTypeIconGroup.iconId, desc)
-                    else null
-                return@combine when {
-                    !shouldShow -> null
-                    else -> icon
+            networkTypeIconGroup,
+            shouldShow ->
+            val desc =
+                if (networkTypeIconGroup.contentDescription != 0) {
+                    ContentDescription.Resource(networkTypeIconGroup.contentDescription)
+                } else {
+                    null
                 }
-            }
-            .distinctUntilChanged()
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
-
-    override val networkTypeBackground =
-        iconInteractor.showSliceAttribution
-            .map {
-                when {
-                    it && NewStatusBarIcons.isEnabled ->
-                        Icon.Resource(R.drawable.mobile_network_type_background_updated, null)
-                    it -> Icon.Resource(R.drawable.mobile_network_type_background, null)
-                    else -> null
+            val icon =
+                if (networkTypeIconGroup.iconId != 0) {
+                    Icon.Resource(networkTypeIconGroup.iconId, desc)
+                } else {
+                    null
                 }
+            when {
+                !shouldShow -> null
+                else -> icon
             }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
+        }
 
-    override val roaming: StateFlow<Boolean> =
-        iconInteractor.isRoaming
-            .logDiffsForTable(
-                iconInteractor.tableLogBuffer,
-                columnName = "roaming",
-                initialValue = false,
-            )
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+    override val networkTypeBackground: KairosState<Icon.Resource?> =
+        iconInteractor.showSliceAttribution.map {
+            when {
+                it && NewStatusBarIcons.isEnabled ->
+                    Icon.Resource(R.drawable.mobile_network_type_background_updated, null)
+                it -> Icon.Resource(R.drawable.mobile_network_type_background, null)
+                else -> null
+            }
+        }
 
-    private val activity: Flow<DataActivityModel?> =
+    override val roaming: KairosState<Boolean> =
+        iconInteractor.isRoaming.also {
+            onActivated {
+                logDiffsForTable(it, iconInteractor.tableLogBuffer, columnName = "roaming")
+            }
+        }
+
+    private val activity: KairosState<DataActivityModel?> =
         if (!constants.shouldShowActivityConfig) {
-            flowOf(null)
+            stateOf(null)
         } else {
             iconInteractor.activity
         }
 
-    override val activityInVisible: Flow<Boolean> =
-        activity
-            .map { it?.hasActivityIn ?: false }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+    override val activityInVisible: KairosState<Boolean> =
+        activity.map { it?.hasActivityIn ?: false }
 
-    override val activityOutVisible: Flow<Boolean> =
-        activity
-            .map { it?.hasActivityOut ?: false }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+    override val activityOutVisible: KairosState<Boolean> =
+        activity.map { it?.hasActivityOut ?: false }
 
-    override val activityContainerVisible: Flow<Boolean> =
+    override val activityContainerVisible: KairosState<Boolean> =
         if (statusBarStaticInoutIndicators()) {
-                flowOf(constants.shouldShowActivityConfig)
-            } else {
-                activity.map { it != null && (it.hasActivityIn || it.hasActivityOut) }
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
+            stateOf(constants.shouldShowActivityConfig)
+        } else {
+            activity.map { it != null && (it.hasActivityIn || it.hasActivityOut) }
+        }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt
index a655407..ada5500 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2024 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,137 +16,149 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
 
-import androidx.annotation.VisibleForTesting
-import com.android.app.tracing.coroutines.launchTraced as launch
-import com.android.systemui.coroutines.newTracingContext
+import androidx.compose.runtime.State as ComposeState
+import androidx.compose.runtime.mutableStateOf
+import com.android.systemui.Flags
+import com.android.systemui.KairosActivatable
+import com.android.systemui.KairosBuilder
+import com.android.systemui.activated
 import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.flags.FeatureFlagsClassic
+import com.android.systemui.kairos.BuildScope
+import com.android.systemui.kairos.BuildSpec
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.Incremental
+import com.android.systemui.kairos.State as KairosState
+import com.android.systemui.kairos.State
+import com.android.systemui.kairos.buildSpec
+import com.android.systemui.kairos.changes
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.flatten
+import com.android.systemui.kairos.map
+import com.android.systemui.kairos.mapValues
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairosBuilder
 import com.android.systemui.statusbar.phone.StatusBarLocation
 import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.AirplaneModeInteractor
-import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.MobileIconsInteractorKairos
 import com.android.systemui.statusbar.pipeline.mobile.ui.MobileViewLogger
 import com.android.systemui.statusbar.pipeline.mobile.ui.VerboseMobileViewLogger
 import com.android.systemui.statusbar.pipeline.mobile.ui.view.ModernStatusBarMobileView
 import com.android.systemui.statusbar.pipeline.shared.ConnectivityConstants
-import java.util.concurrent.ConcurrentHashMap
+import dagger.Provides
+import dagger.multibindings.ElementsIntoSet
 import javax.inject.Inject
-import kotlin.coroutines.CoroutineContext
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.Job
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.flow.SharingStarted
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.mapLatest
-import kotlinx.coroutines.flow.stateIn
+import javax.inject.Provider
 
 /**
  * View model for describing the system's current mobile cellular connections. The result is a list
  * of [MobileIconViewModel]s which describe the individual icons and can be bound to
  * [ModernStatusBarMobileView].
  */
+@ExperimentalKairosApi
 @SysUISingleton
 class MobileIconsViewModelKairos
 @Inject
 constructor(
     val logger: MobileViewLogger,
     private val verboseLogger: VerboseMobileViewLogger,
-    private val interactor: MobileIconsInteractor,
+    private val interactor: MobileIconsInteractorKairos,
     private val airplaneModeInteractor: AirplaneModeInteractor,
     private val constants: ConnectivityConstants,
-    @Background private val scope: CoroutineScope,
-) {
-    @VisibleForTesting
-    val reuseCache = ConcurrentHashMap<Int, Pair<MobileIconViewModel, CoroutineScope>>()
+    private val flags: FeatureFlagsClassic,
+) : KairosBuilder by kairosBuilder() {
 
-    val activeMobileDataSubscriptionId: StateFlow<Int?> = interactor.activeMobileDataSubscriptionId
+    val activeSubscriptionId: State<Int?>
+        get() = interactor.activeDataIconInteractor.map { it?.subscriptionId }
 
-    val subscriptionIdsFlow: StateFlow<List<Int>> =
-        interactor.filteredSubscriptions
-            .mapLatest { subscriptions ->
-                subscriptions.map { subscriptionModel -> subscriptionModel.subscriptionId }
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), listOf())
+    val subscriptionIds: KairosState<List<Int>> =
+        interactor.filteredSubscriptions.map { subscriptions ->
+            subscriptions.map { it.subscriptionId }
+        }
 
-    val mobileSubViewModels: StateFlow<List<MobileIconViewModelCommon>> =
-        subscriptionIdsFlow
-            .map { ids -> ids.map { commonViewModelForSub(it) } }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), emptyList())
-
-    private val firstMobileSubViewModel: StateFlow<MobileIconViewModelCommon?> =
-        mobileSubViewModels
-            .map {
-                if (it.isEmpty()) {
-                    null
-                } else {
-                    // Mobile icons get reversed by [StatusBarIconController], so the last element
-                    // in this list will show up visually first.
-                    it.last()
-                }
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), null)
-
-    /**
-     * A flow that emits `true` if the mobile sub that's displayed first visually is showing its
-     * network type icon and `false` otherwise.
-     */
-    val firstMobileSubShowingNetworkTypeIcon: StateFlow<Boolean> =
-        firstMobileSubViewModel
-            .flatMapLatest { firstMobileSubViewModel ->
-                firstMobileSubViewModel?.networkTypeIcon?.map { it != null } ?: flowOf(false)
-            }
-            .stateIn(scope, SharingStarted.WhileSubscribed(), false)
-
-    val isStackable: StateFlow<Boolean> = interactor.isStackable
-
-    init {
-        scope.launch { subscriptionIdsFlow.collect { invalidateCaches(it) } }
+    val icons: Incremental<Int, MobileIconViewModelKairos> = buildIncremental {
+        interactor.icons
+            .mapValues { (subId, icon) -> buildSpec { commonViewModel(subId, icon) } }
+            .applyLatestSpecForKey()
     }
 
-    fun viewModelForSub(subId: Int, location: StatusBarLocation): LocationBasedMobileViewModel {
-        val common = commonViewModelForSub(subId)
-        return LocationBasedMobileViewModel.viewModelForLocation(
-            common,
-            interactor.getMobileConnectionInteractorForSubId(subId),
+    /** Whether the mobile sub that's displayed first visually is showing its network type icon. */
+    val firstMobileSubShowingNetworkTypeIcon: KairosState<Boolean> = buildState {
+        combine(subscriptionIds.map { it.lastOrNull() }, icons) { lastId, icons ->
+                icons[lastId]?.networkTypeIcon?.map { it != null } ?: stateOf(false)
+            }
+            .flatten()
+    }
+
+    val isStackable: KairosState<Boolean>
+        get() = interactor.isStackable
+
+    fun viewModelForSub(
+        subId: Int,
+        location: StatusBarLocation,
+    ): BuildSpec<LocationBasedMobileViewModelKairos> = buildSpec {
+        val iconInteractor =
+            interactor.icons.sample().getOrElse(subId) { error("Unknown subscription id: $subId") }
+        val commonViewModel =
+            icons.sample().getOrElse(subId) { error("Unknown subscription id: $subId") }
+        LocationBasedMobileViewModelKairos.viewModelForLocation(
+            commonViewModel,
+            iconInteractor,
             verboseLogger,
             location,
-            scope,
         )
     }
 
-    private fun commonViewModelForSub(subId: Int): MobileIconViewModelCommon {
-        return reuseCache.getOrPut(subId) { createViewModel(subId) }.first
-    }
+    fun shadeCarrierGroupIcon(subId: Int): BuildSpec<ShadeCarrierGroupMobileIconViewModelKairos> =
+        buildSpec {
+            val iconInteractor =
+                interactor.icons.sample().getOrElse(subId) {
+                    error("Unknown subscription id: $subId")
+                }
+            val commonViewModel =
+                icons.sample().getOrElse(subId) { error("Unknown subscription id: $subId") }
+            ShadeCarrierGroupMobileIconViewModelKairos(commonViewModel, iconInteractor)
+        }
 
-    private fun createViewModel(subId: Int): Pair<MobileIconViewModel, CoroutineScope> {
-        // Create a child scope so we can cancel it
-        val vmScope = scope.createChildScope(newTracingContext("MobileIconViewModel"))
-        val vm =
-            MobileIconViewModel(
-                subId,
-                interactor.getMobileConnectionInteractorForSubId(subId),
-                airplaneModeInteractor,
-                constants,
-                vmScope,
+    private fun BuildScope.commonViewModel(subId: Int, iconInteractor: MobileIconInteractorKairos) =
+        activated {
+            MobileIconViewModelKairos(
+                subscriptionId = subId,
+                iconInteractor = iconInteractor,
+                airplaneModeInteractor = airplaneModeInteractor,
+                constants = constants,
+                flags = flags,
             )
+        }
 
-        return Pair(vm, vmScope)
+    @dagger.Module
+    object Module {
+        @Provides
+        @ElementsIntoSet
+        fun bindKairosActivatable(
+            impl: Provider<MobileIconsViewModelKairos>
+        ): Set<@JvmSuppressWildcards KairosActivatable> =
+            if (Flags.statusBarMobileIconKairos()) setOf(impl.get()) else emptySet()
     }
+}
 
-    private fun CoroutineScope.createChildScope(extraContext: CoroutineContext) =
-        CoroutineScope(coroutineContext + Job(coroutineContext[Job]) + extraContext)
+@ExperimentalKairosApi
+class MobileIconsViewModelKairosComposeWrapper(
+    val icons: ComposeState<Map<Int, MobileIconViewModelKairos>>
+)
 
-    private fun invalidateCaches(subIds: List<Int>) {
-        reuseCache.keys
-            .filter { !subIds.contains(it) }
-            .forEach { id ->
-                reuseCache
-                    .remove(id)
-                    // Cancel the view model's scope after removing it
-                    ?.second
-                    ?.cancel()
-            }
-    }
+@ExperimentalKairosApi
+fun composeWrapper(
+    viewModel: MobileIconsViewModelKairos
+): BuildSpec<MobileIconsViewModelKairosComposeWrapper> = buildSpec {
+    MobileIconsViewModelKairosComposeWrapper(icons = toComposeState(viewModel.icons))
+}
+
+@ExperimentalKairosApi
+fun <T> BuildScope.toComposeState(state: KairosState<T>): ComposeState<T> {
+    val initial = state.sample()
+    val cState = mutableStateOf(initial)
+    state.changes.observe { cState.value = it }
+    return cState
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt
index 2c85a51..060454c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModel.kt
@@ -22,6 +22,7 @@
 import com.android.systemui.lifecycle.ExclusiveActivatable
 import com.android.systemui.lifecycle.Hydrator
 import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModel.DualSim
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -30,10 +31,22 @@
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
 
+interface StackedMobileIconViewModel {
+    val dualSim: DualSim?
+    val networkTypeIcon: Icon.Resource?
+    val isIconVisible: Boolean
+
+    data class DualSim(
+        val primary: SignalIconModel.Cellular,
+        val secondary: SignalIconModel.Cellular,
+    )
+}
+
 @OptIn(ExperimentalCoroutinesApi::class)
-class StackedMobileIconViewModel
+class StackedMobileIconViewModelImpl
 @AssistedInject
-constructor(mobileIconsViewModel: MobileIconsViewModel) : ExclusiveActivatable() {
+constructor(mobileIconsViewModel: MobileIconsViewModel) :
+    ExclusiveActivatable(), StackedMobileIconViewModel {
     private val hydrator = Hydrator("StackedMobileIconViewModel")
 
     private val isStackable: Boolean by
@@ -52,7 +65,7 @@
             viewModels.sortedByDescending { it.subscriptionId == activeSubId }
         }
 
-    val dualSim: DualSim? by
+    override val dualSim: DualSim? by
         hydrator.hydratedStateOf(
             traceName = "dualSim",
             source =
@@ -68,7 +81,7 @@
             initialValue = null,
         )
 
-    val networkTypeIcon: Icon.Resource? by
+    override val networkTypeIcon: Icon.Resource? by
         hydrator.hydratedStateOf(
             traceName = "networkTypeIcon",
             source =
@@ -78,7 +91,7 @@
             initialValue = null,
         )
 
-    val isIconVisible: Boolean by derivedStateOf { isStackable && dualSim != null }
+    override val isIconVisible: Boolean by derivedStateOf { isStackable && dualSim != null }
 
     override suspend fun onActivated(): Nothing {
         hydrator.activate()
@@ -86,11 +99,6 @@
 
     @AssistedFactory
     interface Factory {
-        fun create(): StackedMobileIconViewModel
+        fun create(): StackedMobileIconViewModelImpl
     }
-
-    data class DualSim(
-        val primary: SignalIconModel.Cellular,
-        val secondary: SignalIconModel.Cellular,
-    )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt
index 2dbb02c..402fdf0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairos.kt
@@ -16,81 +16,71 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
 
-import androidx.compose.runtime.derivedStateOf
 import androidx.compose.runtime.getValue
+import com.android.systemui.KairosBuilder
 import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.lifecycle.ExclusiveActivatable
-import com.android.systemui.lifecycle.Hydrator
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State as KairosState
+import com.android.systemui.kairos.combine
+import com.android.systemui.kairos.flatMap
+import com.android.systemui.kairos.stateOf
+import com.android.systemui.kairosBuilder
 import com.android.systemui.statusbar.pipeline.mobile.domain.model.SignalIconModel
+import com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel.StackedMobileIconViewModel.DualSim
+import com.android.systemui.util.composable.kairos.hydratedComposeStateOf
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.flatMapLatest
-import kotlinx.coroutines.flow.flowOf
 
-@OptIn(ExperimentalCoroutinesApi::class)
+@OptIn(ExperimentalKairosApi::class)
 class StackedMobileIconViewModelKairos
 @AssistedInject
-constructor(mobileIconsViewModel: MobileIconsViewModel) : ExclusiveActivatable() {
-    private val hydrator = Hydrator("StackedMobileIconViewModel")
+constructor(mobileIcons: MobileIconsViewModelKairos) :
+    KairosBuilder by kairosBuilder(), StackedMobileIconViewModel {
 
     private val isStackable: Boolean by
-        hydrator.hydratedStateOf(
-            traceName = "isStackable",
-            source = mobileIconsViewModel.isStackable,
-            initialValue = false,
-        )
+        hydratedComposeStateOf(mobileIcons.isStackable, initialValue = false)
 
-    private val iconViewModelFlow: Flow<List<MobileIconViewModelCommon>> =
-        combine(
-            mobileIconsViewModel.mobileSubViewModels,
-            mobileIconsViewModel.activeMobileDataSubscriptionId,
-        ) { viewModels, activeSubId ->
-            // Sort to get the active subscription first, if it's set
-            viewModels.sortedByDescending { it.subscriptionId == activeSubId }
+    private val iconList: KairosState<List<MobileIconViewModelKairos>> =
+        combine(mobileIcons.icons, mobileIcons.activeSubscriptionId) { iconsBySubId, activeSubId ->
+            buildList {
+                activeSubId?.let { iconsBySubId[activeSubId]?.let { add(it) } }
+                addAll(iconsBySubId.values.asSequence().filter { it.subscriptionId != activeSubId })
+            }
         }
 
-    val dualSim: DualSim? by
-        hydrator.hydratedStateOf(
-            traceName = "dualSim",
-            source =
-                iconViewModelFlow.flatMapLatest { viewModels ->
-                    combine(viewModels.map { it.icon }) { icons ->
-                        icons
-                            .toList()
-                            .filterIsInstance<SignalIconModel.Cellular>()
-                            .takeIf { it.size == 2 }
-                            ?.let { DualSim(it[0], it[1]) }
-                    }
-                },
+    override val dualSim: DualSim? by
+        hydratedComposeStateOf(
+            iconList.flatMap { icons ->
+                icons.map { it.icon }.combine { signalIcons -> tryParseDualSim(signalIcons) }
+            },
             initialValue = null,
         )
 
-    val networkTypeIcon: Icon.Resource? by
-        hydrator.hydratedStateOf(
-            traceName = "networkTypeIcon",
-            source =
-                iconViewModelFlow.flatMapLatest { viewModels ->
-                    viewModels.firstOrNull()?.networkTypeIcon ?: flowOf(null)
-                },
+    override val networkTypeIcon: Icon.Resource? by
+        hydratedComposeStateOf(
+            iconList.flatMap { icons -> icons.firstOrNull()?.networkTypeIcon ?: stateOf(null) },
             initialValue = null,
         )
 
-    val isIconVisible: Boolean by derivedStateOf { isStackable && dualSim != null }
+    override val isIconVisible: Boolean
+        get() = isStackable && dualSim != null
 
-    override suspend fun onActivated(): Nothing {
-        hydrator.activate()
+    private fun tryParseDualSim(icons: List<SignalIconModel>): DualSim? {
+        var first: SignalIconModel.Cellular? = null
+        var second: SignalIconModel.Cellular? = null
+        for (icon in icons) {
+            when {
+                icon !is SignalIconModel.Cellular -> continue
+                first == null -> first = icon
+                second == null -> second = icon
+                else -> return null
+            }
+        }
+        return first?.let { second?.let { DualSim(first, second) } }
     }
 
     @AssistedFactory
     interface Factory {
         fun create(): StackedMobileIconViewModelKairos
     }
-
-    data class DualSim(
-        val primary: SignalIconModel.Cellular,
-        val secondary: SignalIconModel.Cellular,
-    )
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
index ba66651..2f9cff4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/composable/StatusBarRoot.kt
@@ -196,9 +196,8 @@
 
                                 setContent {
                                     PlatformTheme {
-                                        val chipsVisibilityModel by
+                                        val chipsVisibilityModel =
                                             statusBarViewModel.ongoingActivityChips
-                                                .collectAsStateWithLifecycle()
                                         if (chipsVisibilityModel.areChipsAllowed) {
                                             OngoingActivityChips(
                                                 chips = chipsVisibilityModel.chips,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
index c717b18..540baba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ui/viewmodel/HomeStatusBarViewModel.kt
@@ -21,6 +21,8 @@
 import android.view.Display
 import android.view.View
 import androidx.compose.runtime.getValue
+import com.android.app.tracing.FlowTracing.traceEach
+import com.android.app.tracing.TrackGroupUtils.trackGroup
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
@@ -130,7 +132,7 @@
     val primaryOngoingActivityChip: StateFlow<OngoingActivityChipModel>
 
     /** All supported activity chips, whether they are currently active or not. */
-    val ongoingActivityChips: StateFlow<ChipsVisibilityModel>
+    val ongoingActivityChips: ChipsVisibilityModel
 
     /**
      * The multiple ongoing activity chips that should be shown on the left-hand side of the status
@@ -386,11 +388,9 @@
         }
 
     override val isHomeStatusBarAllowed =
-        isHomeStatusBarAllowedCompat.stateIn(
-            bgScope,
-            SharingStarted.WhileSubscribed(),
-            initialValue = false,
-        )
+        isHomeStatusBarAllowedCompat
+            .traceEach(trackGroup(TRACK_GROUP, "isHomeStatusBarAllowed"), logcat = true)
+            .stateIn(bgScope, SharingStarted.WhileSubscribed(), initialValue = false)
 
     private val shouldHomeStatusBarBeVisible =
         combine(
@@ -461,24 +461,29 @@
             isHomeStatusBarAllowed && !isSecureCameraActive && !hideStartSideContentForHeadsUp
         }
 
-    override val ongoingActivityChips =
+    private val chipsVisibilityModel: Flow<ChipsVisibilityModel> =
         combine(ongoingActivityChipsViewModel.chips, canShowOngoingActivityChips) { chips, canShow
                 ->
                 ChipsVisibilityModel(chips, areChipsAllowed = canShow)
             }
-            .stateIn(
-                bgScope,
-                SharingStarted.WhileSubscribed(),
-                initialValue =
-                    ChipsVisibilityModel(
-                        chips = MultipleOngoingActivityChipsModel(),
-                        areChipsAllowed = false,
-                    ),
-            )
+            .traceEach(trackGroup(TRACK_GROUP, "chips"), logcat = true) {
+                "Chips[allowed=${it.areChipsAllowed} numChips=${it.chips.active.size}]"
+            }
+
+    override val ongoingActivityChips: ChipsVisibilityModel by
+        hydrator.hydratedStateOf(
+            traceName = "ongoingActivityChips",
+            initialValue =
+                ChipsVisibilityModel(
+                    chips = MultipleOngoingActivityChipsModel(),
+                    areChipsAllowed = false,
+                ),
+            source = chipsVisibilityModel,
+        )
 
     private val hasOngoingActivityChips =
         if (StatusBarChipsModernization.isEnabled) {
-            ongoingActivityChips.map { it.chips.active.any { chip -> !chip.isHidden } }
+            chipsVisibilityModel.map { it.chips.active.any { chip -> !chip.isHidden } }
         } else if (StatusBarNotifChips.isEnabled) {
             ongoingActivityChipsLegacy.map { it.primary is OngoingActivityChipModel.Active }
         } else {
@@ -607,6 +612,8 @@
         private const val COL_PREFIX_NOTIF_CONTAINER = "notifContainer"
         private const val COL_PREFIX_SYSTEM_INFO = "systemInfo"
 
+        private const val TRACK_GROUP = "StatusBar"
+
         fun tableLogBufferName(displayId: Int) = "HomeStatusBarViewModel[$displayId]"
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 9a81992..7f778bb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -256,6 +256,9 @@
                     if (mClockFormat != null) {
                         mClockFormat.setTimeZone(mCalendar.getTimeZone());
                     }
+                    if (mContentDescriptionFormat != null) {
+                        mContentDescriptionFormat.setTimeZone(mCalendar.getTimeZone());
+                    }
                 });
             } else if (action.equals(Intent.ACTION_CONFIGURATION_CHANGED)) {
                 final Locale newLocale = getResources().getConfiguration().locale;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java
index b13e01b..fa022b4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingController.java
@@ -27,6 +27,7 @@
 
 import androidx.annotation.NonNull;
 
+import com.android.settingslib.devicestate.DeviceStateAutoRotateSettingManager;
 import com.android.settingslib.devicestate.DeviceStateRotationLockSettingsManager;
 import com.android.systemui.Dumpable;
 import com.android.systemui.dagger.qualifiers.Main;
@@ -56,8 +57,8 @@
     private int mDeviceState = -1;
     @Nullable
     private DeviceStateManager.DeviceStateCallback mDeviceStateCallback;
-    private DeviceStateRotationLockSettingsManager.DeviceStateRotationLockSettingsListener
-            mDeviceStateRotationLockSettingsListener;
+    private DeviceStateAutoRotateSettingManager.DeviceStateAutoRotateSettingListener
+            mDeviceStateAutoRotateSettingListener;
 
     @Inject
     public DeviceStateRotationLockSettingController(
@@ -83,17 +84,17 @@
             // is no user action.
             mDeviceStateCallback = this::updateDeviceState;
             mDeviceStateManager.registerCallback(mMainExecutor, mDeviceStateCallback);
-            mDeviceStateRotationLockSettingsListener = () ->
+            mDeviceStateAutoRotateSettingListener = () ->
                     readPersistedSetting("deviceStateRotationLockChange", mDeviceState);
             mDeviceStateRotationLockSettingsManager.registerListener(
-                    mDeviceStateRotationLockSettingsListener);
+                    mDeviceStateAutoRotateSettingListener);
         } else {
             if (mDeviceStateCallback != null) {
                 mDeviceStateManager.unregisterCallback(mDeviceStateCallback);
             }
-            if (mDeviceStateRotationLockSettingsListener != null) {
+            if (mDeviceStateAutoRotateSettingListener != null) {
                 mDeviceStateRotationLockSettingsManager.unregisterListener(
-                        mDeviceStateRotationLockSettingsListener);
+                        mDeviceStateAutoRotateSettingListener);
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
index a352982..f6e0123 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/PolicyModule.kt
@@ -36,20 +36,25 @@
 import com.android.systemui.qs.tiles.ModesTile
 import com.android.systemui.qs.tiles.UiModeNightTile
 import com.android.systemui.qs.tiles.WorkModeTile
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
-import com.android.systemui.qs.tiles.impl.alarm.domain.AlarmTileMapper
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.ui.viewmodel.StubQSTileViewModel
 import com.android.systemui.qs.tiles.impl.alarm.domain.interactor.AlarmTileDataInteractor
 import com.android.systemui.qs.tiles.impl.alarm.domain.interactor.AlarmTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.alarm.domain.model.AlarmTileModel
-import com.android.systemui.qs.tiles.impl.flashlight.domain.FlashlightMapper
+import com.android.systemui.qs.tiles.impl.alarm.ui.mapper.AlarmTileMapper
 import com.android.systemui.qs.tiles.impl.flashlight.domain.interactor.FlashlightTileDataInteractor
 import com.android.systemui.qs.tiles.impl.flashlight.domain.interactor.FlashlightTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.flashlight.domain.model.FlashlightTileModel
-import com.android.systemui.qs.tiles.impl.location.domain.LocationTileMapper
+import com.android.systemui.qs.tiles.impl.flashlight.ui.mapper.FlashlightMapper
 import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileDataInteractor
 import com.android.systemui.qs.tiles.impl.location.domain.interactor.LocationTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.location.domain.model.LocationTileModel
+import com.android.systemui.qs.tiles.impl.location.ui.mapper.LocationTileMapper
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileDataInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesDndTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.modes.domain.interactor.ModesTileDataInteractor
@@ -57,25 +62,20 @@
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesDndTileModel
 import com.android.systemui.qs.tiles.impl.modes.domain.model.ModesTileModel
 import com.android.systemui.qs.tiles.impl.modes.ui.ModesDndTileMapper
-import com.android.systemui.qs.tiles.impl.modes.ui.ModesTileMapper
-import com.android.systemui.qs.tiles.impl.sensorprivacy.SensorPrivacyToggleTileDataInteractor
-import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.SensorPrivacyToggleTileUserActionInteractor
+import com.android.systemui.qs.tiles.impl.modes.ui.mapper.ModesTileMapper
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor.SensorPrivacyToggleTileDataInteractor
+import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.interactor.SensorPrivacyToggleTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.sensorprivacy.domain.model.SensorPrivacyToggleTileModel
-import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyTileResources
-import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.SensorPrivacyToggleTileMapper
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.UiModeNightTileMapper
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.mapper.SensorPrivacyToggleTileMapper
+import com.android.systemui.qs.tiles.impl.sensorprivacy.ui.model.SensorPrivacyTileResources
 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileDataInteractor
 import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.UiModeNightTileUserActionInteractor
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel
+import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel
+import com.android.systemui.qs.tiles.impl.uimodenight.ui.mapper.UiModeNightTileMapper
 import com.android.systemui.qs.tiles.impl.work.domain.interactor.WorkModeTileDataInteractor
 import com.android.systemui.qs.tiles.impl.work.domain.interactor.WorkModeTileUserActionInteractor
 import com.android.systemui.qs.tiles.impl.work.domain.model.WorkModeTileModel
-import com.android.systemui.qs.tiles.impl.work.ui.WorkModeTileMapper
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
-import com.android.systemui.qs.tiles.viewmodel.StubQSTileViewModel
+import com.android.systemui.qs.tiles.impl.work.ui.mapper.WorkModeTileMapper
 import com.android.systemui.res.R
 import dagger.Binds
 import dagger.Module
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index f1f2b88..6509a69 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -79,6 +79,7 @@
 import com.android.internal.logging.UiEventLogger;
 import com.android.internal.util.ContrastColorUtil;
 import com.android.systemui.Dependency;
+import com.android.systemui.Flags;
 import com.android.systemui.res.R;
 import com.android.systemui.statusbar.RemoteInputController;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -245,7 +246,9 @@
         mProgressBar.setProgressTintList(accentColor);
         mProgressBar.setIndeterminateTintList(accentColor);
         mProgressBar.setSecondaryProgressTintList(accentColor);
-        setBackgroundColor(backgroundColor);
+        if (!Flags.notificationRowTransparency()) {
+            setBackgroundColor(backgroundColor);
+        }
     }
 
     @Override
@@ -419,10 +422,10 @@
         // case to prevent flicker.
         if (!mRemoved) {
             ViewGroup parent = (ViewGroup) getParent();
+            View actionsContainer = getActionsContainerLayout();
             if (animate && parent != null) {
 
                 ViewGroup grandParent = (ViewGroup) parent.getParent();
-                View actionsContainer = getActionsContainerLayout();
                 int actionsContainerHeight =
                         actionsContainer != null ? actionsContainer.getHeight() : 0;
 
@@ -459,6 +462,9 @@
                 if (mWrapper != null) {
                     mWrapper.setRemoteInputVisible(false);
                 }
+                if (Flags.notificationRowTransparency()) {
+                    if (actionsContainer != null) actionsContainer.setAlpha(1);
+                }
             }
         }
         unregisterBackCallback();
@@ -823,12 +829,14 @@
                     ObjectAnimator.ofFloat(fadeOutView, View.ALPHA, 1f, 0f);
             fadeOutViewAlphaAnimator.setDuration(FOCUS_ANIMATION_CROSSFADE_DURATION);
             fadeOutViewAlphaAnimator.setInterpolator(InterpolatorsAndroidX.LINEAR);
-            animatorSet.addListener(new AnimatorListenerAdapter() {
-                @Override
-                public void onAnimationEnd(Animator animation, boolean isReverse) {
-                    fadeOutView.setAlpha(1f);
-                }
-            });
+            if (!Flags.notificationRowTransparency()) {
+                animatorSet.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation, boolean isReverse) {
+                        fadeOutView.setAlpha(1f);
+                    }
+                });
+            }
             animatorSet.playTogether(alphaAnimator, scaleAnimator, fadeOutViewAlphaAnimator);
         }
         return animatorSet;
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index 48d7747..bd3fead 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -988,6 +988,7 @@
     public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
         pw.println("mSystemColors=" + mCurrentColors);
         pw.println("mMainWallpaperColor=" + Integer.toHexString(mMainWallpaperColor));
+        pw.println("mContrast=" + mContrast);
         pw.println("mSecondaryOverlay=" + mSecondaryOverlay);
         pw.println("mNeutralOverlay=" + mNeutralOverlay);
         pw.println("mDynamicOverlay=" + mDynamicOverlay);
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt
index 47e27bc..1cc7a31 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyLogger.kt
@@ -50,6 +50,7 @@
                 onScreenTurningOnToOnDrawnMs,
                 onDrawnToOnScreenTurnedOnMs,
                 trackingResult,
+                screenWakelockstatus
             )
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt
index 66de522..5800d5e 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/DisplaySwitchLatencyTracker.kt
@@ -344,6 +344,8 @@
         val onDrawnToOnScreenTurnedOnMs: Int = VALUE_UNKNOWN,
         val trackingResult: Int =
             SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__TRACKING_RESULT__UNKNOWN_RESULT,
+        val screenWakelockstatus: Int =
+            SysUiStatsLog.DISPLAY_SWITCH_LATENCY_TRACKED__SCREEN_WAKELOCK_STATUS__SCREEN_WAKELOCK_STATUS_UNKNOWN,
     )
 
     enum class TrackingResult {
diff --git a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
index 05b2e0d..b33eafc 100644
--- a/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/data/repository/UserRepository.kt
@@ -414,16 +414,15 @@
         }
     }
 
+    private suspend fun SelectedUserModel.isEligibleForLogout(): Boolean {
+        return withContext(backgroundDispatcher) {
+            selectionStatus == SelectionStatus.SELECTION_COMPLETE &&
+                devicePolicyManager.logoutUser != null
+        }
+    }
+
     companion object {
         private const val TAG = "UserRepository"
         @VisibleForTesting const val SETTING_SIMPLE_USER_SWITCHER = "lockscreenSimpleUserSwitcher"
     }
 }
-
-fun SelectedUserModel.isEligibleForLogout(): Boolean {
-    // TODO(b/206032495): should call mDevicePolicyManager.getLogoutUserId() instead of
-    // hardcode it to USER_SYSTEM so it properly supports headless system user mode
-    // (and then call mDevicePolicyManager.clearLogoutUser() after switched)
-    return selectionStatus == SelectionStatus.SELECTION_COMPLETE &&
-        userInfo.id != android.os.UserHandle.USER_SYSTEM
-}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
index a791376..38ac5e6 100644
--- a/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
+++ b/packages/SystemUI/src/com/android/systemui/util/AlarmTimeout.java
@@ -26,7 +26,6 @@
  */
 public class AlarmTimeout implements AlarmManager.OnAlarmListener {
 
-    public static final int MODE_CRASH_IF_SCHEDULED = 0;
     public static final int MODE_IGNORE_IF_SCHEDULED = 1;
     public static final int MODE_RESCHEDULE_IF_SCHEDULED = 2;
 
@@ -48,17 +47,11 @@
      * Schedules an alarm in {@code timeout} milliseconds in the future.
      *
      * @param timeout How long to wait from now.
-     * @param mode {@link #MODE_CRASH_IF_SCHEDULED}, {@link #MODE_IGNORE_IF_SCHEDULED} or
-     *             {@link #MODE_RESCHEDULE_IF_SCHEDULED}.
+     * @param mode {@link #MODE_IGNORE_IF_SCHEDULED} or {@link #MODE_RESCHEDULE_IF_SCHEDULED}.
      * @return {@code true} when scheduled successfully, {@code false} otherwise.
      */
     public boolean schedule(long timeout, int mode) {
         switch (mode) {
-            case MODE_CRASH_IF_SCHEDULED:
-                if (mScheduled) {
-                    throw new IllegalStateException(mTag + " timeout is already scheduled");
-                }
-                break;
             case MODE_IGNORE_IF_SCHEDULED:
                 if (mScheduled) {
                     return false;
diff --git a/packages/SystemUI/src/com/android/systemui/util/composable/kairos/HydratedComposeStateOf.kt b/packages/SystemUI/src/com/android/systemui/util/composable/kairos/HydratedComposeStateOf.kt
new file mode 100644
index 0000000..0d53a00
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/util/composable/kairos/HydratedComposeStateOf.kt
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.util.composable.kairos
+
+import androidx.compose.runtime.mutableStateOf
+import com.android.systemui.KairosBuilder
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kairos.State
+
+@ExperimentalKairosApi
+fun <T> KairosBuilder.hydratedComposeStateOf(
+    source: State<T>,
+    initialValue: T,
+): androidx.compose.runtime.State<T> =
+    mutableStateOf(initialValue).also { state ->
+        onActivated { source.observe { state.value = it } }
+    }
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
index 735da46..cc4307a 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
@@ -19,8 +19,11 @@
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.util.time.SystemClock
 import com.android.systemui.util.time.SystemClockImpl
+import java.util.LinkedList
 import java.util.concurrent.atomic.AtomicReference
 import kotlin.math.max
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.CoroutineStart
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Job
@@ -364,3 +367,58 @@
  */
 @Suppress("NOTHING_TO_INLINE")
 inline fun Flow<Unit>.emitOnStart(): Flow<Unit> = onStart { emit(Unit) }
+
+/**
+ * Transforms a Flow<T> into a Flow<List<T>> by implementing a sliding window algorithm.
+ *
+ * This function creates a sliding window over the input Flow<T>. The window has a specified
+ * [windowDuration] and slides continuously as time progresses. The emitted List<T> contains all
+ * items from the input flow that fall within the current window.
+ *
+ * The window slides forward by the smallest possible increment to include or exclude *one* event
+ * based on the time the event was emitted (determined by the System.currentTimeMillis()). This
+ * means that consecutive emitted lists will have overlapping elements if the elements fall within
+ * the [windowDuration]
+ *
+ * @param windowDuration The duration of the sliding window.
+ * @return A Flow that emits Lists of elements within the current sliding window.
+ */
+fun <T> Flow<T>.slidingWindow(
+    windowDuration: Duration,
+    clock: SystemClock = SystemClockImpl(),
+): Flow<List<T>> = channelFlow {
+    require(windowDuration.isPositive()) { "Window duration must be positive" }
+    val buffer = LinkedList<Pair<Duration, T>>()
+
+    coroutineScope {
+        var windowAdvancementJob: Job? = null
+
+        collect { value ->
+            windowAdvancementJob?.cancel()
+            val now = clock.currentTimeMillis().milliseconds
+            buffer.addLast(now to value)
+
+            while (buffer.isNotEmpty() && buffer.first.first + windowDuration <= now) {
+                buffer.removeFirst()
+            }
+            send(buffer.map { it.second })
+
+            // Keep the window advancing through time even if the source flow isn't emitting
+            // anymore. We stop advancing the window as soon as there are no items left in the
+            // buffer.
+            windowAdvancementJob = launch {
+                while (buffer.isNotEmpty()) {
+                    val startOfWindow = clock.currentTimeMillis().milliseconds - windowDuration
+                    // Invariant: At this point, everything in the buffer is guaranteed to be in
+                    // the window, as we removed expired items above.
+                    val timeUntilNextOldest =
+                        (buffer.first.first - startOfWindow).coerceAtLeast(0.milliseconds)
+                    delay(timeUntilNextOldest)
+                    // Remove the oldest item, as it has now fallen out of the window.
+                    buffer.removeFirst()
+                    send(buffer.map { it.second })
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
index 43d1ef4..db4b8ef 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/VolumeDialogSliderViewBinder.kt
@@ -16,44 +16,38 @@
 
 package com.android.systemui.volume.dialog.sliders.ui
 
-import android.graphics.drawable.Drawable
 import android.view.View
-import androidx.compose.animation.AnimatedVisibility
-import androidx.compose.animation.core.tween
-import androidx.compose.animation.fadeIn
-import androidx.compose.animation.fadeOut
 import androidx.compose.foundation.gestures.Orientation
 import androidx.compose.foundation.interaction.DragInteraction
 import androidx.compose.foundation.interaction.MutableInteractionSource
-import androidx.compose.foundation.layout.BoxScope
-import androidx.compose.foundation.layout.padding
 import androidx.compose.foundation.layout.size
 import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.Icon
+import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
 import androidx.compose.material3.MaterialTheme
 import androidx.compose.material3.SliderDefaults
 import androidx.compose.runtime.Composable
 import androidx.compose.runtime.LaunchedEffect
 import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
-import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
 import androidx.compose.ui.input.pointer.pointerInput
 import androidx.compose.ui.platform.ComposeView
+import androidx.compose.ui.unit.DpSize
 import androidx.compose.ui.unit.dp
 import androidx.lifecycle.compose.collectAsStateWithLifecycle
 import com.android.compose.theme.PlatformTheme
-import com.android.compose.ui.graphics.painter.DrawablePainter
+import com.android.systemui.common.ui.compose.Icon
 import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter
 import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
 import com.android.systemui.res.R
 import com.android.systemui.volume.dialog.sliders.dagger.VolumeDialogSliderScope
-import com.android.systemui.volume.dialog.sliders.ui.compose.VolumeDialogSliderTrack
+import com.android.systemui.volume.dialog.sliders.ui.compose.SliderTrack
 import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogOverscrollViewModel
 import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSliderViewModel
-import com.android.systemui.volume.ui.slider.AccessibilityParams
-import com.android.systemui.volume.ui.slider.Haptics
-import com.android.systemui.volume.ui.slider.Slider
+import com.android.systemui.volume.ui.compose.slider.AccessibilityParams
+import com.android.systemui.volume.ui.compose.slider.Haptics
+import com.android.systemui.volume.ui.compose.slider.Slider
+import com.android.systemui.volume.ui.compose.slider.SliderIcon
 import javax.inject.Inject
 import kotlinx.coroutines.coroutineScope
 import kotlinx.coroutines.currentCoroutineContext
@@ -86,7 +80,7 @@
     }
 }
 
-@OptIn(ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
 @Composable
 private fun VolumeDialogSlider(
     viewModel: VolumeDialogSliderViewModel,
@@ -96,10 +90,7 @@
 ) {
     val colors =
         SliderDefaults.colors(
-            thumbColor = MaterialTheme.colorScheme.primary,
             activeTickColor = MaterialTheme.colorScheme.surfaceContainerHighest,
-            inactiveTickColor = MaterialTheme.colorScheme.primary,
-            activeTrackColor = MaterialTheme.colorScheme.primary,
             inactiveTrackColor = MaterialTheme.colorScheme.surfaceContainerHighest,
         )
     val collectedSliderStateModel by viewModel.state.collectAsStateWithLifecycle(null)
@@ -143,19 +134,39 @@
             } ?: Haptics.Disabled,
         stepDistance = 1f,
         track = { sliderState ->
-            VolumeDialogSliderTrack(
+            SliderTrack(
                 sliderState,
                 colors = colors,
                 isEnabled = !sliderStateModel.isDisabled,
-                activeTrackEndIcon = { iconsState ->
-                    VolumeIcon(sliderStateModel.icon, iconsState.isActiveTrackEndIconVisible)
+                isVertical = true,
+                activeTrackStartIcon = { iconsState ->
+                    SliderIcon(
+                        icon = {
+                            Icon(icon = sliderStateModel.icon, modifier = Modifier.size(20.dp))
+                        },
+                        isVisible = iconsState.isActiveTrackStartIconVisible,
+                    )
                 },
-                inactiveTrackEndIcon = { iconsState ->
-                    VolumeIcon(sliderStateModel.icon, !iconsState.isActiveTrackEndIconVisible)
+                inactiveTrackStartIcon = { iconsState ->
+                    SliderIcon(
+                        icon = {
+                            Icon(icon = sliderStateModel.icon, modifier = Modifier.size(20.dp))
+                        },
+                        isVisible = !iconsState.isActiveTrackStartIconVisible,
+                    )
                 },
             )
         },
-        accessibilityParams = AccessibilityParams(label = sliderStateModel.label),
+        thumb = { sliderState, interactions ->
+            SliderDefaults.Thumb(
+                sliderState = sliderState,
+                interactionSource = interactions,
+                enabled = !sliderStateModel.isDisabled,
+                colors = colors,
+                thumbSize = DpSize(52.dp, 4.dp),
+            )
+        },
+        accessibilityParams = AccessibilityParams(contentDescription = sliderStateModel.label),
         modifier =
             modifier.pointerInput(Unit) {
                 coroutineScope {
@@ -169,19 +180,3 @@
             },
     )
 }
-
-@Composable
-private fun BoxScope.VolumeIcon(
-    drawable: Drawable,
-    isVisible: Boolean,
-    modifier: Modifier = Modifier,
-) {
-    AnimatedVisibility(
-        visible = isVisible,
-        enter = fadeIn(animationSpec = tween(delayMillis = 33, durationMillis = 100)),
-        exit = fadeOut(animationSpec = tween(durationMillis = 50)),
-        modifier = modifier.align(Alignment.Center).size(40.dp).padding(10.dp),
-    ) {
-        Icon(painter = DrawablePainter(drawable), contentDescription = null)
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt
index 1dd9dda..fb8de45 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/compose/VolumeDialogSliderTrack.kt
@@ -19,6 +19,7 @@
 import androidx.compose.foundation.layout.Box
 import androidx.compose.foundation.layout.BoxScope
 import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.height
 import androidx.compose.foundation.layout.width
 import androidx.compose.material3.ExperimentalMaterial3Api
 import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
@@ -32,38 +33,47 @@
 import androidx.compose.runtime.mutableStateOf
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.layout.Layout
 import androidx.compose.ui.layout.Measurable
 import androidx.compose.ui.layout.MeasurePolicy
 import androidx.compose.ui.layout.MeasureResult
 import androidx.compose.ui.layout.MeasureScope
-import androidx.compose.ui.layout.Placeable
 import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.platform.LocalLayoutDirection
 import androidx.compose.ui.unit.Constraints
 import androidx.compose.ui.unit.Dp
+import androidx.compose.ui.unit.LayoutDirection
 import androidx.compose.ui.unit.dp
-import androidx.compose.ui.util.fastFilter
 import androidx.compose.ui.util.fastFirst
 import kotlin.math.min
 
 @Composable
 @OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
-fun VolumeDialogSliderTrack(
+fun SliderTrack(
     sliderState: SliderState,
-    colors: SliderColors,
     isEnabled: Boolean,
     modifier: Modifier = Modifier,
+    colors: SliderColors = SliderDefaults.colors(),
     thumbTrackGapSize: Dp = 6.dp,
     trackCornerSize: Dp = 12.dp,
     trackInsideCornerSize: Dp = 2.dp,
     trackSize: Dp = 40.dp,
+    isVertical: Boolean = false,
     activeTrackStartIcon: (@Composable BoxScope.(iconsState: SliderIconsState) -> Unit)? = null,
     activeTrackEndIcon: (@Composable BoxScope.(iconsState: SliderIconsState) -> Unit)? = null,
     inactiveTrackStartIcon: (@Composable BoxScope.(iconsState: SliderIconsState) -> Unit)? = null,
     inactiveTrackEndIcon: (@Composable BoxScope.(iconsState: SliderIconsState) -> Unit)? = null,
 ) {
-    val measurePolicy = remember(sliderState) { TrackMeasurePolicy(sliderState) }
+    val isRtl = LocalLayoutDirection.current == LayoutDirection.Rtl
+    val measurePolicy =
+        remember(sliderState) {
+            TrackMeasurePolicy(
+                sliderState = sliderState,
+                shouldMirrorIcons = !isVertical && isRtl || isVertical,
+                isVertical = isVertical,
+                gapSize = thumbTrackGapSize,
+            )
+        }
     Layout(
         measurePolicy = measurePolicy,
         content = {
@@ -76,33 +86,41 @@
                 drawStopIndicator = null,
                 thumbTrackGapSize = thumbTrackGapSize,
                 drawTick = { _, _ -> },
-                modifier = Modifier.width(trackSize).layoutId(Contents.Track),
+                modifier =
+                    Modifier.then(
+                            if (isVertical) {
+                                Modifier.width(trackSize)
+                            } else {
+                                Modifier.height(trackSize)
+                            }
+                        )
+                        .layoutId(Contents.Track),
             )
 
             TrackIcon(
                 icon = activeTrackStartIcon,
-                contentsId = Contents.Active.TrackStartIcon,
+                contents = Contents.Active.TrackStartIcon,
                 isEnabled = isEnabled,
                 colors = colors,
                 state = measurePolicy,
             )
             TrackIcon(
                 icon = activeTrackEndIcon,
-                contentsId = Contents.Active.TrackEndIcon,
+                contents = Contents.Active.TrackEndIcon,
                 isEnabled = isEnabled,
                 colors = colors,
                 state = measurePolicy,
             )
             TrackIcon(
                 icon = inactiveTrackStartIcon,
-                contentsId = Contents.Inactive.TrackStartIcon,
+                contents = Contents.Inactive.TrackStartIcon,
                 isEnabled = isEnabled,
                 colors = colors,
                 state = measurePolicy,
             )
             TrackIcon(
                 icon = inactiveTrackEndIcon,
-                contentsId = Contents.Inactive.TrackEndIcon,
+                contents = Contents.Inactive.TrackEndIcon,
                 isEnabled = isEnabled,
                 colors = colors,
                 state = measurePolicy,
@@ -116,24 +134,47 @@
 private fun TrackIcon(
     icon: (@Composable BoxScope.(sliderIconsState: SliderIconsState) -> Unit)?,
     isEnabled: Boolean,
-    contentsId: Contents,
+    contents: Contents,
     state: SliderIconsState,
     colors: SliderColors,
     modifier: Modifier = Modifier,
 ) {
     icon ?: return
-    Box(modifier = modifier.layoutId(contentsId).fillMaxSize()) {
-        CompositionLocalProvider(
-            LocalContentColor provides contentsId.getColor(colors, isEnabled)
-        ) {
-            icon(state)
+    /*
+    ignore icons mirroring for the rtl layouts here because icons positioning is handled by the
+    TrackMeasurePolicy. It ensures that active icons are always above the active track and the
+    same for inactive
+    */
+    val iconColor =
+        when (contents) {
+            is Contents.Inactive ->
+                if (isEnabled) {
+                    colors.inactiveTickColor
+                } else {
+                    colors.disabledInactiveTickColor
+                }
+            is Contents.Active ->
+                if (isEnabled) {
+                    colors.activeTickColor
+                } else {
+                    colors.disabledActiveTickColor
+                }
+            is Contents.Track -> {
+                error("$contents is unsupported by the TrackIcon")
+            }
         }
+    Box(modifier = modifier.layoutId(contents).fillMaxSize()) {
+        CompositionLocalProvider(LocalContentColor provides iconColor) { icon(state) }
     }
 }
 
 @OptIn(ExperimentalMaterial3Api::class)
-private class TrackMeasurePolicy(private val sliderState: SliderState) :
-    MeasurePolicy, SliderIconsState {
+private class TrackMeasurePolicy(
+    private val sliderState: SliderState,
+    private val shouldMirrorIcons: Boolean,
+    private val gapSize: Dp,
+    private val isVertical: Boolean,
+) : MeasurePolicy, SliderIconsState {
 
     private val isVisible: Map<Contents, MutableState<Boolean>> =
         mutableMapOf(
@@ -144,16 +185,16 @@
         )
 
     override val isActiveTrackStartIconVisible: Boolean
-        get() = isVisible.getValue(Contents.Active.TrackStartIcon).value
+        get() = isVisible.getValue(Contents.Active.TrackStartIcon.resolve()).value
 
     override val isActiveTrackEndIconVisible: Boolean
-        get() = isVisible.getValue(Contents.Active.TrackEndIcon).value
+        get() = isVisible.getValue(Contents.Active.TrackEndIcon.resolve()).value
 
     override val isInactiveTrackStartIconVisible: Boolean
-        get() = isVisible.getValue(Contents.Inactive.TrackStartIcon).value
+        get() = isVisible.getValue(Contents.Inactive.TrackStartIcon.resolve()).value
 
     override val isInactiveTrackEndIconVisible: Boolean
-        get() = isVisible.getValue(Contents.Inactive.TrackEndIcon).value
+        get() = isVisible.getValue(Contents.Inactive.TrackEndIcon.resolve()).value
 
     override fun MeasureScope.measure(
         measurables: List<Measurable>,
@@ -164,178 +205,196 @@
         val iconSize = min(track.width, track.height)
         val iconConstraints = constraints.copy(maxWidth = iconSize, maxHeight = iconSize)
 
-        val icons =
-            measurables
-                .fastFilter { it.layoutId != Contents.Track }
-                .associateBy(
-                    keySelector = { it.layoutId as Contents },
-                    valueTransform = { it.measure(iconConstraints) },
-                )
+        val components = buildMap {
+            put(Contents.Track, track)
+            for (measurable in measurables) {
+                // don't measure track a second time
+                if (measurable.layoutId != Contents.Track) {
+                    put(
+                        (measurable.layoutId as Contents).resolve(),
+                        measurable.measure(iconConstraints),
+                    )
+                }
+            }
+        }
 
         return layout(track.width, track.height) {
-            with(Contents.Track) {
-                performPlacing(
-                    placeable = track,
-                    width = track.width,
-                    height = track.height,
-                    sliderState = sliderState,
-                )
-            }
-
-            for (iconLayoutId in icons.keys) {
-                with(iconLayoutId) {
-                    performPlacing(
-                        placeable = icons.getValue(iconLayoutId),
-                        width = track.width,
-                        height = track.height,
-                        sliderState = sliderState,
+            val gapSizePx = gapSize.roundToPx()
+            val coercedValueAsFraction =
+                if (shouldMirrorIcons) {
+                    1 - sliderState.coercedValueAsFraction
+                } else {
+                    sliderState.coercedValueAsFraction
+                }
+            for (iconLayoutId in components.keys) {
+                val iconPlaceable = components.getValue(iconLayoutId)
+                if (isVertical) {
+                    iconPlaceable.place(
+                        0,
+                        iconLayoutId.calculatePosition(
+                            placeableDimension = iconPlaceable.height,
+                            containerDimension = track.height,
+                            gapSize = gapSizePx,
+                            coercedValueAsFraction = coercedValueAsFraction,
+                        ),
                     )
+                } else {
+                    iconPlaceable.place(
+                        iconLayoutId.calculatePosition(
+                            placeableDimension = iconPlaceable.width,
+                            containerDimension = track.width,
+                            gapSize = gapSizePx,
+                            coercedValueAsFraction = coercedValueAsFraction,
+                        ),
+                        0,
+                    )
+                }
 
-                    isVisible.getValue(iconLayoutId).value =
-                        isVisible(
-                            placeable = icons.getValue(iconLayoutId),
-                            width = track.width,
-                            height = track.height,
-                            sliderState = sliderState,
+                // isVisible is only relevant for the icons
+                if (iconLayoutId != Contents.Track) {
+                    val isVisibleState = isVisible.getValue(iconLayoutId)
+                    val newIsVisible =
+                        iconLayoutId.isVisible(
+                            placeableDimension =
+                                if (isVertical) iconPlaceable.height else iconPlaceable.width,
+                            containerDimension = if (isVertical) track.height else track.width,
+                            gapSize = gapSizePx,
+                            coercedValueAsFraction = coercedValueAsFraction,
                         )
+                    if (isVisibleState.value != newIsVisible) {
+                        isVisibleState.value = newIsVisible
+                    }
                 }
             }
         }
     }
+
+    private fun Contents.resolve(): Contents {
+        return if (shouldMirrorIcons) {
+            mirrored
+        } else {
+            this
+        }
+    }
 }
 
-@OptIn(ExperimentalMaterial3Api::class)
 private sealed interface Contents {
 
     data object Track : Contents {
-        override fun Placeable.PlacementScope.performPlacing(
-            placeable: Placeable,
-            width: Int,
-            height: Int,
-            sliderState: SliderState,
-        ) = placeable.place(x = 0, y = 0)
+
+        override val mirrored: Contents
+            get() = error("unsupported for Track")
+
+        override fun calculatePosition(
+            placeableDimension: Int,
+            containerDimension: Int,
+            gapSize: Int,
+            coercedValueAsFraction: Float,
+        ): Int = 0
 
         override fun isVisible(
-            placeable: Placeable,
-            width: Int,
-            height: Int,
-            sliderState: SliderState,
-        ) = true
-
-        override fun getColor(sliderColors: SliderColors, isEnabled: Boolean): Color =
-            error("Unsupported")
+            placeableDimension: Int,
+            containerDimension: Int,
+            gapSize: Int,
+            coercedValueAsFraction: Float,
+        ): Boolean = true
     }
 
     interface Active : Contents {
-        override fun getColor(sliderColors: SliderColors, isEnabled: Boolean): Color {
-            return if (isEnabled) {
-                sliderColors.activeTickColor
-            } else {
-                sliderColors.disabledActiveTickColor
-            }
-        }
+
+        override fun isVisible(
+            placeableDimension: Int,
+            containerDimension: Int,
+            gapSize: Int,
+            coercedValueAsFraction: Float,
+        ): Boolean =
+            (containerDimension * coercedValueAsFraction - gapSize).toInt() > placeableDimension
 
         data object TrackStartIcon : Active {
-            override fun Placeable.PlacementScope.performPlacing(
-                placeable: Placeable,
-                width: Int,
-                height: Int,
-                sliderState: SliderState,
-            ) =
-                placeable.place(
-                    x = 0,
-                    y = (height * (1 - sliderState.coercedValueAsFraction)).toInt(),
-                )
 
-            override fun isVisible(
-                placeable: Placeable,
-                width: Int,
-                height: Int,
-                sliderState: SliderState,
-            ): Boolean = (height * (sliderState.coercedValueAsFraction)).toInt() > placeable.height
+            override val mirrored: Contents
+                get() = Inactive.TrackEndIcon
+
+            override fun calculatePosition(
+                placeableDimension: Int,
+                containerDimension: Int,
+                gapSize: Int,
+                coercedValueAsFraction: Float,
+            ): Int = 0
         }
 
         data object TrackEndIcon : Active {
-            override fun Placeable.PlacementScope.performPlacing(
-                placeable: Placeable,
-                width: Int,
-                height: Int,
-                sliderState: SliderState,
-            ) = placeable.place(x = 0, y = (height - placeable.height))
 
-            override fun isVisible(
-                placeable: Placeable,
-                width: Int,
-                height: Int,
-                sliderState: SliderState,
-            ): Boolean = (height * (sliderState.coercedValueAsFraction)).toInt() > placeable.height
+            override val mirrored: Contents
+                get() = Inactive.TrackStartIcon
+
+            override fun calculatePosition(
+                placeableDimension: Int,
+                containerDimension: Int,
+                gapSize: Int,
+                coercedValueAsFraction: Float,
+            ): Int =
+                (containerDimension * coercedValueAsFraction - placeableDimension - gapSize).toInt()
         }
     }
 
     interface Inactive : Contents {
 
-        override fun getColor(sliderColors: SliderColors, isEnabled: Boolean): Color {
-            return if (isEnabled) {
-                sliderColors.inactiveTickColor
-            } else {
-                sliderColors.disabledInactiveTickColor
-            }
-        }
+        override fun isVisible(
+            placeableDimension: Int,
+            containerDimension: Int,
+            gapSize: Int,
+            coercedValueAsFraction: Float,
+        ): Boolean =
+            containerDimension - (containerDimension * coercedValueAsFraction + gapSize) >
+                placeableDimension
 
         data object TrackStartIcon : Inactive {
-            override fun Placeable.PlacementScope.performPlacing(
-                placeable: Placeable,
-                width: Int,
-                height: Int,
-                sliderState: SliderState,
-            ) {
-                placeable.place(x = 0, y = 0)
-            }
 
-            override fun isVisible(
-                placeable: Placeable,
-                width: Int,
-                height: Int,
-                sliderState: SliderState,
-            ): Boolean =
-                (height * (1 - sliderState.coercedValueAsFraction)).toInt() > placeable.height
+            override val mirrored: Contents
+                get() = Active.TrackEndIcon
+
+            override fun calculatePosition(
+                placeableDimension: Int,
+                containerDimension: Int,
+                gapSize: Int,
+                coercedValueAsFraction: Float,
+            ): Int = (containerDimension * coercedValueAsFraction + gapSize).toInt()
         }
 
         data object TrackEndIcon : Inactive {
-            override fun Placeable.PlacementScope.performPlacing(
-                placeable: Placeable,
-                width: Int,
-                height: Int,
-                sliderState: SliderState,
-            ) {
-                placeable.place(
-                    x = 0,
-                    y =
-                        (height * (1 - sliderState.coercedValueAsFraction)).toInt() -
-                            placeable.height,
-                )
-            }
 
-            override fun isVisible(
-                placeable: Placeable,
-                width: Int,
-                height: Int,
-                sliderState: SliderState,
-            ): Boolean =
-                (height * (1 - sliderState.coercedValueAsFraction)).toInt() > placeable.height
+            override val mirrored: Contents
+                get() = Active.TrackStartIcon
+
+            override fun calculatePosition(
+                placeableDimension: Int,
+                containerDimension: Int,
+                gapSize: Int,
+                coercedValueAsFraction: Float,
+            ): Int = containerDimension - placeableDimension
         }
     }
 
-    fun Placeable.PlacementScope.performPlacing(
-        placeable: Placeable,
-        width: Int,
-        height: Int,
-        sliderState: SliderState,
-    )
+    fun calculatePosition(
+        placeableDimension: Int,
+        containerDimension: Int,
+        gapSize: Int,
+        coercedValueAsFraction: Float,
+    ): Int
 
-    fun isVisible(placeable: Placeable, width: Int, height: Int, sliderState: SliderState): Boolean
+    fun isVisible(
+        placeableDimension: Int,
+        containerDimension: Int,
+        gapSize: Int,
+        coercedValueAsFraction: Float,
+    ): Boolean
 
-    fun getColor(sliderColors: SliderColors, isEnabled: Boolean): Color
+    /**
+     * [Contents] that is visually on the opposite side of the current one on the slider. This is
+     * handy when dealing with the rtl layouts
+     */
+    val mirrored: Contents
 }
 
 /** Provides visibility state for each of the Slider's icons. */
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt
index ef147c7..3712276 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProvider.kt
@@ -18,32 +18,36 @@
 
 import android.annotation.SuppressLint
 import android.content.Context
-import android.graphics.drawable.Drawable
 import android.media.AudioManager
 import androidx.annotation.DrawableRes
 import com.android.settingslib.R as SettingsR
 import com.android.settingslib.volume.domain.interactor.AudioVolumeInteractor
 import com.android.settingslib.volume.shared.model.AudioStream
 import com.android.settingslib.volume.shared.model.RingerMode
+import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.res.R
 import com.android.systemui.statusbar.policy.domain.interactor.ZenModeInteractor
 import com.android.systemui.statusbar.policy.domain.model.ActiveZenModes
 import javax.inject.Inject
+import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.withContext
 
 @SuppressLint("UseCompatLoadingForDrawables")
 class VolumeDialogSliderIconProvider
 @Inject
 constructor(
     private val context: Context,
+    @UiBackground private val uiBackgroundContext: CoroutineContext,
     private val zenModeInteractor: ZenModeInteractor,
     private val audioVolumeInteractor: AudioVolumeInteractor,
 ) {
 
-    fun getAudioSharingIcon(isMuted: Boolean): Flow<Drawable> {
+    fun getAudioSharingIcon(isMuted: Boolean): Flow<Icon.Loaded> {
         return flow {
             val iconRes =
                 if (isMuted) {
@@ -51,11 +55,12 @@
                 } else {
                     R.drawable.ic_volume_media_bt
                 }
-            emit(context.getDrawable(iconRes)!!)
+            val drawable = withContext(uiBackgroundContext) { context.getDrawable(iconRes)!! }
+            emit(Icon.Loaded(drawable = drawable, contentDescription = null, res = iconRes))
         }
     }
 
-    fun getCastIcon(isMuted: Boolean): Flow<Drawable> {
+    fun getCastIcon(isMuted: Boolean): Flow<Icon.Loaded> {
         return flow {
             val iconRes =
                 if (isMuted) {
@@ -63,7 +68,8 @@
                 } else {
                     SettingsR.drawable.ic_volume_remote
                 }
-            emit(context.getDrawable(iconRes)!!)
+            val drawable = withContext(uiBackgroundContext) { context.getDrawable(iconRes)!! }
+            emit(Icon.Loaded(drawable = drawable, contentDescription = null, res = iconRes))
         }
     }
 
@@ -74,15 +80,18 @@
         levelMax: Int,
         isMuted: Boolean,
         isRoutedToBluetooth: Boolean,
-    ): Flow<Drawable> {
+    ): Flow<Icon.Loaded> {
         return combine(
             zenModeInteractor.activeModesBlockingStream(stream),
             ringerModeForStream(stream),
         ) { activeModesBlockingStream, ringerMode ->
             if (activeModesBlockingStream?.mainMode?.icon != null) {
-                return@combine activeModesBlockingStream.mainMode.icon.drawable
+                Icon.Loaded(
+                    drawable = activeModesBlockingStream.mainMode.icon.drawable,
+                    contentDescription = null,
+                )
             } else {
-                context.getDrawable(
+                val iconRes =
                     getIconRes(
                         stream,
                         level,
@@ -92,7 +101,8 @@
                         isRoutedToBluetooth,
                         ringerMode,
                     )
-                )!!
+                val drawable = withContext(uiBackgroundContext) { context.getDrawable(iconRes)!! }
+                Icon.Loaded(drawable = drawable, contentDescription = null, res = iconRes)
             }
         }
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.kt
index 88a061f..ed59598 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderStateModel.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.volume.dialog.sliders.ui.viewmodel
 
 import android.content.Context
-import android.graphics.drawable.Drawable
+import com.android.systemui.common.shared.model.Icon
 import com.android.systemui.volume.dialog.shared.model.VolumeDialogStreamModel
 import com.android.systemui.volume.dialog.shared.model.streamLabel
 
@@ -25,14 +25,14 @@
     val value: Float,
     val isDisabled: Boolean,
     val valueRange: ClosedFloatingPointRange<Float>,
-    val icon: Drawable,
+    val icon: Icon.Loaded,
     val label: String,
 )
 
 fun VolumeDialogStreamModel.toStateModel(
     context: Context,
     isDisabled: Boolean,
-    icon: Drawable,
+    icon: Icon.Loaded,
 ): VolumeDialogSliderStateModel {
     return VolumeDialogSliderStateModel(
         value = level.toFloat(),
diff --git a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
index 1f11f2d..faf0abd 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderViewModel.kt
@@ -40,7 +40,6 @@
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.filter
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.flow.flatMapLatest
@@ -78,11 +77,16 @@
 
     private val userVolumeUpdates = MutableStateFlow<VolumeUpdate?>(null)
     private val model: Flow<VolumeDialogStreamModel> =
-        interactor.slider
-            .filter {
-                val currentVolumeUpdate = userVolumeUpdates.value ?: return@filter true
+        combine(interactor.slider, userVolumeUpdates) { model, currentVolumeUpdate ->
+                currentVolumeUpdate ?: return@combine model
                 val lastVolumeUpdateTime = currentVolumeUpdate.timestampMillis
-                getTimestampMillis() - lastVolumeUpdateTime > VOLUME_UPDATE_GRACE_PERIOD
+                val shouldIgnoreUpdates =
+                    getTimestampMillis() - lastVolumeUpdateTime < VOLUME_UPDATE_GRACE_PERIOD
+                if (shouldIgnoreUpdates) {
+                    model.copy(level = currentVolumeUpdate.newVolumeLevel)
+                } else {
+                    model
+                }
             }
             .stateIn(coroutineScope, SharingStarted.Eagerly, null)
             .filterNotNull()
@@ -104,11 +108,9 @@
                                     isMuted = isMuted,
                                     isRoutedToBluetooth = routedToBluetooth,
                                 )
-
                             is VolumeDialogSliderType.RemoteMediaStream -> {
                                 volumeDialogSliderIconProvider.getCastIcon(isMuted)
                             }
-
                             is VolumeDialogSliderType.AudioSharingStream -> {
                                 volumeDialogSliderIconProvider.getAudioSharingIcon(isMuted)
                             }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt
index 3d98eba..f645267 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModel.kt
@@ -16,9 +16,11 @@
 
 package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel
 
+import android.content.Context
 import com.android.internal.logging.UiEventLogger
 import com.android.systemui.Flags
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter
 import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
 import com.android.systemui.res.R
@@ -28,6 +30,7 @@
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlin.coroutines.CoroutineContext
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -39,11 +42,14 @@
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.withContext
 
 class AudioSharingStreamSliderViewModel
 @AssistedInject
 constructor(
+    private val context: Context,
     @Assisted private val coroutineScope: CoroutineScope,
+    @UiBackground private val uiBackgroundContext: CoroutineContext,
     private val audioSharingInteractor: AudioSharingInteractor,
     private val uiEventLogger: UiEventLogger,
     private val hapticsViewModelFactory: SliderHapticsViewModel.Factory,
@@ -51,6 +57,12 @@
 ) : SliderViewModel {
     private val volumeChanges = MutableStateFlow<Int?>(null)
 
+    private val audioSharingIcon =
+        Icon.Loaded(
+            drawable = context.getDrawable(R.drawable.ic_volume_media_bt)!!,
+            contentDescription = null,
+            res = R.drawable.ic_volume_media_bt,
+        )
     override val slider: StateFlow<SliderState> =
         combine(
                 audioSharingInteractor.volume.distinctUntilChanged().onEach {
@@ -62,16 +74,17 @@
                 if (volume == null) {
                     SliderState.Empty
                 } else {
-
-                    State(
-                        value = volume.toFloat(),
-                        valueRange =
-                            audioSharingInteractor.volumeMin.toFloat()..audioSharingInteractor
-                                    .volumeMax
-                                    .toFloat(),
-                        icon = Icon.Resource(R.drawable.ic_volume_media_bt, null),
-                        label = deviceName,
-                    )
+                    withContext(uiBackgroundContext) {
+                        State(
+                            value = volume.toFloat(),
+                            valueRange =
+                                audioSharingInteractor.volumeMin.toFloat()..audioSharingInteractor
+                                        .volumeMax
+                                        .toFloat(),
+                            icon = audioSharingIcon,
+                            label = deviceName,
+                        )
+                    }
                 }
             }
             .stateIn(coroutineScope, SharingStarted.Eagerly, SliderState.Empty)
@@ -107,7 +120,7 @@
     private data class State(
         override val value: Float,
         override val valueRange: ClosedFloatingPointRange<Float>,
-        override val icon: Icon,
+        override val icon: Icon.Loaded?,
         override val label: String,
     ) : SliderState {
         override val hapticFilter: SliderHapticFeedbackFilter
@@ -116,7 +129,7 @@
         override val isEnabled: Boolean
             get() = true
 
-        override val a11yStep: Float
+        override val step: Float
             get() = 1f
 
         override val disabledMessage: String?
@@ -125,6 +138,9 @@
         override val isMutable: Boolean
             get() = false
 
+        override val a11yContentDescription: String
+            get() = label
+
         override val a11yClickDescription: String?
             get() = null
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
index 9d32285..9fe0ad4 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModel.kt
@@ -19,6 +19,7 @@
 import android.content.Context
 import android.media.AudioManager
 import android.util.Log
+import androidx.annotation.DrawableRes
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.internal.logging.UiEventLogger
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
@@ -28,6 +29,7 @@
 import com.android.settingslib.volume.shared.model.RingerMode
 import com.android.systemui.Flags
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter
 import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
 import com.android.systemui.modes.shared.ModesUiIcons
@@ -40,18 +42,21 @@
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlin.coroutines.CoroutineContext
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.filterNotNull
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.withContext
 
 /** Models a particular slider state. */
 class AudioStreamSliderViewModel
@@ -59,10 +64,11 @@
 constructor(
     @Assisted private val audioStreamWrapper: FactoryAudioStreamWrapper,
     @Assisted private val coroutineScope: CoroutineScope,
+    @UiBackground private val uiBackgroundContext: CoroutineContext,
     private val context: Context,
     private val audioVolumeInteractor: AudioVolumeInteractor,
     private val zenModeInteractor: ZenModeInteractor,
-    private val audioSharingInteractor: AudioSharingInteractor,
+    audioSharingInteractor: AudioSharingInteractor,
     private val uiEventLogger: UiEventLogger,
     private val volumePanelLogger: VolumePanelLogger,
     private val hapticsViewModelFactory: SliderHapticsViewModel.Factory,
@@ -148,57 +154,69 @@
             null
         }
 
-    private fun AudioStreamModel.toState(
+    private suspend fun AudioStreamModel.toState(
         isEnabled: Boolean,
         ringerMode: RingerMode,
         disabledMessage: String?,
         inAudioSharing: Boolean,
         primaryDevice: CachedBluetoothDevice?,
-    ): State {
-        val label = getLabel(inAudioSharing, primaryDevice)
-        val icon = getIcon(ringerMode, inAudioSharing)
-        return State(
-            value = volume.toFloat(),
-            valueRange = volumeRange.first.toFloat()..volumeRange.last.toFloat(),
-            hapticFilter = createHapticFilter(ringerMode),
-            icon = icon,
-            label = label,
-            disabledMessage = disabledMessage,
-            isEnabled = isEnabled,
-            a11yStep = volumeRange.step.toFloat(),
-            a11yClickDescription =
-                if (isAffectedByMute) {
-                    context.getString(
-                        if (isMuted) {
-                            R.string.volume_panel_hint_unmute
-                        } else {
-                            R.string.volume_panel_hint_mute
-                        },
-                        label,
-                    )
-                } else {
-                    null
-                },
-            a11yStateDescription =
-                if (isMuted) {
-                    context.getString(
-                        if (isAffectedByRingerMode) {
-                            if (ringerMode.value == AudioManager.RINGER_MODE_VIBRATE) {
-                                R.string.volume_panel_hint_vibrate
+    ): State =
+        withContext(uiBackgroundContext) {
+            val label = getLabel(inAudioSharing, primaryDevice)
+            State(
+                value = volume.toFloat(),
+                valueRange = volumeRange.first.toFloat()..volumeRange.last.toFloat(),
+                hapticFilter = createHapticFilter(ringerMode),
+                icon = getIcon(ringerMode, inAudioSharing),
+                label = label,
+                disabledMessage = disabledMessage,
+                isEnabled = isEnabled,
+                step = volumeRange.step.toFloat(),
+                a11yContentDescription =
+                    if (isEnabled) {
+                        label
+                    } else {
+                        disabledMessage?.let {
+                            context.getString(
+                                R.string.volume_slider_disabled_message_template,
+                                label,
+                                disabledMessage,
+                            )
+                        } ?: label
+                    },
+                a11yClickDescription =
+                    if (isAffectedByMute) {
+                        context.getString(
+                            if (isMuted) {
+                                R.string.volume_panel_hint_unmute
+                            } else {
+                                R.string.volume_panel_hint_mute
+                            },
+                            label,
+                        )
+                    } else {
+                        null
+                    },
+                a11yStateDescription =
+                    if (isMuted) {
+                        context.getString(
+                            if (isAffectedByRingerMode) {
+                                if (ringerMode.value == AudioManager.RINGER_MODE_VIBRATE) {
+                                    R.string.volume_panel_hint_vibrate
+                                } else {
+                                    R.string.volume_panel_hint_muted
+                                }
                             } else {
                                 R.string.volume_panel_hint_muted
                             }
-                        } else {
-                            R.string.volume_panel_hint_muted
-                        }
-                    )
-                } else {
-                    null
-                },
-            audioStreamModel = this,
-            isMutable = isAffectedByMute,
-        )
-    }
+                        )
+                    } else {
+                        null
+                    },
+                audioStreamModel = this@toState,
+                isMutable = isAffectedByMute,
+            )
+        }
 
     private fun AudioStreamModel.createHapticFilter(
         ringerMode: RingerMode
@@ -220,12 +238,14 @@
                 flowOf(context.getString(R.string.stream_notification_unavailable))
             } else {
                 if (zenModeInteractor.canBeBlockedByZenMode(audioStream)) {
-                    zenModeInteractor.activeModesBlockingStream(audioStream).map { blockingZenModes
-                        ->
-                        blockingZenModes.mainMode?.name?.let {
-                            context.getString(R.string.stream_unavailable_by_modes, it)
-                        } ?: context.getString(R.string.stream_unavailable_by_unknown)
-                    }
+                    zenModeInteractor
+                        .activeModesBlockingStream(audioStream)
+                        .map { blockingZenModes ->
+                            blockingZenModes.mainMode?.name?.let {
+                                context.getString(R.string.stream_unavailable_by_modes, it)
+                            } ?: context.getString(R.string.stream_unavailable_by_unknown)
+                        }
+                        .distinctUntilChanged()
                 } else {
                     flowOf(context.getString(R.string.stream_unavailable_by_unknown))
                 }
@@ -256,8 +276,11 @@
                 ?: error("No label for the stream: $audioStream")
         }
 
-    private fun AudioStreamModel.getIcon(ringerMode: RingerMode, inAudioSharing: Boolean): Icon {
-        val iconRes =
+    private fun AudioStreamModel.getIcon(
+        ringerMode: RingerMode,
+        inAudioSharing: Boolean,
+    ): Icon.Loaded {
+        val iconResource: Int =
             if (isMuted) {
                 if (isAffectedByRingerMode) {
                     if (ringerMode.value == AudioManager.RINGER_MODE_VIBRATE) {
@@ -272,14 +295,21 @@
                             inAudioSharing
                     ) {
                         R.drawable.ic_volume_media_bt_mute
-                    } else R.drawable.ic_volume_off
+                    } else {
+                        R.drawable.ic_volume_off
+                    }
                 }
             } else {
                 getIconByStream(audioStream, inAudioSharing)
             }
-        return Icon.Resource(iconRes, null)
+        return Icon.Loaded(
+            drawable = context.getDrawable(iconResource)!!,
+            contentDescription = null,
+            res = iconResource,
+        )
     }
 
+    @DrawableRes
     private fun getIconByStream(audioStream: AudioStream, inAudioSharing: Boolean): Int =
         when (audioStream.value) {
             AudioManager.STREAM_MUSIC ->
@@ -302,14 +332,15 @@
     private data class State(
         override val value: Float,
         override val valueRange: ClosedFloatingPointRange<Float>,
+        override val step: Float,
         override val hapticFilter: SliderHapticFeedbackFilter,
-        override val icon: Icon,
+        override val icon: Icon.Loaded?,
         override val label: String,
         override val disabledMessage: String?,
         override val isEnabled: Boolean,
-        override val a11yStep: Float,
         override val a11yClickDescription: String?,
         override val a11yStateDescription: String?,
+        override val a11yContentDescription: String,
         override val isMutable: Boolean,
         val audioStreamModel: AudioStreamModel,
     ) : SliderState
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt
index a6c8091..01810f9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModel.kt
@@ -21,6 +21,7 @@
 import com.android.app.tracing.coroutines.launchTraced as launch
 import com.android.systemui.Flags
 import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.dagger.qualifiers.UiBackground
 import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter
 import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
 import com.android.systemui.res.R
@@ -30,30 +31,40 @@
 import dagger.assisted.Assisted
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
+import kotlin.coroutines.CoroutineContext
 import kotlin.math.roundToInt
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.StateFlow
 import kotlinx.coroutines.flow.mapNotNull
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.withContext
 
 class CastVolumeSliderViewModel
 @AssistedInject
 constructor(
     @Assisted private val session: MediaDeviceSession,
     @Assisted private val coroutineScope: CoroutineScope,
+    @UiBackground private val uiBackgroundContext: CoroutineContext,
     private val context: Context,
     private val mediaDeviceSessionInteractor: MediaDeviceSessionInteractor,
     private val hapticsViewModelFactory: SliderHapticsViewModel.Factory,
     private val volumePanelLogger: VolumePanelLogger,
 ) : SliderViewModel {
 
+    private val castLabel = context.getString(R.string.media_device_cast)
+    private val castIcon =
+        Icon.Loaded(
+            drawable = context.getDrawable(R.drawable.ic_cast)!!,
+            contentDescription = null,
+            res = R.drawable.ic_cast,
+        )
     override val slider: StateFlow<SliderState> =
         mediaDeviceSessionInteractor
             .playbackInfo(session)
             .mapNotNull {
                 volumePanelLogger.onVolumeUpdateReceived(session.sessionToken, it.currentVolume)
-                it.getCurrentState()
+                withContext(uiBackgroundContext) { it.getCurrentState() }
             }
             .stateIn(coroutineScope, SharingStarted.Eagerly, SliderState.Empty)
 
@@ -83,20 +94,20 @@
         return State(
             value = currentVolume.toFloat(),
             valueRange = volumeRange.first.toFloat()..volumeRange.last.toFloat(),
-            icon = Icon.Resource(R.drawable.ic_cast, null),
-            label = context.getString(R.string.media_device_cast),
+            icon = castIcon,
+            label = castLabel,
             isEnabled = true,
-            a11yStep = 1f,
+            step = 1f,
         )
     }
 
     private data class State(
         override val value: Float,
         override val valueRange: ClosedFloatingPointRange<Float>,
-        override val icon: Icon,
+        override val icon: Icon.Loaded?,
         override val label: String,
         override val isEnabled: Boolean,
-        override val a11yStep: Float,
+        override val step: Float,
     ) : SliderState {
         override val hapticFilter: SliderHapticFeedbackFilter
             get() = SliderHapticFeedbackFilter()
@@ -107,6 +118,9 @@
         override val isMutable: Boolean
             get() = false
 
+        override val a11yContentDescription: String
+            get() = label
+
         override val a11yClickDescription: String?
             get() = null
 
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderState.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderState.kt
index 4bc237b..b1d18340 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderState.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/SliderState.kt
@@ -27,18 +27,17 @@
 sealed interface SliderState {
     val value: Float
     val valueRange: ClosedFloatingPointRange<Float>
+    val step: Float
     val hapticFilter: SliderHapticFeedbackFilter
 
-    val icon: Icon?
+    // Force preloaded icon
+    val icon: Icon.Loaded?
     val isEnabled: Boolean
     val label: String
-    /**
-     * A11y slider controls works by adjusting one step up or down. The default slider step isn't
-     * enough to trigger rounding to the correct value.
-     */
-    val a11yStep: Float
+
     val a11yClickDescription: String?
     val a11yStateDescription: String?
+    val a11yContentDescription: String
     val disabledMessage: String?
     val isMutable: Boolean
 
@@ -46,12 +45,13 @@
         override val value: Float = 0f
         override val valueRange: ClosedFloatingPointRange<Float> = 0f..1f
         override val hapticFilter = SliderHapticFeedbackFilter()
-        override val icon: Icon? = null
+        override val icon: Icon.Loaded? = null
         override val label: String = ""
         override val disabledMessage: String? = null
-        override val a11yStep: Float = 0f
+        override val step: Float = 0f
         override val a11yClickDescription: String? = null
         override val a11yStateDescription: String? = null
+        override val a11yContentDescription: String = label
         override val isEnabled: Boolean = true
         override val isMutable: Boolean = false
     }
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ui/slider/Slider.kt b/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/Slider.kt
similarity index 90%
rename from packages/SystemUI/src/com/android/systemui/volume/ui/slider/Slider.kt
rename to packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/Slider.kt
index f6582a0..54d2f79 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ui/slider/Slider.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/Slider.kt
@@ -16,7 +16,7 @@
 
 @file:OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
 
-package com.android.systemui.volume.ui.slider
+package com.android.systemui.volume.ui.compose.slider
 
 import androidx.compose.animation.core.Animatable
 import androidx.compose.animation.core.Spring
@@ -40,7 +40,6 @@
 import androidx.compose.runtime.setValue
 import androidx.compose.runtime.snapshotFlow
 import androidx.compose.ui.Modifier
-import androidx.compose.ui.res.stringResource
 import androidx.compose.ui.semantics.ProgressBarRangeInfo
 import androidx.compose.ui.semantics.SemanticsPropertyReceiver
 import androidx.compose.ui.semantics.clearAndSetSemantics
@@ -52,7 +51,6 @@
 import com.android.systemui.haptics.slider.SliderHapticFeedbackFilter
 import com.android.systemui.haptics.slider.compose.ui.SliderHapticsViewModel
 import com.android.systemui.lifecycle.rememberViewModel
-import com.android.systemui.res.R
 import com.android.systemui.volume.haptics.ui.VolumeHapticsConfigsProvider
 import kotlin.math.round
 import kotlinx.coroutines.Job
@@ -63,8 +61,6 @@
 
 private val defaultSpring =
     SpringSpec<Float>(dampingRatio = Spring.DampingRatioNoBouncy, stiffness = Spring.StiffnessHigh)
-private val defaultTrack: @Composable (SliderState) -> Unit =
-    @Composable { SliderDefaults.Track(it) }
 
 @Composable
 fun Slider(
@@ -81,7 +77,14 @@
     haptics: Haptics = Haptics.Disabled,
     isVertical: Boolean = false,
     isReverseDirection: Boolean = false,
-    track: (@Composable (SliderState) -> Unit)? = null,
+    track: (@Composable (SliderState) -> Unit) = { SliderDefaults.Track(it) },
+    thumb: (@Composable (SliderState, MutableInteractionSource) -> Unit) = { _, _ ->
+        SliderDefaults.Thumb(
+            interactionSource = interactionSource,
+            colors = colors,
+            enabled = isEnabled,
+        )
+    },
 ) {
     require(stepDistance >= 0) { "stepDistance must not be negative" }
     val coroutineScope = rememberCoroutineScope()
@@ -108,7 +111,8 @@
         }
     }
     val semantics =
-        accessibilityParams.createSemantics(
+        createSemantics(
+            accessibilityParams,
             animatable.targetValue,
             valueRange,
             valueChange,
@@ -140,7 +144,8 @@
             reverseDirection = isReverseDirection,
             interactionSource = interactionSource,
             colors = colors,
-            track = track ?: defaultTrack,
+            track = track,
+            thumb = { thumb(it, interactionSource) },
             modifier = modifier.clearAndSetSemantics(semantics),
         )
     } else {
@@ -149,7 +154,8 @@
             enabled = isEnabled,
             interactionSource = interactionSource,
             colors = colors,
-            track = track ?: defaultTrack,
+            track = track,
+            thumb = { thumb(it, interactionSource) },
             modifier = modifier.clearAndSetSemantics(semantics),
         )
     }
@@ -167,24 +173,18 @@
     return Math.round(coercedValue / stepDistance) * stepDistance
 }
 
-@Composable
-private fun AccessibilityParams.createSemantics(
+private fun createSemantics(
+    params: AccessibilityParams,
     value: Float,
     valueRange: ClosedFloatingPointRange<Float>,
     onValueChanged: (Float) -> Unit,
     isEnabled: Boolean,
     stepDistance: Float,
 ): SemanticsPropertyReceiver.() -> Unit {
-    val semanticsContentDescription =
-        disabledMessage
-            ?.takeIf { !isEnabled }
-            ?.let { message ->
-                stringResource(R.string.volume_slider_disabled_message_template, label, message)
-            } ?: label
     return {
-        contentDescription = semanticsContentDescription
+        contentDescription = params.contentDescription
         if (isEnabled) {
-            currentStateDescription?.let { stateDescription = it }
+            params.stateDescription?.let { stateDescription = it }
             progressBarRangeInfo = ProgressBarRangeInfo(value, valueRange)
         } else {
             disabled()
@@ -253,9 +253,8 @@
 }
 
 data class AccessibilityParams(
-    val label: String,
-    val currentStateDescription: String? = null,
-    val disabledMessage: String? = null,
+    val contentDescription: String,
+    val stateDescription: String? = null,
 )
 
 sealed interface Haptics {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt b/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt
new file mode 100644
index 0000000..fd8f477
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/ui/compose/slider/SliderIcon.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.volume.ui.compose.slider
+
+import androidx.compose.animation.AnimatedVisibility
+import androidx.compose.animation.core.tween
+import androidx.compose.animation.fadeIn
+import androidx.compose.animation.fadeOut
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.BoxScope
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+
+@Composable
+fun SliderIcon(
+    icon: @Composable BoxScope.() -> Unit,
+    isVisible: Boolean,
+    modifier: Modifier = Modifier,
+) {
+    Box(contentAlignment = Alignment.Center, modifier = modifier.fillMaxSize()) {
+        AnimatedVisibility(
+            visible = isVisible,
+            enter = fadeIn(animationSpec = tween(delayMillis = 33, durationMillis = 100)),
+            exit = fadeOut(animationSpec = tween(durationMillis = 50)),
+        ) {
+            icon()
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
index dd1c11d..e9180df 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/dagger/WalletModule.java
@@ -28,9 +28,9 @@
 import com.android.systemui.qs.shared.model.TileCategory;
 import com.android.systemui.qs.tileimpl.QSTileImpl;
 import com.android.systemui.qs.tiles.QuickAccessWalletTile;
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig;
-import com.android.systemui.qs.tiles.viewmodel.QSTilePolicy;
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig;
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig;
+import com.android.systemui.qs.tiles.base.shared.model.QSTilePolicy;
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig;
 import com.android.systemui.res.R;
 import com.android.systemui.wallet.controller.WalletContextualLocationsService;
 import com.android.systemui.wallet.ui.WalletActivity;
diff --git a/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt
index 06532bc..fd642f9 100644
--- a/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/window/ui/WindowRootViewBinder.kt
@@ -59,6 +59,15 @@
             ) { viewModel ->
                 try {
                     Log.d(TAG, "Launching coroutines that update window root view state")
+                    launchTraced("early-wakeup") {
+                        viewModel.isPersistentEarlyWakeupRequired.collect { wakeupRequired ->
+                            blurUtils.setPersistentEarlyWakeup(
+                                wakeupRequired,
+                                view.rootView?.viewRootImpl,
+                            )
+                        }
+                    }
+
                     launchTraced("WindowBlur") {
                         var wasUpdateScheduledForThisFrame = false
                         var lastScheduledBlurRadius = 0
diff --git a/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt
index e60e853..e4b3ec7 100644
--- a/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModel.kt
@@ -19,13 +19,16 @@
 import android.os.Build
 import android.util.Log
 import com.android.systemui.Flags
+import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
 import com.android.systemui.keyguard.ui.transitions.GlanceableHubTransition
 import com.android.systemui.keyguard.ui.transitions.PrimaryBouncerTransition
+import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.window.domain.interactor.WindowRootViewBlurInteractor
 import dagger.assisted.AssistedFactory
 import dagger.assisted.AssistedInject
 import kotlinx.coroutines.ExperimentalCoroutinesApi
 import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
 import kotlinx.coroutines.flow.distinctUntilChanged
 import kotlinx.coroutines.flow.flatMapLatest
 import kotlinx.coroutines.flow.flowOf
@@ -41,6 +44,8 @@
     primaryBouncerTransitions: Set<@JvmSuppressWildcards PrimaryBouncerTransition>,
     glanceableHubTransitions: Set<@JvmSuppressWildcards GlanceableHubTransition>,
     private val blurInteractor: WindowRootViewBlurInteractor,
+    private val keyguardInteractor: KeyguardInteractor,
+    private val shadeInteractor: ShadeInteractor,
 ) {
 
     private val bouncerBlurRadiusFlows =
@@ -70,6 +75,24 @@
             }
         }
 
+    val isPersistentEarlyWakeupRequired =
+        blurInteractor.isBlurCurrentlySupported
+            .flatMapLatest { blurSupported ->
+                if (blurSupported) {
+                    combine(
+                        keyguardInteractor.isKeyguardShowing,
+                        shadeInteractor.isUserInteracting,
+                        shadeInteractor.isAnyExpanded,
+                    ) { keyguardShowing, userDraggingShade, anyExpanded ->
+                        keyguardShowing || userDraggingShade || anyExpanded
+                    }
+                } else {
+                    flowOf(false)
+                }
+            }
+            .distinctUntilChanged()
+            .logIfPossible("isPersistentEarlyWakeupRequired")
+
     val isBlurOpaque =
         blurInteractor.isBlurCurrentlySupported.flatMapLatest { blurSupported ->
             if (blurSupported) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearanceTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearanceTest.java
index 146488b..108f3ae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearanceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewAppearanceTest.java
@@ -69,4 +69,25 @@
 
         assertThat(end_y).isEqualTo(end_y);
     }
+
+    @Test
+    public void avoidVerticalDisplayCutout_doesNotExceedTopBounds() {
+        final int y = DRAGGABLE_BOUNDS.top - 100;
+
+        final float end_y = MenuViewAppearance.avoidVerticalDisplayCutout(
+                y, MENU_HEIGHT, DRAGGABLE_BOUNDS, new Rect(0, 5, 0, 6));
+
+        assertThat(end_y).isGreaterThan(DRAGGABLE_BOUNDS.top);
+    }
+
+
+    @Test
+    public void avoidVerticalDisplayCutout_doesNotExceedBottomBounds() {
+        final int y = DRAGGABLE_BOUNDS.bottom + 100;
+
+        final float end_y = MenuViewAppearance.avoidVerticalDisplayCutout(
+                y, MENU_HEIGHT, DRAGGABLE_BOUNDS, new Rect(0, 5, 0, 6));
+
+        assertThat(end_y).isLessThan(DRAGGABLE_BOUNDS.bottom);
+    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
index 5c893da..6a4f3da 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/clipboardoverlay/ClipboardOverlayControllerTest.java
@@ -44,6 +44,7 @@
 import android.content.ClipData;
 import android.content.ClipDescription;
 import android.content.Context;
+import android.content.Intent;
 import android.graphics.Insets;
 import android.graphics.Rect;
 import android.net.Uri;
@@ -77,6 +78,7 @@
 import org.mockito.stubbing.Answer;
 
 import java.util.Optional;
+import java.util.function.Consumer;
 
 @SmallTest
 @RunWith(AndroidJUnit4.class)
@@ -158,6 +160,31 @@
      * is false are removed.[
      */
     private void initController() {
+        IntentCreator fakeIntentCreator = new IntentCreator() {
+            @Override
+            public Intent getTextEditorIntent(Context context) {
+                return new Intent();
+            }
+
+            @Override
+            public Intent getShareIntent(ClipData clipData, Context context) {
+                Intent intent = Intent.createChooser(new Intent(Intent.ACTION_SEND), null);
+                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+                return intent;
+            }
+
+            @Override
+            public void getImageEditIntentAsync(Uri uri, Context context,
+                    Consumer<Intent> outputConsumer) {
+                outputConsumer.accept(new Intent(Intent.ACTION_EDIT));
+            }
+
+            @Override
+            public Intent getRemoteCopyIntent(ClipData clipData, Context context) {
+                return new Intent();
+            }
+        };
+
         mOverlayController = new ClipboardOverlayController(
                 mContext,
                 mClipboardOverlayView,
@@ -171,7 +198,7 @@
                 mClipboardTransitionExecutor,
                 mClipboardIndicationProvider,
                 mUiEventLogger,
-                new ActionIntentCreator());
+                fakeIntentCreator);
         verify(mClipboardOverlayView).setCallbacks(mOverlayCallbacksCaptor.capture());
         mCallbacks = mOverlayCallbacksCaptor.getValue();
     }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
index fb70846..061f798 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/globalactions/GlobalActionsDialogLiteTest.java
@@ -134,7 +134,6 @@
     @Mock private RingerModeTracker mRingerModeTracker;
     @Mock private RingerModeLiveData mRingerModeLiveData;
     @Mock private PackageManager mPackageManager;
-    @Mock private Handler mHandler;
     @Mock private UserContextProvider mUserContextProvider;
     @Mock private VibratorHelper mVibratorHelper;
     @Mock private ShadeController mShadeController;
@@ -148,6 +147,7 @@
     private TestableLooper mTestableLooper;
     private KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
     private GlobalActionsInteractor mInteractor;
+    private Handler mHandler;
 
     @Before
     public void setUp() throws Exception {
@@ -166,6 +166,7 @@
         mGlobalSettings = new FakeGlobalSettings();
         mSecureSettings = new FakeSettings();
         mInteractor = mKosmos.getGlobalActionsInteractor();
+        mHandler = new Handler(mTestableLooper.getLooper());
 
         mGlobalActionsDialogLite = new GlobalActionsDialogLite(mContext,
                 mWindowManagerFuncs,
@@ -771,6 +772,31 @@
         mGlobalActionsDialogLite.showOrHideDialog(false, false, null, Display.DEFAULT_DISPLAY);
     }
 
+    @Test
+    public void userSwitching_dismissDialog() {
+        String[] actions = {
+                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_POWER,
+                GlobalActionsDialogLite.GLOBAL_ACTION_KEY_RESTART,
+        };
+        doReturn(actions).when(mResources)
+                .getStringArray(com.android.internal.R.array.config_globalActionsList);
+
+        mGlobalActionsDialogLite.showOrHideDialog(false, true, null, Display.DEFAULT_DISPLAY);
+        mTestableLooper.processAllMessages();
+
+        assertThat(mGlobalActionsDialogLite.mDialog.isShowing()).isTrue();
+
+        ArgumentCaptor<UserTracker.Callback> captor =
+                ArgumentCaptor.forClass(UserTracker.Callback.class);
+
+        verify(mUserTracker).addCallback(captor.capture(), any());
+
+        captor.getValue().onBeforeUserSwitching(100);
+        mTestableLooper.processAllMessages();
+
+        assertThat(mGlobalActionsDialogLite.mDialog).isNull();
+    }
+
     private UserInfo mockCurrentUser(int flags) {
         return new UserInfo(10, "A User", flags);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
index 8105ae0..206654a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java
@@ -101,7 +101,6 @@
 import com.android.systemui.dump.DumpManager;
 import com.android.systemui.flags.FakeFeatureFlags;
 import com.android.systemui.flags.SystemPropertiesHelper;
-import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
 import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionBootInteractor;
 import com.android.systemui.kosmos.KosmosJavaAdapter;
 import com.android.systemui.log.SessionTracker;
@@ -207,7 +206,6 @@
     private @Mock ShadeWindowLogger mShadeWindowLogger;
     private @Mock SelectedUserInteractor mSelectedUserInteractor;
     private @Mock UserTracker.Callback mUserTrackerCallback;
-    private @Mock KeyguardInteractor mKeyguardInteractor;
     private @Mock KeyguardTransitionBootInteractor mKeyguardTransitionBootInteractor;
     private @Captor ArgumentCaptor<KeyguardStateController.Callback>
             mKeyguardStateControllerCallback;
@@ -1499,7 +1497,7 @@
                 mSystemPropertiesHelper,
                 () -> mock(WindowManagerLockscreenVisibilityManager.class),
                 mSelectedUserInteractor,
-                mKeyguardInteractor,
+                mKosmos.getKeyguardInteractor(),
                 mKeyguardTransitionBootInteractor,
                 mKosmos::getCommunalSceneInteractor,
                 mock(WindowManagerOcclusionManager.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.java
deleted file mode 100644
index 7297e0f..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.lowlightclock;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.shared.condition.Condition;
-import com.android.systemui.statusbar.commandline.Command;
-import com.android.systemui.statusbar.commandline.CommandRegistry;
-
-import kotlin.jvm.functions.Function0;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-
-import java.io.PrintWriter;
-import java.util.Arrays;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class ForceLowLightConditionTest extends SysuiTestCase {
-    @Mock
-    private CommandRegistry mCommandRegistry;
-
-    @Mock
-    private Condition.Callback mCallback;
-
-    @Mock
-    private PrintWriter mPrintWriter;
-
-    @Mock
-    CoroutineScope mScope;
-
-    private ForceLowLightCondition mCondition;
-    private Command mCommand;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        mCondition = new ForceLowLightCondition(mScope, mCommandRegistry);
-        mCondition.addCallback(mCallback);
-        ArgumentCaptor<Function0<Command>> commandCaptor =
-                ArgumentCaptor.forClass(Function0.class);
-        verify(mCommandRegistry).registerCommand(eq(ForceLowLightCondition.COMMAND_ROOT),
-                commandCaptor.capture());
-        mCommand = commandCaptor.getValue().invoke();
-    }
-
-    @Test
-    public void testEnableLowLight() {
-        mCommand.execute(mPrintWriter,
-                Arrays.asList(ForceLowLightCondition.COMMAND_ENABLE_LOW_LIGHT));
-        verify(mCallback).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionSet()).isTrue();
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void testDisableLowLight() {
-        mCommand.execute(mPrintWriter,
-                Arrays.asList(ForceLowLightCondition.COMMAND_DISABLE_LOW_LIGHT));
-        verify(mCallback).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionSet()).isTrue();
-        assertThat(mCondition.isConditionMet()).isFalse();
-    }
-
-    @Test
-    public void testClearEnableLowLight() {
-        mCommand.execute(mPrintWriter,
-                Arrays.asList(ForceLowLightCondition.COMMAND_ENABLE_LOW_LIGHT));
-        verify(mCallback).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionSet()).isTrue();
-        assertThat(mCondition.isConditionMet()).isTrue();
-        Mockito.clearInvocations(mCallback);
-        mCommand.execute(mPrintWriter,
-                Arrays.asList(ForceLowLightCondition.COMMAND_CLEAR_LOW_LIGHT));
-        verify(mCallback).onConditionChanged(mCondition);
-        assertThat(mCondition.isConditionSet()).isFalse();
-        assertThat(mCondition.isConditionMet()).isFalse();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.kt
new file mode 100644
index 0000000..f8ce242
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ForceLowLightConditionTest.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.lowlightclock
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.shared.condition.Condition
+import com.android.systemui.statusbar.commandline.Command
+import com.android.systemui.statusbar.commandline.CommandRegistry
+import com.google.common.truth.Truth
+import java.io.PrintWriter
+import java.util.Arrays
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ForceLowLightConditionTest : SysuiTestCase() {
+    private val kosmos = Kosmos()
+
+    @Mock private lateinit var commandRegistry: CommandRegistry
+
+    @Mock private lateinit var callback: Condition.Callback
+
+    @Mock private lateinit var printWriter: PrintWriter
+
+    private lateinit var condition: ForceLowLightCondition
+    private lateinit var command: Command
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        condition = ForceLowLightCondition(kosmos.testScope, commandRegistry)
+        condition.addCallback(callback)
+        val commandCaptor = argumentCaptor<() -> Command>()
+        Mockito.verify(commandRegistry)
+            .registerCommand(eq(ForceLowLightCondition.COMMAND_ROOT), commandCaptor.capture())
+        command = commandCaptor.lastValue.invoke()
+    }
+
+    @Test
+    fun testEnableLowLight() =
+        kosmos.runTest {
+            command.execute(
+                printWriter,
+                Arrays.asList(ForceLowLightCondition.COMMAND_ENABLE_LOW_LIGHT),
+            )
+            Mockito.verify(callback).onConditionChanged(condition)
+            Truth.assertThat(condition.isConditionSet).isTrue()
+            Truth.assertThat(condition.isConditionMet).isTrue()
+        }
+
+    @Test
+    fun testDisableLowLight() =
+        kosmos.runTest {
+            command.execute(printWriter, listOf(ForceLowLightCondition.COMMAND_DISABLE_LOW_LIGHT))
+            Mockito.verify(callback).onConditionChanged(condition)
+            Truth.assertThat(condition.isConditionSet).isTrue()
+            Truth.assertThat(condition.isConditionMet).isFalse()
+        }
+
+    @Test
+    fun testClearEnableLowLight() =
+        kosmos.runTest {
+            command.execute(printWriter, listOf(ForceLowLightCondition.COMMAND_ENABLE_LOW_LIGHT))
+            Mockito.verify(callback).onConditionChanged(condition)
+            Truth.assertThat(condition.isConditionSet).isTrue()
+            Truth.assertThat(condition.isConditionMet).isTrue()
+            Mockito.clearInvocations(callback)
+            command.execute(printWriter, listOf(ForceLowLightCondition.COMMAND_CLEAR_LOW_LIGHT))
+            Mockito.verify(callback).onConditionChanged(condition)
+            Truth.assertThat(condition.isConditionSet).isFalse()
+            Truth.assertThat(condition.isConditionMet).isFalse()
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.java
deleted file mode 100644
index 2c21624..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.lowlightclock;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.SysuiTestCase;
-
-import kotlinx.coroutines.CoroutineScope;
-
-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;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class LowLightConditionTest extends SysuiTestCase {
-    @Mock
-    private AmbientLightModeMonitor mAmbientLightModeMonitor;
-    @Mock
-    private UiEventLogger mUiEventLogger;
-    @Mock
-    CoroutineScope mScope;
-    private LowLightCondition mCondition;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-
-        mCondition = new LowLightCondition(mScope, mAmbientLightModeMonitor, mUiEventLogger);
-        mCondition.start();
-    }
-
-    @Test
-    public void testLowLightFalse() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT);
-        assertThat(mCondition.isConditionMet()).isFalse();
-    }
-
-    @Test
-    public void testLowLightTrue() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK);
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void testUndecidedLowLightStateIgnored() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK);
-        assertThat(mCondition.isConditionMet()).isTrue();
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED);
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void testLowLightChange() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT);
-        assertThat(mCondition.isConditionMet()).isFalse();
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK);
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void testResetIsConditionMetUponStop() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK);
-        assertThat(mCondition.isConditionMet()).isTrue();
-
-        mCondition.stop();
-        assertThat(mCondition.isConditionMet()).isFalse();
-    }
-
-    @Test
-    public void testLoggingAmbientLightNotLowToLow() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK);
-        // Only logged once.
-        verify(mUiEventLogger, times(1)).log(any());
-        // Logged with the correct state.
-        verify(mUiEventLogger).log(LowLightDockEvent.AMBIENT_LIGHT_TO_DARK);
-    }
-
-    @Test
-    public void testLoggingAmbientLightLowToLow() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK);
-        reset(mUiEventLogger);
-
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK);
-        // Doesn't log.
-        verify(mUiEventLogger, never()).log(any());
-    }
-
-    @Test
-    public void testLoggingAmbientLightNotLowToNotLow() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT);
-        // Doesn't log.
-        verify(mUiEventLogger, never()).log(any());
-    }
-
-    @Test
-    public void testLoggingAmbientLightLowToNotLow() {
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK);
-        reset(mUiEventLogger);
-
-        changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT);
-        // Only logged once.
-        verify(mUiEventLogger).log(any());
-        // Logged with the correct state.
-        verify(mUiEventLogger).log(LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT);
-    }
-
-    private void changeLowLightMode(int mode) {
-        ArgumentCaptor<AmbientLightModeMonitor.Callback> ambientLightCallbackCaptor =
-                ArgumentCaptor.forClass(AmbientLightModeMonitor.Callback.class);
-        verify(mAmbientLightModeMonitor).start(ambientLightCallbackCaptor.capture());
-        ambientLightCallbackCaptor.getValue().onChange(mode);
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.kt
new file mode 100644
index 0000000..da68442
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/LowLightConditionTest.kt
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.lowlightclock
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.condition.testStart
+import com.android.systemui.condition.testStop
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.argumentCaptor
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class LowLightConditionTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+
+    @Mock private lateinit var ambientLightModeMonitor: AmbientLightModeMonitor
+
+    @Mock private lateinit var uiEventLogger: UiEventLogger
+
+    private lateinit var condition: LowLightCondition
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+
+        condition = LowLightCondition(kosmos.testScope, ambientLightModeMonitor, uiEventLogger)
+    }
+
+    @Test
+    fun testLowLightFalse() =
+        kosmos.runTest {
+            testStart(condition)
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+            Truth.assertThat(condition.isConditionMet).isFalse()
+        }
+
+    @Test
+    fun testLowLightTrue() =
+        kosmos.runTest {
+            testStart(condition)
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+            Truth.assertThat(condition.isConditionMet).isTrue()
+        }
+
+    @Test
+    fun testUndecidedLowLightStateIgnored() =
+        kosmos.runTest {
+            testStart(condition)
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+            Truth.assertThat(condition.isConditionMet).isTrue()
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_UNDECIDED)
+            Truth.assertThat(condition.isConditionMet).isTrue()
+        }
+
+    @Test
+    fun testLowLightChange() =
+        kosmos.runTest {
+            testStart(condition)
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+            Truth.assertThat(condition.isConditionMet).isFalse()
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+            Truth.assertThat(condition.isConditionMet).isTrue()
+        }
+
+    @Test
+    fun testResetIsConditionMetUponStop() =
+        kosmos.runTest {
+            testStart(condition)
+            runCurrent()
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+            Truth.assertThat(condition.isConditionMet).isTrue()
+
+            testStop(condition)
+            Truth.assertThat(condition.isConditionMet).isFalse()
+        }
+
+    @Test
+    fun testLoggingAmbientLightNotLowToLow() =
+        kosmos.runTest {
+            testStart(condition)
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+            // Only logged once.
+            Mockito.verify(uiEventLogger, Mockito.times(1)).log(ArgumentMatchers.any())
+            // Logged with the correct state.
+            Mockito.verify(uiEventLogger).log(LowLightDockEvent.AMBIENT_LIGHT_TO_DARK)
+        }
+
+    @Test
+    fun testLoggingAmbientLightLowToLow() =
+        kosmos.runTest {
+            testStart(condition)
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+            Mockito.reset(uiEventLogger)
+
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+            // Doesn't log.
+            Mockito.verify(uiEventLogger, Mockito.never()).log(ArgumentMatchers.any())
+        }
+
+    @Test
+    fun testLoggingAmbientLightNotLowToNotLow() =
+        kosmos.runTest {
+            testStart(condition)
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+            // Doesn't log.
+            Mockito.verify(uiEventLogger, Mockito.never()).log(ArgumentMatchers.any())
+        }
+
+    @Test
+    fun testLoggingAmbientLightLowToNotLow() =
+        kosmos.runTest {
+            testStart(condition)
+            runCurrent()
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_DARK)
+            Mockito.reset(uiEventLogger)
+
+            changeLowLightMode(AmbientLightModeMonitor.AMBIENT_LIGHT_MODE_LIGHT)
+            // Only logged once.
+            Mockito.verify(uiEventLogger).log(ArgumentMatchers.any())
+            // Logged with the correct state.
+            Mockito.verify(uiEventLogger).log(LowLightDockEvent.AMBIENT_LIGHT_TO_LIGHT)
+        }
+
+    private fun changeLowLightMode(mode: Int) {
+        val ambientLightCallbackCaptor = argumentCaptor<AmbientLightModeMonitor.Callback>()
+
+        Mockito.verify(ambientLightModeMonitor).start(ambientLightCallbackCaptor.capture())
+        ambientLightCallbackCaptor.lastValue.onChange(mode)
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.java
deleted file mode 100644
index 366c071..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.lowlightclock;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.os.UserHandle;
-import android.provider.Settings;
-import android.testing.AndroidTestingRunner;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.util.settings.SecureSettings;
-
-import kotlinx.coroutines.CoroutineScope;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-public class ScreenSaverEnabledConditionTest extends SysuiTestCase {
-    @Mock
-    private Resources mResources;
-    @Mock
-    private SecureSettings mSecureSettings;
-    @Mock
-    CoroutineScope mScope;
-    @Captor
-    private ArgumentCaptor<ContentObserver> mSettingsObserverCaptor;
-    private ScreenSaverEnabledCondition mCondition;
-
-    @Before
-    public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        // Default dreams to enabled by default
-        doReturn(true).when(mResources).getBoolean(
-                com.android.internal.R.bool.config_dreamsEnabledByDefault);
-
-        mCondition = new ScreenSaverEnabledCondition(mScope, mResources, mSecureSettings);
-    }
-
-    @Test
-    public void testScreenSaverInitiallyEnabled() {
-        setScreenSaverEnabled(true);
-        mCondition.start();
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    @Test
-    public void testScreenSaverInitiallyDisabled() {
-        setScreenSaverEnabled(false);
-        mCondition.start();
-        assertThat(mCondition.isConditionMet()).isFalse();
-    }
-
-    @Test
-    public void testScreenSaverStateChanges() {
-        setScreenSaverEnabled(false);
-        mCondition.start();
-        assertThat(mCondition.isConditionMet()).isFalse();
-
-        setScreenSaverEnabled(true);
-        final ContentObserver observer = captureSettingsObserver();
-        observer.onChange(/* selfChange= */ false);
-        assertThat(mCondition.isConditionMet()).isTrue();
-    }
-
-    private void setScreenSaverEnabled(boolean enabled) {
-        when(mSecureSettings.getIntForUser(eq(Settings.Secure.SCREENSAVER_ENABLED), anyInt(),
-                eq(UserHandle.USER_CURRENT))).thenReturn(enabled ? 1 : 0);
-    }
-
-    private ContentObserver captureSettingsObserver() {
-        verify(mSecureSettings).registerContentObserverForUserSync(
-                eq(Settings.Secure.SCREENSAVER_ENABLED),
-                mSettingsObserverCaptor.capture(), eq(UserHandle.USER_CURRENT));
-        return mSettingsObserverCaptor.getValue();
-    }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.kt
new file mode 100644
index 0000000..29237a7
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/lowlightclock/ScreenSaverEnabledConditionTest.kt
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.lowlightclock
+
+import android.content.res.Resources
+import android.database.ContentObserver
+import android.os.UserHandle
+import android.provider.Settings
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.internal.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.condition.testStart
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.kosmos.runTest
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.testKosmos
+import com.android.systemui.util.settings.SecureSettings
+import com.google.common.truth.Truth
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.any
+import org.mockito.kotlin.argumentCaptor
+import org.mockito.kotlin.eq
+import org.mockito.kotlin.whenever
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class ScreenSaverEnabledConditionTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+
+    @Mock private lateinit var resources: Resources
+
+    @Mock private lateinit var secureSettings: SecureSettings
+
+    private val settingsObserverCaptor = argumentCaptor<ContentObserver>()
+    private lateinit var condition: ScreenSaverEnabledCondition
+
+    @Before
+    fun setUp() {
+        MockitoAnnotations.initMocks(this)
+        // Default dreams to enabled by default
+        whenever(resources.getBoolean(R.bool.config_dreamsEnabledByDefault)).thenReturn(true)
+
+        condition = ScreenSaverEnabledCondition(kosmos.testScope, resources, secureSettings)
+    }
+
+    @Test
+    fun testScreenSaverInitiallyEnabled() =
+        kosmos.runTest {
+            setScreenSaverEnabled(true)
+            testStart(condition)
+            Truth.assertThat(condition.isConditionMet).isTrue()
+        }
+
+    @Test
+    fun testScreenSaverInitiallyDisabled() =
+        kosmos.runTest {
+            setScreenSaverEnabled(false)
+            testStart(condition)
+            Truth.assertThat(condition.isConditionMet).isFalse()
+        }
+
+    @Test
+    fun testScreenSaverStateChanges() =
+        kosmos.runTest {
+            setScreenSaverEnabled(false)
+            testStart(condition)
+            Truth.assertThat(condition.isConditionMet).isFalse()
+
+            setScreenSaverEnabled(true)
+            runCurrent()
+            val observer = captureSettingsObserver()
+            observer.onChange(/* selfChange= */ false)
+            Truth.assertThat(condition.isConditionMet).isTrue()
+        }
+
+    private fun setScreenSaverEnabled(enabled: Boolean) {
+        whenever(
+                secureSettings.getIntForUser(
+                    eq(Settings.Secure.SCREENSAVER_ENABLED),
+                    any(),
+                    eq(UserHandle.USER_CURRENT),
+                )
+            )
+            .thenReturn(if (enabled) 1 else 0)
+    }
+
+    private fun captureSettingsObserver(): ContentObserver {
+        Mockito.verify(secureSettings)
+            .registerContentObserverForUserSync(
+                eq(Settings.Secure.SCREENSAVER_ENABLED),
+                settingsObserverCaptor.capture(),
+                eq(UserHandle.USER_CURRENT),
+            )
+        return settingsObserverCaptor.lastValue
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
index f394c80..8f1d07b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/viewmodel/SeekBarViewModelTest.kt
@@ -855,6 +855,20 @@
 
     @Test
     fun contentDescriptionUpdated() {
+        var elapsedTimeDesc: CharSequence? = null
+        var durationDesc: CharSequence? = null
+        val listener =
+            object : SeekBarViewModel.ContentDescriptionListener {
+                override fun onContentDescriptionChanged(
+                    elapsedTimeDescription: CharSequence,
+                    durationDescription: CharSequence,
+                ) {
+                    elapsedTimeDesc = elapsedTimeDescription
+                    durationDesc = durationDescription
+                }
+            }
+        viewModel.setContentDescriptionListener(listener)
+
         // When there is a duration and position
         val duration = (1.5 * 60 * 60 * 1000).toLong()
         val metadata =
@@ -875,9 +889,7 @@
         viewModel.updateController(mockController)
         fakeExecutor.runNextReady()
 
-        // Then the content description is set
-        val result = viewModel.progress.value!!
-
+        // Then the content description listener gets an update
         val expectedProgress =
             MeasureFormat.getInstance(Locale.getDefault(), MeasureFormat.FormatWidth.WIDE)
                 .formatMeasures(Measure(3, MeasureUnit.SECOND))
@@ -888,7 +900,7 @@
                     Measure(30, MeasureUnit.MINUTE),
                     Measure(0, MeasureUnit.SECOND),
                 )
-        assertThat(result.durationDescription).isEqualTo(expectedDuration)
-        assertThat(result.elapsedTimeDescription).isEqualTo(expectedProgress)
+        assertThat(elapsedTimeDesc).isEqualTo(expectedProgress)
+        assertThat(durationDesc).isEqualTo(expectedDuration)
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
index 92b26ea..7e42ec7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/DragAndDropTest.kt
@@ -30,6 +30,7 @@
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.FlakyTest
 import androidx.test.filters.SmallTest
+import com.android.compose.theme.PlatformTheme
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
@@ -55,19 +56,21 @@
         listState: EditTileListState,
         onSetTiles: (List<TileSpec>) -> Unit,
     ) {
-        DefaultEditTileGrid(
-            listState = listState,
-            otherTiles = listOf(),
-            columns = 4,
-            largeTilesSpan = 4,
-            modifier = Modifier.fillMaxSize(),
-            onAddTile = {},
-            onRemoveTile = {},
-            onSetTiles = onSetTiles,
-            onResize = { _, _ -> },
-            onStopEditing = {},
-            onReset = null,
-        )
+        PlatformTheme {
+            DefaultEditTileGrid(
+                listState = listState,
+                otherTiles = listOf(),
+                columns = 4,
+                largeTilesSpan = 4,
+                modifier = Modifier.fillMaxSize(),
+                onAddTile = {},
+                onRemoveTile = {},
+                onSetTiles = onSetTiles,
+                onResize = { _, _ -> },
+                onStopEditing = {},
+                onReset = null,
+            )
+        }
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt
index e76be82c..9d4a425 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/EditModeTest.kt
@@ -33,6 +33,7 @@
 import androidx.compose.ui.text.AnnotatedString
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.compose.theme.PlatformTheme
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
@@ -56,19 +57,22 @@
         var tiles by remember { mutableStateOf(TestEditTiles) }
         val (currentTiles, otherTiles) = tiles.partition { it.tile.isCurrent }
         val listState = EditTileListState(currentTiles, columns = 4, largeTilesSpan = 2)
-        DefaultEditTileGrid(
-            listState = listState,
-            otherTiles = otherTiles,
-            columns = 4,
-            largeTilesSpan = 4,
-            modifier = Modifier.fillMaxSize(),
-            onAddTile = { tiles = tiles.add(it) },
-            onRemoveTile = { tiles = tiles.remove(it) },
-            onSetTiles = {},
-            onResize = { _, _ -> },
-            onStopEditing = {},
-            onReset = null,
-        )
+
+        PlatformTheme {
+            DefaultEditTileGrid(
+                listState = listState,
+                otherTiles = otherTiles,
+                columns = 4,
+                largeTilesSpan = 4,
+                modifier = Modifier.fillMaxSize(),
+                onAddTile = { tiles = tiles.add(it) },
+                onRemoveTile = { tiles = tiles.remove(it) },
+                onSetTiles = {},
+                onResize = { _, _ -> },
+                onStopEditing = {},
+                onReset = null,
+            )
+        }
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
index 021be32..5e76000 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/panels/ui/compose/ResizingTest.kt
@@ -35,6 +35,7 @@
 import androidx.compose.ui.text.AnnotatedString
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
+import com.android.compose.theme.PlatformTheme
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.common.shared.model.ContentDescription
 import com.android.systemui.common.shared.model.Icon
@@ -61,19 +62,21 @@
         listState: EditTileListState,
         onResize: (TileSpec, Boolean) -> Unit,
     ) {
-        DefaultEditTileGrid(
-            listState = listState,
-            otherTiles = listOf(),
-            columns = 4,
-            largeTilesSpan = 4,
-            modifier = Modifier.fillMaxSize(),
-            onAddTile = {},
-            onRemoveTile = {},
-            onSetTiles = {},
-            onResize = onResize,
-            onStopEditing = {},
-            onReset = null,
-        )
+        PlatformTheme {
+            DefaultEditTileGrid(
+                listState = listState,
+                otherTiles = listOf(),
+                columns = 4,
+                largeTilesSpan = 4,
+                modifier = Modifier.fillMaxSize(),
+                onAddTile = {},
+                onRemoveTile = {},
+                onSetTiles = {},
+                onResize = onResize,
+                onStopEditing = {},
+                onReset = null,
+            )
+        }
     }
 
     @Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt
index cf54df8..997cf41 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/reardisplay/RearDisplayCoreStartableTest.kt
@@ -22,6 +22,7 @@
 import android.platform.test.annotations.EnableFlags
 import android.view.Display
 import androidx.test.filters.SmallTest
+import com.android.keyguard.keyguardUpdateMonitor
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.deviceStateManager
 import com.android.systemui.display.domain.interactor.RearDisplayStateInteractor
@@ -37,6 +38,7 @@
 import kotlinx.coroutines.flow.MutableSharedFlow
 import org.junit.Before
 import org.junit.Test
+import org.mockito.Mockito.times
 import org.mockito.kotlin.any
 import org.mockito.kotlin.mock
 import org.mockito.kotlin.never
@@ -59,6 +61,7 @@
             fakeRearDisplayStateInteractor,
             kosmos.rearDisplayInnerDialogDelegateFactory,
             kosmos.testScope,
+            kosmos.keyguardUpdateMonitor,
         )
 
     @Before
@@ -96,6 +99,26 @@
             }
         }
 
+    @Test
+    @EnableFlags(FLAG_DEVICE_STATE_RDM_V2)
+    fun testDialogResumesAfterKeyguardGone() =
+        kosmos.runTest {
+            impl.use {
+                it.start()
+                fakeRearDisplayStateInteractor.emitRearDisplay()
+
+                verify(mockDialog).show()
+
+                it.keyguardCallback.onKeyguardVisibilityChanged(true)
+                // Do not need to check that the dialog is dismissed, since SystemUIDialog
+                // implementation handles that. We just toggle keyguard here so that the flow
+                // emits.
+
+                it.keyguardCallback.onKeyguardVisibilityChanged(false)
+                verify(mockDialog, times(2)).show()
+            }
+        }
+
     private class FakeRearDisplayStateInteractor(private val kosmos: Kosmos) :
         RearDisplayStateInteractor {
         private val stateFlow = MutableSharedFlow<RearDisplayStateInteractor.State>()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
index e0118b1..9b03833 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/recents/LauncherProxyServiceTest.kt
@@ -22,6 +22,7 @@
 import android.content.pm.ResolveInfo
 import android.os.PowerManager
 import android.os.UserManager
+import android.platform.test.annotations.EnableFlags
 import android.testing.TestableContext
 import android.testing.TestableLooper
 import android.view.Display
@@ -29,17 +30,23 @@
 import androidx.test.filters.SmallTest
 import com.android.internal.app.AssistUtils
 import com.android.internal.logging.UiEventLogger
+import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.broadcast.BroadcastDispatcher
 import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.display.data.repository.displayRepository
 import com.android.systemui.dump.DumpManager
 import com.android.systemui.keyguard.KeyguardUnlockAnimationController
 import com.android.systemui.keyguard.WakefulnessLifecycle
 import com.android.systemui.keyguard.ui.view.InWindowLauncherUnlockAnimationManager
+import com.android.systemui.kosmos.testScope
 import com.android.systemui.log.assertLogsWtf
+import com.android.systemui.model.fakeSysUIStatePerDisplayRepository
 import com.android.systemui.model.sysUiState
+import com.android.systemui.model.sysUiStateFactory
 import com.android.systemui.navigationbar.NavigationBarController
 import com.android.systemui.navigationbar.NavigationModeController
+import com.android.systemui.navigationbar.views.NavigationBar
 import com.android.systemui.process.ProcessWrapper
 import com.android.systemui.recents.LauncherProxyService.ACTION_QUICKSTEP
 import com.android.systemui.settings.FakeDisplayTracker
@@ -56,18 +63,20 @@
 import com.android.systemui.testKosmos
 import com.android.systemui.unfold.progress.UnfoldTransitionProgressForwarder
 import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.whenever
 import com.android.systemui.util.time.FakeSystemClock
 import com.android.wm.shell.back.BackAnimation
 import com.android.wm.shell.sysui.ShellInterface
 import com.google.common.util.concurrent.MoreExecutors
 import java.util.Optional
 import java.util.concurrent.Executor
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
 import org.junit.After
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.ArgumentMatchers
+import org.mockito.ArgumentMatchers.anyLong
 import org.mockito.ArgumentMatchers.eq
 import org.mockito.Mock
 import org.mockito.Mockito.any
@@ -81,6 +90,7 @@
 import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.MockitoAnnotations
+import org.mockito.kotlin.whenever
 
 @SmallTest
 @RunWith(AndroidJUnit4::class)
@@ -96,8 +106,10 @@
     private val displayTracker = FakeDisplayTracker(mContext)
     private val fakeSystemClock = FakeSystemClock()
     private val sysUiState = kosmos.sysUiState
+    private val sysUiStateFactory = kosmos.sysUiStateFactory
     private val wakefulnessLifecycle =
         WakefulnessLifecycle(mContext, null, fakeSystemClock, dumpManager)
+    private val sysuiStatePerDisplayRepository = kosmos.fakeSysUIStatePerDisplayRepository
 
     @Mock private lateinit var launcherProxy: ILauncherProxy.Stub
     @Mock private lateinit var packageManager: PackageManager
@@ -149,6 +161,8 @@
 
         // return isSystemUser as true by default.
         `when`(processWrapper.isSystemUser).thenReturn(true)
+        sysuiStatePerDisplayRepository.add(Display.DEFAULT_DISPLAY, sysUiState)
+        runBlocking { kosmos.displayRepository.apply { addDisplay(0) } }
         subject = createLauncherProxyService(context)
     }
 
@@ -249,6 +263,48 @@
         verify(spyContext, times(0)).bindServiceAsUser(any(), any(), anyInt(), any())
     }
 
+    @Test
+    fun notifySysUiStateFlagsForAllDisplays_triggersUpdateInAllDisplays() =
+        kosmos.testScope.runTest {
+            kosmos.displayRepository.apply {
+                addDisplay(0)
+                addDisplay(1)
+                addDisplay(2)
+            }
+            kosmos.fakeSysUIStatePerDisplayRepository.apply {
+                add(1, sysUiStateFactory.create(1))
+                add(2, sysUiStateFactory.create(2))
+            }
+            clearInvocations(launcherProxy)
+            subject.notifySysUiStateFlagsForAllDisplays()
+
+            verify(launcherProxy).onSystemUiStateChanged(anyLong(), eq(0))
+            verify(launcherProxy).onSystemUiStateChanged(anyLong(), eq(1))
+            verify(launcherProxy).onSystemUiStateChanged(anyLong(), eq(2))
+        }
+
+    @Test
+    @EnableFlags(Flags.FLAG_SHADE_WINDOW_GOES_AROUND)
+    fun updateSystemUiStateFlags_updatesAllNavBars() =
+        kosmos.testScope.runTest {
+            kosmos.displayRepository.apply {
+                addDisplay(0)
+                addDisplay(1)
+            }
+            kosmos.fakeSysUIStatePerDisplayRepository.apply {
+                add(1, sysUiStateFactory.create(1))
+            }
+            val navBar0 = mock<NavigationBar>()
+            val navBar1 = mock<NavigationBar>()
+            whenever(navBarController.getNavigationBar(eq(0))).thenReturn(navBar0)
+            whenever(navBarController.getNavigationBar(eq(1))).thenReturn(navBar1)
+
+            subject.updateSystemUiStateFlags()
+
+            verify(navBar0).updateSystemUiStateFlags()
+            verify(navBar1).updateSystemUiStateFlags()
+        }
+
     private fun createLauncherProxyService(ctx: Context): LauncherProxyService {
         return LauncherProxyService(
             ctx,
@@ -260,7 +316,7 @@
             screenPinningRequest,
             navModeController,
             statusBarWinController,
-            sysUiState,
+            kosmos.fakeSysUIStatePerDisplayRepository,
             mock(),
             mock(),
             userTracker,
@@ -276,6 +332,7 @@
             broadcastDispatcher,
             backAnimation,
             processWrapper,
+            kosmos.displayRepository,
         )
     }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
index 116a2ca..e1e9aa3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/condition/CombinedConditionTest.kt
@@ -35,8 +35,7 @@
 @RunWith(AndroidJUnit4::class)
 class CombinedConditionTest : SysuiTestCase() {
 
-    class FakeCondition
-    constructor(
+    class FakeCondition(
         scope: CoroutineScope,
         initialValue: Boolean?,
         overriding: Boolean = false,
@@ -46,7 +45,7 @@
         val started: Boolean
             get() = _started
 
-        override fun start() {
+        override suspend fun start() {
             _started = true
         }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
index 3937d3d46..ff17a36 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
@@ -20,7 +20,6 @@
 import androidx.test.filters.SmallTest
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.keyguard.KeyguardUpdateMonitorCallback
-import com.android.systemui.Flags
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.NotificationLockscreenUserManager
 import com.android.systemui.statusbar.NotificationLockscreenUserManager.UserChangedListener
@@ -97,7 +96,6 @@
     fun themeChangePropagatesToEntry() {
         configurationListener.onThemeChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
     }
 
@@ -105,7 +103,6 @@
     fun densityChangePropagatesToEntry() {
         configurationListener.onDensityOrFontScaleChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
     }
 
@@ -129,7 +126,6 @@
         verify(entry).row
         verify(row).onUiModeChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
         clearInvocations(entry, row)
 
@@ -160,7 +156,6 @@
         verify(entry).row
         verify(row).onUiModeChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
         clearInvocations(entry, row)
 
@@ -196,14 +191,7 @@
         verify(entry).row
         verify(row).onUiModeChanged()
         verify(entry).onDensityOrFontScaleChanged()
-        checkGutsExposedCalled()
         verifyNoMoreInteractions(entry, row)
         clearInvocations(entry, row)
     }
-
-    private fun checkGutsExposedCalled() {
-        if (!Flags.notificationUndoGutsOnConfigChanged()) {
-            verify(entry).areGutsExposed()
-        }
-    }
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 84f39be..2ea4e7f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -61,6 +61,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
+import com.android.internal.logging.MetricsLogger;
 import com.android.internal.widget.CachingIconView;
 import com.android.systemui.SysuiTestCase;
 import com.android.systemui.SysuiTestableContext;
@@ -71,12 +72,18 @@
 import com.android.systemui.statusbar.chips.notification.shared.StatusBarNotifChips;
 import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
 import com.android.systemui.statusbar.notification.FeedbackIcon;
+import com.android.systemui.statusbar.notification.NotificationActivityStarter;
 import com.android.systemui.statusbar.notification.SourceType;
+import com.android.systemui.statusbar.notification.collection.EntryAdapter;
 import com.android.systemui.statusbar.notification.collection.NotificationEntry;
+import com.android.systemui.statusbar.notification.collection.NotificationEntryAdapter;
+import com.android.systemui.statusbar.notification.collection.coordinator.VisualStabilityCoordinator;
 import com.android.systemui.statusbar.notification.headsup.PinnedStatus;
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUi;
 import com.android.systemui.statusbar.notification.promoted.PromotedNotificationUiForceExpanded;
 import com.android.systemui.statusbar.notification.row.ExpandableView.OnHeightChangedListener;
+import com.android.systemui.statusbar.notification.row.icon.NotificationIconStyleProvider;
 import com.android.systemui.statusbar.notification.row.wrapper.NotificationViewWrapper;
 import com.android.systemui.statusbar.notification.shared.NotificationBundleUi;
 import com.android.systemui.statusbar.notification.shared.NotificationContentAlphaOptimization;
@@ -173,6 +180,7 @@
     }
 
     @Test
+    @DisableFlags(NotificationBundleUi.FLAG_NAME)
     public void testUpdateBackgroundColors_isRecursive() throws Exception {
         ExpandableNotificationRow group = mNotificationTestHelper.createGroup();
         group.setTintColor(Color.RED);
@@ -597,14 +605,14 @@
     public void testGetIsNonblockable() throws Exception {
         ExpandableNotificationRow row =
                 mNotificationTestHelper.createRow(mNotificationTestHelper.createNotification());
-        row.setEntry(null);
+        row.setEntryLegacy(null);
 
         assertTrue(row.getIsNonblockable());
 
         NotificationEntry entry = mock(NotificationEntry.class);
 
         Mockito.doReturn(false, true).when(entry).isBlockable();
-        row.setEntry(entry);
+        row.setEntryLegacy(entry);
         assertTrue(row.getIsNonblockable());
         assertFalse(row.getIsNonblockable());
     }
@@ -939,12 +947,14 @@
 
     @Test
     @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME})
+    @DisableFlags(NotificationBundleUi.FLAG_NAME)
     public void isExpanded_sensitivePromotedNotification_notExpanded() throws Exception {
         // GIVEN
         final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
         NotificationEntry entry = mock(NotificationEntry.class);
         when(entry.isPromotedOngoing()).thenReturn(true);
-        row.setEntry(entry);
+        row.setEntryLegacy(entry);
+        setRowPromotedOngoing(row);
         row.setSensitive(/* sensitive= */true, /* hideSensitive= */false);
         row.setHideSensitiveForIntrinsicHeight(/* hideSensitive= */true);
 
@@ -954,12 +964,14 @@
 
     @Test
     @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME})
+    @DisableFlags(NotificationBundleUi.FLAG_NAME)
     public void isExpanded_promotedNotificationNotOnKeyguard_expanded() throws Exception {
         // GIVEN
         final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
         NotificationEntry entry = mock(NotificationEntry.class);
         when(entry.isPromotedOngoing()).thenReturn(true);
-        row.setEntry(entry);
+        row.setEntryLegacy(entry);
+        setRowPromotedOngoing(row);
         row.setOnKeyguard(false);
 
         // THEN
@@ -968,12 +980,14 @@
 
     @Test
     @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME})
+    @DisableFlags(NotificationBundleUi.FLAG_NAME)
     public void isExpanded_promotedNotificationAllowOnKeyguard_expanded() throws Exception {
         // GIVEN
         final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
         NotificationEntry entry = mock(NotificationEntry.class);
         when(entry.isPromotedOngoing()).thenReturn(true);
-        row.setEntry(entry);
+        row.setEntryLegacy(entry);
+        setRowPromotedOngoing(row);
         row.setOnKeyguard(true);
 
         // THEN
@@ -982,13 +996,15 @@
 
     @Test
     @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME})
+    @DisableFlags(NotificationBundleUi.FLAG_NAME)
     public void isExpanded_promotedNotificationIgnoreLockscreenConstraints_expanded()
             throws Exception {
         // GIVEN
         final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
         NotificationEntry entry = mock(NotificationEntry.class);
         when(entry.isPromotedOngoing()).thenReturn(true);
-        row.setEntry(entry);
+        row.setEntryLegacy(entry);
+        setRowPromotedOngoing(row);
         row.setOnKeyguard(true);
         row.setIgnoreLockscreenConstraints(true);
 
@@ -996,15 +1012,35 @@
         assertThat(row.isExpanded()).isTrue();
     }
 
+    private static void setRowPromotedOngoing(ExpandableNotificationRow row) {
+        final NotificationEntry entry = mock(NotificationEntry.class);
+        when(entry.isPromotedOngoing()).thenReturn(true);
+        if (NotificationBundleUi.isEnabled()) {
+            final EntryAdapter entryAdapter = new NotificationEntryAdapter(
+                    mock(NotificationActivityStarter.class),
+                    mock(MetricsLogger.class),
+                    mock(PeopleNotificationIdentifier.class),
+                    mock(NotificationIconStyleProvider.class),
+                    mock(VisualStabilityCoordinator.class),
+                    mock(NotificationActionClickManager.class),
+                    entry);
+            row.setEntryAdapter(entryAdapter);
+        } else {
+            row.setEntryLegacy(entry);
+        }
+    }
+
     @Test
     @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME})
+    @DisableFlags(NotificationBundleUi.FLAG_NAME)
     public void isExpanded_promotedNotificationSaveSpaceOnLockScreen_notExpanded()
             throws Exception {
         // GIVEN
         final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
         NotificationEntry entry = mock(NotificationEntry.class);
         when(entry.isPromotedOngoing()).thenReturn(true);
-        row.setEntry(entry);
+        row.setEntryLegacy(entry);
+        setRowPromotedOngoing(row);
         row.setOnKeyguard(true);
         row.setSaveSpaceOnLockscreen(true);
 
@@ -1014,13 +1050,15 @@
 
     @Test
     @EnableFlags({PromotedNotificationUi.FLAG_NAME, PromotedNotificationUiForceExpanded.FLAG_NAME})
+    @DisableFlags(NotificationBundleUi.FLAG_NAME)
     public void isExpanded_promotedNotificationNotSaveSpaceOnLockScreen_expanded()
             throws Exception {
         // GIVEN
         final ExpandableNotificationRow row = mNotificationTestHelper.createRow();
         NotificationEntry entry = mock(NotificationEntry.class);
         when(entry.isPromotedOngoing()).thenReturn(true);
-        row.setEntry(entry);
+        row.setEntryLegacy(entry);
+        setRowPromotedOngoing(row);
         row.setOnKeyguard(true);
         row.setSaveSpaceOnLockscreen(false);
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
index c874bc6..82082cc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -19,6 +19,7 @@
 import android.annotation.DimenRes
 import android.content.res.Resources
 import android.os.UserHandle
+import android.platform.test.annotations.DisableFlags
 import android.service.notification.StatusBarNotification
 import android.testing.TestableLooper
 import android.testing.ViewUtils
@@ -37,9 +38,13 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.statusbar.notification.FeedbackIcon
 import com.android.systemui.statusbar.notification.collection.EntryAdapter
+import com.android.systemui.statusbar.notification.collection.EntryAdapterFactory
 import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.msgStyleBubbleableFullPerson
+import com.android.systemui.statusbar.notification.people.peopleNotificationIdentifier
 import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier
 import com.android.systemui.statusbar.notification.shared.NotificationBundleUi
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
@@ -50,7 +55,6 @@
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
-import org.mockito.Mock
 import org.mockito.Mockito
 import org.mockito.Mockito.anyBoolean
 import org.mockito.Mockito.anyInt
@@ -66,10 +70,12 @@
 @RunWith(AndroidJUnit4::class)
 @TestableLooper.RunWithLooper
 class NotificationContentViewTest : SysuiTestCase() {
+    private val kosmos = testKosmos()
+
+    private val factory: EntryAdapterFactory = kosmos.entryAdapterFactory
 
     private lateinit var row: ExpandableNotificationRow
     private lateinit var fakeParent: ViewGroup
-    @Mock private lateinit var mPeopleNotificationIdentifier: PeopleNotificationIdentifier
 
     private val testableResources = mContext.getOrCreateTestableResources()
     private val contractedHeight =
@@ -81,25 +87,19 @@
     fun setup() {
         initMocks(this)
         fakeParent =
-            spy(FrameLayout(mContext, /* attrs= */ null).also { it.visibility = View.GONE })
-        val mockEntry = createMockNotificationEntry()
-        val mockEntryAdapter = createMockNotificationEntryAdapter()
+            spy(FrameLayout(mContext, /* attrs= */ null)).also { it.visibility = View.GONE }
+        val entry = kosmos.msgStyleBubbleableFullPerson
+        val mockEntryAdapter = factory.create(entry)
         row =
             spy(
                 when (NotificationBundleUi.isEnabled) {
                     true -> {
-                        ExpandableNotificationRow(
-                            mContext,
-                            /* attrs= */ null,
-                            UserHandle.CURRENT
-                        ).apply {
-                            entry = mockEntry
-                            entryAdapter = mockEntryAdapter
-                        }
+                        ExpandableNotificationRow(mContext, /* attrs= */ null, UserHandle.CURRENT)
+                            .apply { entryAdapter = mockEntryAdapter }
                     }
                     false -> {
-                        ExpandableNotificationRow(mContext, /* attrs= */ null, mockEntry).apply {
-                            entry = mockEntry
+                        ExpandableNotificationRow(mContext, /* attrs= */ null, entry).apply {
+                            entryLegacy = entry
                         }
                     }
                 }
@@ -402,14 +402,15 @@
     }
 
     @Test
+    @DisableFlags(android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES)
     fun setExpandedChild_notShowBubbleButton_marginTargetBottomMarginShouldNotChange() {
         // Given: bottom margin of actionListMarginTarget is notificationContentMargin
         // Bubble button should not be shown for the given NotificationEntry
-        val mockNotificationEntry = createMockNotificationEntry()
+        val mockNotificationEntry = kosmos.msgStyleBubbleableFullPerson
         val mockContainingNotification = createMockContainingNotification(mockNotificationEntry)
         val actionListMarginTarget =
             spy(createLinearLayoutWithBottomMargin(notificationContentMargin))
-        val mockExpandedChild = createMockExpandedChild(mockNotificationEntry)
+        val mockExpandedChild = createMockExpandedChild()
         whenever(
                 mockExpandedChild.findViewById<LinearLayout>(
                     R.id.notification_action_list_margin_target
@@ -429,14 +430,15 @@
     }
 
     @Test
+    @DisableFlags(android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES)
     fun setExpandedChild_showBubbleButton_marginTargetBottomMarginShouldChangeToZero() {
         // Given: bottom margin of actionListMarginTarget is notificationContentMargin
         // Bubble button should be shown for the given NotificationEntry
-        val mockNotificationEntry = createMockNotificationEntry()
+        val mockNotificationEntry = kosmos.msgStyleBubbleableFullPerson
         val mockContainingNotification = createMockContainingNotification(mockNotificationEntry)
         val actionListMarginTarget =
             spy(createLinearLayoutWithBottomMargin(notificationContentMargin))
-        val mockExpandedChild = createMockExpandedChild(mockNotificationEntry)
+        val mockExpandedChild = createMockExpandedChild()
         whenever(
                 mockExpandedChild.findViewById<LinearLayout>(
                     R.id.notification_action_list_margin_target
@@ -458,13 +460,14 @@
     }
 
     @Test
+    @DisableFlags(android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES)
     fun onNotificationUpdated_notShowBubbleButton_marginTargetBottomMarginShouldNotChange() {
         // Given: bottom margin of actionListMarginTarget is notificationContentMargin
-        val mockNotificationEntry = createMockNotificationEntry()
+        val mockNotificationEntry = kosmos.msgStyleBubbleableFullPerson
         val mockContainingNotification = createMockContainingNotification(mockNotificationEntry)
         val actionListMarginTarget =
             spy(createLinearLayoutWithBottomMargin(notificationContentMargin))
-        val mockExpandedChild = createMockExpandedChild(mockNotificationEntry)
+        val mockExpandedChild = createMockExpandedChild()
         whenever(
                 mockExpandedChild.findViewById<LinearLayout>(
                     R.id.notification_action_list_margin_target
@@ -479,20 +482,21 @@
 
         // When: call NotificationContentView.onNotificationUpdated() to update the
         // NotificationEntry, which should not show bubble button
-        view.onNotificationUpdated(createMockNotificationEntry())
+        view.onNotificationUpdated(kosmos.msgStyleBubbleableFullPerson)
 
         // Then: bottom margin of actionListMarginTarget should not change, still be 20
         assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget))
     }
 
     @Test
+    @DisableFlags(android.app.Flags.FLAG_NOTIFICATIONS_REDESIGN_TEMPLATES)
     fun onNotificationUpdated_showBubbleButton_marginTargetBottomMarginShouldChangeToZero() {
         // Given: bottom margin of actionListMarginTarget is notificationContentMargin
-        val mockNotificationEntry = createMockNotificationEntry()
+        val mockNotificationEntry = kosmos.msgStyleBubbleableFullPerson
         val mockContainingNotification = createMockContainingNotification(mockNotificationEntry)
         val actionListMarginTarget =
             spy(createLinearLayoutWithBottomMargin(notificationContentMargin))
-        val mockExpandedChild = createMockExpandedChild(mockNotificationEntry)
+        val mockExpandedChild = createMockExpandedChild()
         whenever(
                 mockExpandedChild.findViewById<LinearLayout>(
                     R.id.notification_action_list_margin_target
@@ -506,7 +510,7 @@
 
         // When: call NotificationContentView.onNotificationUpdated() to update the
         // NotificationEntry, which should show bubble button
-        view.onNotificationUpdated(createMockNotificationEntry(/*true*/ ))
+        view.onNotificationUpdated(kosmos.msgStyleBubbleableFullPerson)
 
         // Then: no bubble yet
         assertEquals(notificationContentMargin, getMarginBottom(actionListMarginTarget))
@@ -514,7 +518,7 @@
         // Given: controller says bubbles are enabled for the user
         view.setBubblesEnabledForUser(true)
 
-        // Then: bottom margin of actionListMarginTarget should not change, still be 20
+        // Then: bottom margin of actionListMarginTarget should be changed to 0
         assertEquals(0, getMarginBottom(actionListMarginTarget))
     }
 
@@ -611,15 +615,17 @@
 
     private fun createMockContainingNotification(notificationEntry: NotificationEntry) =
         mock<ExpandableNotificationRow>().apply {
-            whenever(this.entry).thenReturn(notificationEntry)
+            if (!NotificationBundleUi.isEnabled) {
+                whenever(this.entryLegacy).thenReturn(notificationEntry)
+            }
             whenever(this.context).thenReturn(mContext)
             whenever(this.bubbleClickListener).thenReturn(View.OnClickListener {})
-            whenever(this.entryAdapter).thenReturn(createMockNotificationEntryAdapter())
+            whenever(this.entryAdapter).thenReturn(factory.create(notificationEntry))
         }
 
     private fun createMockNotificationEntry() =
         mock<NotificationEntry>().apply {
-            whenever(mPeopleNotificationIdentifier.getPeopleNotificationType(this))
+            whenever(kosmos.peopleNotificationIdentifier.getPeopleNotificationType(this))
                 .thenReturn(PeopleNotificationIdentifier.TYPE_FULL_PERSON)
             whenever(this.bubbleMetadata).thenReturn(mock())
             val sbnMock: StatusBarNotification = mock()
@@ -640,7 +646,7 @@
         return innerLayout
     }
 
-    private fun createMockExpandedChild(notificationEntry: NotificationEntry) =
+    private fun createMockExpandedChild() =
         spy(createViewWithHeight(expandedHeight)).apply {
             whenever(this.findViewById<ImageView>(R.id.bubble_button)).thenReturn(mock())
             whenever(this.findViewById<View>(R.id.actions_container)).thenReturn(mock())
@@ -661,9 +667,16 @@
         val height = if (isSystemExpanded) expandedHeight else contractedHeight
         doReturn(height).whenever(row).intrinsicHeight
 
-        return spy(NotificationContentView(mContext, /* attrs= */ null))
+        return NotificationContentView(mContext, /* attrs= */ null)
             .apply {
-                initialize(mPeopleNotificationIdentifier, mock(), mock(), mock(), mock(), mock())
+                initialize(
+                    kosmos.peopleNotificationIdentifier,
+                    mock(),
+                    mock(),
+                    mock(),
+                    mock(),
+                    mock(),
+                )
                 setContainingNotification(row)
                 setHeights(
                     /* smallHeight= */ contractedHeight,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
index ee9a5f3..10de866 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerWithScenesTest.kt
@@ -300,45 +300,6 @@
     }
 
     @Test
-    fun testChangeDensityOrFontScale() {
-        val guts = spy(NotificationGuts(mContext))
-        whenever(guts.post(any())).thenAnswer { invocation: InvocationOnMock ->
-            handler.post((invocation.arguments[0] as Runnable))
-            null
-        }
-
-        // Test doesn't support animation since the guts view is not attached.
-        doNothing()
-            .whenever(guts)
-            .openControls(any<Int>(), any<Int>(), any<Boolean>(), any<Runnable>())
-        val realRow = createTestNotificationRow()
-        val menuItem = createTestMenuItem(realRow)
-        val row = spy(realRow)
-        whenever(row!!.windowToken).thenReturn(Binder())
-        whenever(row.guts).thenReturn(guts)
-        doNothing().whenever(row).ensureGutsInflated()
-        val realEntry = realRow!!.entry
-        val entry = spy(realEntry)
-        whenever(entry.row).thenReturn(row)
-        whenever(entry.getGuts()).thenReturn(guts)
-        Assert.assertTrue(gutsManager.openGutsInternal(row, 0, 0, menuItem))
-        executor.runAllReady()
-        verify(guts).openControls(any<Int>(), any<Int>(), any<Boolean>(), any<Runnable>())
-
-        // called once by mGutsManager.bindGuts() in mGutsManager.openGuts()
-        verify(row).setGutsView(any())
-        row.onDensityOrFontScaleChanged()
-        gutsManager.onDensityOrFontScaleChanged(entry)
-        executor.runAllReady()
-        gutsManager.closeAndSaveGuts(false, false, false, 0, 0, false)
-        verify(guts)
-            .closeControls(any<Boolean>(), any<Boolean>(), any<Int>(), any<Int>(), any<Boolean>())
-
-        // called again by mGutsManager.bindGuts(), in mGutsManager.onDensityOrFontScaleChanged()
-        verify(row, times(2)).setGutsView(any())
-    }
-
-    @Test
     fun testAppOpsSettingsIntent_camera() {
         val ops = ArraySet<Int>()
         ops.add(AppOpsManager.OP_CAMERA)
@@ -430,6 +391,7 @@
             .setUserSentiment(Ranking.USER_SENTIMENT_NEGATIVE)
             .setImportance(NotificationManager.IMPORTANCE_HIGH)
             .build()
+        whenever(row.canViewBeDismissed()).thenReturn(true)
         whenever(highPriorityProvider.isHighPriority(entry)).thenReturn(true)
         val statusBarNotification = entry.sbn
         gutsManager.initializeNotificationInfo(row, notificationInfoView)
@@ -451,7 +413,8 @@
                 any<UiEventLogger>(),
                 eq(true),
                 eq(false),
-                eq(true), /* wasShownHighPriority */
+                eq(true),
+                eq(true),
                 eq(assistantFeedbackController),
                 any<MetricsLogger>(),
                 any<View.OnClickListener>(),
@@ -466,6 +429,7 @@
         NotificationEntryHelper.modifyRanking(row.entry)
             .setUserSentiment(Ranking.USER_SENTIMENT_NEGATIVE)
             .build()
+        whenever(row.canViewBeDismissed()).thenReturn(true)
         val statusBarNotification = row.entry.sbn
         val entry = row.entry
         gutsManager.initializeNotificationInfo(row, notificationInfoView)
@@ -487,7 +451,8 @@
                 any<UiEventLogger>(),
                 eq(true),
                 eq(false),
-                eq(false), /* wasShownHighPriority */
+                eq(true), /* wasShownHighPriority */
+                eq(false),
                 eq(assistantFeedbackController),
                 any<MetricsLogger>(),
                 any<View.OnClickListener>(),
@@ -502,6 +467,7 @@
         NotificationEntryHelper.modifyRanking(row.entry)
             .setUserSentiment(Ranking.USER_SENTIMENT_NEGATIVE)
             .build()
+        whenever(row.canViewBeDismissed()).thenReturn(true)
         val statusBarNotification = row.entry.sbn
         val entry = row.entry
         gutsManager.initializeNotificationInfo(row, notificationInfoView)
@@ -523,7 +489,8 @@
                 any<UiEventLogger>(),
                 eq(true),
                 eq(false),
-                eq(false), /* wasShownHighPriority */
+                eq(true), /* wasShownHighPriority */
+                eq(false),
                 eq(assistantFeedbackController),
                 any<MetricsLogger>(),
                 any<View.OnClickListener>(),
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 8fb2a24..6a9a485 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
@@ -734,6 +734,7 @@
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
         NotificationEntry entry = mock(NotificationEntry.class);
         when(row.getEntry()).thenReturn(entry);
+        when(row.getEntryLegacy()).thenReturn(entry);
         when(entry.isAmbient()).thenReturn(false);
         EntryAdapter entryAdapter = mock(EntryAdapter.class);
         when(entryAdapter.isAmbient()).thenReturn(false);
@@ -753,6 +754,7 @@
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
         NotificationEntry entry = mock(NotificationEntry.class);
         when(row.getEntry()).thenReturn(entry);
+        when(row.getEntryLegacy()).thenReturn(entry);
         when(entry.isAmbient()).thenReturn(true);
         EntryAdapter entryAdapter = mock(EntryAdapter.class);
         when(entryAdapter.isAmbient()).thenReturn(true);
@@ -772,6 +774,7 @@
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
         NotificationEntry entry = mock(NotificationEntry.class);
         when(row.getEntry()).thenReturn(entry);
+        when(row.getEntryLegacy()).thenReturn(entry);
         when(entry.isAmbient()).thenReturn(false);
         EntryAdapter entryAdapter = mock(EntryAdapter.class);
         when(entryAdapter.isAmbient()).thenReturn(false);
@@ -1384,6 +1387,7 @@
         NotificationEntry entry = mock(NotificationEntry.class);
         when(entry.isSeenInShade()).thenReturn(true);
         ExpandableNotificationRow row = mock(ExpandableNotificationRow.class);
+        when(row.getEntryLegacy()).thenReturn(entry);
         when(row.getEntry()).thenReturn(entry);
 
         // WHEN we generate an add event
@@ -1440,6 +1444,7 @@
         NotificationEntry entry = mock(NotificationEntry.class);
         when(row.canViewBeCleared()).thenReturn(true);
         when(row.getEntry()).thenReturn(entry);
+        when(row.getEntryLegacy()).thenReturn(entry);
         when(entry.isClearable()).thenReturn(true);
         EntryAdapter entryAdapter = mock(EntryAdapter.class);
         when(entryAdapter.isClearable()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
index a3616d2..a7f3fdc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CentralSurfacesImplTest.java
@@ -28,8 +28,8 @@
 import static android.provider.Settings.Global.HEADS_UP_ON;
 
 import static com.android.systemui.Flags.FLAG_KEYBOARD_SHORTCUT_HELPER_REWRITE;
-import static com.android.systemui.Flags.FLAG_LIGHT_REVEAL_MIGRATION;
 import static com.android.systemui.flags.Flags.SHORTCUT_LIST_SEARCH_LAYOUT;
+import static com.android.systemui.shared.Flags.FLAG_AMBIENT_AOD;
 import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
 import static com.android.systemui.statusbar.StatusBarState.SHADE;
 import static com.android.systemui.statusbar.phone.CentralSurfaces.MSG_DISMISS_KEYBOARD_SHORTCUTS_MENU;
@@ -242,7 +242,7 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 @RunWithLooper(setAsMainLooper = true)
-@EnableFlags(FLAG_LIGHT_REVEAL_MIGRATION)
+@EnableFlags(FLAG_AMBIENT_AOD)
 public class CentralSurfacesImplTest extends SysuiTestCase {
 
     private static final DeviceState FOLD_STATE_FOLDED = new DeviceState(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index ffb861d..063b546 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -296,6 +296,7 @@
                 mKosmos.getTestDispatcher(),
                 mLinearLargeScreenShadeInterpolator,
                 new BlurConfig(0.0f, 0.0f),
+                mContext,
                 mKosmos::getWindowRootViewBlurInteractor);
         mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
         mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
@@ -1247,6 +1248,7 @@
                 mKosmos.getTestDispatcher(),
                 mLinearLargeScreenShadeInterpolator,
                 new BlurConfig(0.0f, 0.0f),
+                mContext,
                 mKosmos::getWindowRootViewBlurInteractor);
         mScrimController.setScrimVisibleListener(visible -> mScrimVisibility = visible);
         mScrimController.attachViews(mScrimBehind, mNotificationsScrim, mScrimInFront);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
index 9440280..54ac3bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
@@ -21,6 +21,7 @@
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.util.time.FakeSystemClock
 import com.google.common.truth.Truth.assertThat
+import kotlin.time.Duration.Companion.milliseconds
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.Job
 import kotlinx.coroutines.delay
@@ -33,6 +34,7 @@
 import kotlinx.coroutines.flow.flow
 import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.onEach
 import kotlinx.coroutines.flow.takeWhile
 import kotlinx.coroutines.flow.toList
 import kotlinx.coroutines.launch
@@ -50,11 +52,7 @@
 class PairwiseFlowTest : SysuiTestCase() {
     @Test
     fun simple() = runBlocking {
-        assertThatFlow((1..3).asFlow().pairwise())
-            .emitsExactly(
-                WithPrev(1, 2),
-                WithPrev(2, 3),
-            )
+        assertThatFlow((1..3).asFlow().pairwise()).emitsExactly(WithPrev(1, 2), WithPrev(2, 3))
     }
 
     @Test fun notEnough() = runBlocking { assertThatFlow(flowOf(1).pairwise()).emitsNothing() }
@@ -157,48 +155,27 @@
     fun simple() = runBlocking {
         assertThatFlow(flowOf(setOf(1, 2, 3), setOf(2, 3, 4)).setChanges())
             .emitsExactly(
-                SetChanges(
-                    added = setOf(1, 2, 3),
-                    removed = emptySet(),
-                ),
-                SetChanges(
-                    added = setOf(4),
-                    removed = setOf(1),
-                ),
+                SetChanges(added = setOf(1, 2, 3), removed = emptySet()),
+                SetChanges(added = setOf(4), removed = setOf(1)),
             )
     }
 
     @Test
     fun onlyOneEmission() = runBlocking {
         assertThatFlow(flowOf(setOf(1)).setChanges())
-            .emitsExactly(
-                SetChanges(
-                    added = setOf(1),
-                    removed = emptySet(),
-                )
-            )
+            .emitsExactly(SetChanges(added = setOf(1), removed = emptySet()))
     }
 
     @Test
     fun fromEmptySet() = runBlocking {
         assertThatFlow(flowOf(emptySet(), setOf(1, 2)).setChanges())
-            .emitsExactly(
-                SetChanges(
-                    removed = emptySet(),
-                    added = setOf(1, 2),
-                )
-            )
+            .emitsExactly(SetChanges(removed = emptySet(), added = setOf(1, 2)))
     }
 
     @Test
     fun dontEmitFirstEvent() = runBlocking {
         assertThatFlow(flowOf(setOf(1, 2), setOf(2, 3)).setChanges(emitFirstEvent = false))
-            .emitsExactly(
-                SetChanges(
-                    removed = setOf(1),
-                    added = setOf(3),
-                )
-            )
+            .emitsExactly(SetChanges(removed = setOf(1), added = setOf(3)))
     }
 }
 
@@ -235,11 +212,7 @@
             emit(4)
         }
         assertThatFlow(sampler.sample(samplee) { a, b -> a to b })
-            .emitsExactly(
-                2 to 1,
-                3 to 3,
-                4 to 3,
-            )
+            .emitsExactly(2 to 1, 3 to 3, 4 to 3)
     }
 }
 
@@ -419,10 +392,262 @@
         }
 }
 
+@SmallTest
+@RunWith(AndroidJUnit4::class)
+class SlidingWindowFlowTest : SysuiTestCase() {
+
+    @Test
+    fun basicWindowing() = runTest {
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<List<Int>>()
+        val collectJob =
+            backgroundScope.launch {
+                (1..5)
+                    .asFlow()
+                    .onEach { delay(100) }
+                    .slidingWindow(300.milliseconds, choreographer.fakeClock)
+                    .toList(output)
+            }
+
+        choreographer.advanceAndRun(0)
+        assertThat(output).isEmpty()
+
+        choreographer.advanceAndRun(100)
+        assertThat(output).containsExactly(listOf(1))
+
+        choreographer.advanceAndRun(1)
+        assertThat(output).containsExactly(listOf(1))
+
+        choreographer.advanceAndRun(99)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2))
+
+        choreographer.advanceAndRun(100)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3))
+
+        choreographer.advanceAndRun(100)
+        assertThat(output)
+            .containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3), listOf(2, 3, 4))
+
+        choreographer.advanceAndRun(100)
+        assertThat(output)
+            .containsExactly(
+                listOf(1),
+                listOf(1, 2),
+                listOf(1, 2, 3),
+                listOf(2, 3, 4),
+                listOf(3, 4, 5),
+            )
+
+        choreographer.advanceAndRun(100)
+        assertThat(output)
+            .containsExactly(
+                listOf(1),
+                listOf(1, 2),
+                listOf(1, 2, 3),
+                listOf(2, 3, 4),
+                listOf(3, 4, 5),
+                listOf(4, 5),
+            )
+
+        choreographer.advanceAndRun(100)
+        assertThat(output)
+            .containsExactly(
+                listOf(1),
+                listOf(1, 2),
+                listOf(1, 2, 3),
+                listOf(2, 3, 4),
+                listOf(3, 4, 5),
+                listOf(4, 5),
+                listOf(5),
+            )
+
+        choreographer.advanceAndRun(100)
+        assertThat(output)
+            .containsExactly(
+                listOf(1),
+                listOf(1, 2),
+                listOf(1, 2, 3),
+                listOf(2, 3, 4),
+                listOf(3, 4, 5),
+                listOf(4, 5),
+                listOf(5),
+                emptyList<Int>(),
+            )
+
+        // Verify no more emissions
+        choreographer.advanceAndRun(9999999999)
+        assertThat(output)
+            .containsExactly(
+                listOf(1),
+                listOf(1, 2),
+                listOf(1, 2, 3),
+                listOf(2, 3, 4),
+                listOf(3, 4, 5),
+                listOf(4, 5),
+                listOf(5),
+                emptyList<Int>(),
+            )
+
+        assertThat(collectJob.isCompleted).isTrue()
+    }
+
+    @Test
+    fun initialEmptyFlow() = runTest {
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<List<Int>>()
+        val collectJob =
+            backgroundScope.launch {
+                flow {
+                        delay(200)
+                        emit(1)
+                    }
+                    .slidingWindow(100.milliseconds, choreographer.fakeClock)
+                    .toList(output)
+            }
+
+        choreographer.advanceAndRun(0)
+        assertThat(output).isEmpty()
+
+        choreographer.advanceAndRun(200)
+        assertThat(output).containsExactly(listOf(1))
+
+        choreographer.advanceAndRun(100)
+        assertThat(output).containsExactly(listOf(1), emptyList<Int>())
+
+        assertThat(collectJob.isCompleted).isTrue()
+    }
+
+    @Test
+    fun windowLargerThanData() = runTest {
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<List<Int>>()
+        val collectJob =
+            backgroundScope.launch {
+                (1..3)
+                    .asFlow()
+                    .onEach { delay(50) }
+                    .slidingWindow(500.milliseconds, choreographer.fakeClock)
+                    .toList(output)
+            }
+
+        choreographer.advanceAndRun(0)
+        assertThat(output).isEmpty()
+
+        choreographer.advanceAndRun(50)
+        assertThat(output).containsExactly(listOf(1))
+
+        choreographer.advanceAndRun(50)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2))
+
+        choreographer.advanceAndRun(50)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3))
+
+        // It has been 100ms since the first emission, which means we have 400ms left until the
+        // first item is evicted from the window. Ensure that we have no evictions until that time.
+        choreographer.advanceAndRun(399)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3))
+
+        choreographer.advanceAndRun(1)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3), listOf(2, 3))
+
+        choreographer.advanceAndRun(50)
+        assertThat(output)
+            .containsExactly(listOf(1), listOf(1, 2), listOf(1, 2, 3), listOf(2, 3), listOf(3))
+
+        choreographer.advanceAndRun(50)
+        assertThat(output)
+            .containsExactly(
+                listOf(1),
+                listOf(1, 2),
+                listOf(1, 2, 3),
+                listOf(2, 3),
+                listOf(3),
+                emptyList<Int>(),
+            )
+
+        assertThat(collectJob.isCompleted).isTrue()
+    }
+
+    @Test
+    fun dataGapLargerThanWindow() = runTest {
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<List<Int>>()
+        val collectJob =
+            backgroundScope.launch {
+                flow {
+                        emit(1)
+                        delay(200)
+                        emit(2)
+                        delay(500) // Gap larger than window
+                        emit(3)
+                    }
+                    .slidingWindow(300.milliseconds, choreographer.fakeClock)
+                    .toList(output)
+            }
+
+        choreographer.advanceAndRun(0)
+        assertThat(output).containsExactly(listOf(1))
+
+        choreographer.advanceAndRun(200)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2))
+
+        choreographer.advanceAndRun(100)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(2))
+
+        choreographer.advanceAndRun(200)
+        assertThat(output).containsExactly(listOf(1), listOf(1, 2), listOf(2), emptyList<Int>())
+
+        choreographer.advanceAndRun(200)
+        assertThat(output)
+            .containsExactly(listOf(1), listOf(1, 2), listOf(2), emptyList<Int>(), listOf(3))
+
+        choreographer.advanceAndRun(300)
+        assertThat(output)
+            .containsExactly(
+                listOf(1),
+                listOf(1, 2),
+                listOf(2),
+                emptyList<Int>(),
+                listOf(3),
+                emptyList<Int>(),
+            )
+
+        assertThat(collectJob.isCompleted).isTrue()
+    }
+
+    @Test
+    fun emptyFlow() = runTest {
+        val choreographer = createChoreographer(this)
+        val output = mutableListOf<List<Int>>()
+
+        val collectJob =
+            backgroundScope.launch {
+                emptyFlow<Int>().slidingWindow(100.milliseconds).toList(output)
+            }
+
+        choreographer.advanceAndRun(0)
+        assertThat(output).isEmpty()
+
+        assertThat(collectJob.isCompleted).isTrue()
+    }
+
+    private fun createChoreographer(testScope: TestScope) =
+        object {
+            val fakeClock = FakeSystemClock()
+
+            fun advanceAndRun(millis: Long) {
+                fakeClock.advanceTime(millis)
+                testScope.advanceTimeBy(millis)
+                testScope.runCurrent()
+            }
+        }
+}
+
 private fun <T> assertThatFlow(flow: Flow<T>) =
     object {
         suspend fun emitsExactly(vararg emissions: T) =
             assertThat(flow.toList()).containsExactly(*emissions).inOrder()
+
         suspend fun emitsNothing() = assertThat(flow.toList()).isEmpty()
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/GradientColorWallpaperTest.kt b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/GradientColorWallpaperTest.kt
index 5f34420..422b20e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallpapers/GradientColorWallpaperTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallpapers/GradientColorWallpaperTest.kt
@@ -45,7 +45,7 @@
 import org.mockito.kotlin.doReturn
 import org.mockito.kotlin.times
 import org.mockito.kotlin.verify
-import org.mockito.kotlin.verifyZeroInteractions
+import org.mockito.kotlin.verifyNoMoreInteractions
 import org.mockito.kotlin.whenever
 
 @SmallTest
@@ -92,7 +92,7 @@
 
         engine.onSurfaceRedrawNeeded(surfaceHolder)
 
-        verifyZeroInteractions(canvas)
+        verifyNoMoreInteractions(canvas)
     }
 
     @Test
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
index e550e88..846db63 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/SysuiTestCase.java
@@ -15,6 +15,7 @@
  */
 package com.android.systemui;
 
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
 
@@ -28,7 +29,6 @@
 import android.os.ParcelFileDescriptor;
 import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.flag.junit.SetFlagsRule;
-import android.platform.test.ravenwood.RavenwoodClassRule;
 import android.platform.test.ravenwood.RavenwoodRule;
 import android.test.mock.MockContext;
 import android.testing.DexmakerShareClassLoaderRule;
@@ -50,11 +50,13 @@
 
 import org.junit.After;
 import org.junit.AfterClass;
+import org.junit.Assert;
 import org.junit.Before;
 import org.junit.ClassRule;
 import org.junit.Rule;
 import org.mockito.Mockito;
 
+import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.lang.annotation.Retention;
@@ -93,23 +95,6 @@
     public AndroidXAnimatorIsolationRule mAndroidXAnimatorIsolationRule =
             new AndroidXAnimatorIsolationRule();
 
-    /**
-     * Rule that respects class-level annotations such as {@code @DisabledOnRavenwood} when tests
-     * are running on Ravenwood; on all other test environments this rule is a no-op passthrough.
-     */
-    @ClassRule(order = Integer.MIN_VALUE + 1)
-    public static final RavenwoodClassRule sRavenwood = new RavenwoodClassRule();
-
-    /**
-     * Rule that defines and prepares the Ravenwood environment when tests are running on
-     * Ravenwood; on all other test environments this rule is a no-op passthrough.
-     */
-    @Rule(order = Integer.MIN_VALUE + 1)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProcessApp()
-            .setProvideMainThread(true)
-            .build();
-
     @ClassRule
     public static final SetFlagsRule.ClassRule mSetFlagsClassRule =
             new SetFlagsRule.ClassRule(
@@ -208,6 +193,7 @@
 
     @Before
     public void SysuiSetup() throws Exception {
+        assertTempFilesAreCreatable();
         ProtoLog.REQUIRE_PROTOLOGTOOL = false;
         mSysuiDependency = new SysuiTestDependency(mContext, shouldFailOnLeakedReceiver());
         mDependency = mSysuiDependency.install();
@@ -229,6 +215,28 @@
         }
     }
 
+    private static Boolean sCanCreateTempFiles = null;
+
+    private static void assertTempFilesAreCreatable() {
+        // TODO(b/391948934): hopefully remove this hack
+        if (sCanCreateTempFiles == null) {
+            try {
+                File tempFile = File.createTempFile("confirm_temp_file_createable", "txt");
+                sCanCreateTempFiles = true;
+                assertTrue(tempFile.delete());
+            } catch (IOException e) {
+                sCanCreateTempFiles = false;
+                throw new RuntimeException(e);
+            }
+        }
+        if (!sCanCreateTempFiles) {
+            Assert.fail(
+                    "Cannot create temp files, so mockito will probably fail (b/391948934).  Temp"
+                            + " folder should be: "
+                            + System.getProperty("java.io.tmpdir"));
+        }
+    }
+
     protected boolean shouldFailOnLeakedReceiver() {
         return false;
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/condition/KosmosConditionTestExtensions.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/condition/KosmosConditionTestExtensions.kt
new file mode 100644
index 0000000..c976b57
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/condition/KosmosConditionTestExtensions.kt
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.condition
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.runCurrent
+import com.android.systemui.shared.condition.Condition
+
+private val testCallback =
+    Condition.Callback {
+        // This is a no-op
+    }
+
+fun Kosmos.testStart(condition: Condition) {
+    condition.addCallback(testCallback)
+    runCurrent()
+}
+
+fun Kosmos.testStop(condition: Condition) {
+    condition.removeCallback(testCallback)
+    runCurrent()
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt
index ff4ba61..208eabc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/DisplayScopeRepositoryKosmos.kt
@@ -16,11 +16,13 @@
 
 package com.android.systemui.display.data.repository
 
+import com.android.app.displaylib.PerDisplayRepository
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.testDispatcher
+import kotlinx.coroutines.CoroutineScope
 
 val Kosmos.fakeDisplayScopeRepository by
     Kosmos.Fixture { FakeDisplayScopeRepository(testDispatcher) }
 
-var Kosmos.displayScopeRepository: DisplayScopeRepository by
+var Kosmos.displayScopeRepository: PerDisplayRepository<CoroutineScope> by
     Kosmos.Fixture { fakeDisplayScopeRepository }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
index 663a853..122e6a5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayRepository.kt
@@ -16,6 +16,7 @@
 package com.android.systemui.display.data.repository
 
 import android.view.Display
+import com.android.app.displaylib.DisplayRepository.PendingDisplay
 import com.android.systemui.dagger.SysUISingleton
 import com.android.systemui.util.mockito.mock
 import dagger.Binds
@@ -41,16 +42,15 @@
 }
 
 /** Creates a mock [DisplayRepository.PendingDisplay]. */
-fun createPendingDisplay(id: Int = 0): DisplayRepository.PendingDisplay =
-    mock<DisplayRepository.PendingDisplay> { whenever(this.id).thenReturn(id) }
+fun createPendingDisplay(id: Int = 0): PendingDisplay =
+    mock<PendingDisplay> { whenever(this.id).thenReturn(id) }
 
 @SysUISingleton
 /** Fake [DisplayRepository] implementation for testing. */
 class FakeDisplayRepository @Inject constructor() : DisplayRepository {
     private val flow = MutableStateFlow<Set<Display>>(emptySet())
     private val displayIdFlow = MutableStateFlow<Set<Int>>(emptySet())
-    private val pendingDisplayFlow =
-        MutableSharedFlow<DisplayRepository.PendingDisplay?>(replay = 1)
+    private val pendingDisplayFlow = MutableSharedFlow<PendingDisplay?>(replay = 1)
     private val displayAdditionEventFlow = MutableSharedFlow<Display?>(replay = 0)
     private val displayRemovalEventFlow = MutableSharedFlow<Int>(replay = 0)
     private val displayIdsWithSystemDecorationsFlow = MutableStateFlow<Set<Int>>(emptySet())
@@ -101,7 +101,7 @@
     suspend fun emit(value: Set<Display>) = flow.emit(value)
 
     /** Emits [value] as [pendingDisplay] flow value. */
-    suspend fun emit(value: DisplayRepository.PendingDisplay?) = pendingDisplayFlow.emit(value)
+    suspend fun emit(value: PendingDisplay?) = pendingDisplayFlow.emit(value)
 
     override val displays: StateFlow<Set<Display>>
         get() = flow
@@ -109,7 +109,7 @@
     override val displayIds: StateFlow<Set<Int>>
         get() = displayIdFlow
 
-    override val pendingDisplay: Flow<DisplayRepository.PendingDisplay?>
+    override val pendingDisplay: Flow<PendingDisplay?>
         get() = pendingDisplayFlow
 
     private val _defaultDisplayOff: MutableStateFlow<Boolean> = MutableStateFlow(false)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt
index 3c25924..84c9abf 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/FakeDisplayScopeRepository.kt
@@ -16,15 +16,18 @@
 
 package com.android.systemui.display.data.repository
 
+import com.android.app.displaylib.PerDisplayRepository
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 
-class FakeDisplayScopeRepository(private val dispatcher: CoroutineDispatcher) :
-    DisplayScopeRepository {
+class FakeDisplayScopeRepository(
+    private val dispatcher: CoroutineDispatcher,
+    override val debugName: String = "FakeDisplayScopeRepository",
+) : PerDisplayRepository<CoroutineScope> {
 
     private val perDisplayScopes = mutableMapOf<Int, CoroutineScope>()
 
-    override fun scopeForDisplay(displayId: Int): CoroutineScope {
+    override fun get(displayId: Int): CoroutineScope {
         return perDisplayScopes.computeIfAbsent(displayId) { CoroutineScope(dispatcher) }
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
index aa23aa3..161e062 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/display/data/repository/PerDisplayStoreKosmos.kt
@@ -16,6 +16,10 @@
 
 package com.android.systemui.display.data.repository
 
+import com.android.app.displaylib.DisplayInstanceLifecycleManager
+import com.android.app.displaylib.FakeDisplayInstanceLifecycleManager
+import com.android.app.displaylib.PerDisplayInstanceProviderWithTeardown
+import com.android.app.displaylib.PerDisplayInstanceRepositoryImpl
 import com.android.systemui.dump.dumpManager
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
@@ -66,13 +70,26 @@
 val Kosmos.fakePerDisplayInstanceProviderWithTeardown by
     Kosmos.Fixture { FakePerDisplayInstanceProviderWithTeardown() }
 
+val Kosmos.perDisplayDumpHelper by Kosmos.Fixture { PerDisplayRepoDumpHelper(dumpManager) }
+val Kosmos.fakeDisplayInstanceLifecycleManager by
+    Kosmos.Fixture { FakeDisplayInstanceLifecycleManager() }
+
 val Kosmos.fakePerDisplayInstanceRepository by
     Kosmos.Fixture {
-        PerDisplayInstanceRepositoryImpl(
-            debugName = "fakePerDisplayInstanceRepository",
-            instanceProvider = fakePerDisplayInstanceProviderWithTeardown,
-            testScope.backgroundScope,
-            displayRepository,
-            dumpManager,
-        )
+        { lifecycleManager: DisplayInstanceLifecycleManager? ->
+            PerDisplayInstanceRepositoryImpl(
+                debugName = "fakePerDisplayInstanceRepository",
+                instanceProvider = fakePerDisplayInstanceProviderWithTeardown,
+                lifecycleManager,
+                testScope.backgroundScope,
+                displayRepository,
+                perDisplayDumpHelper,
+            )
+        }
     }
+
+fun Kosmos.createPerDisplayInstanceRepository(
+    overrideLifecycleManager: DisplayInstanceLifecycleManager? = null
+): PerDisplayInstanceRepositoryImpl<TestPerDisplayInstance> {
+    return fakePerDisplayInstanceRepository(overrideLifecycleManager)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
index 623989e..c80d738 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/kosmos/KosmosJavaAdapter.kt
@@ -81,6 +81,7 @@
 import com.android.systemui.statusbar.notification.collection.provider.visualStabilityProvider
 import com.android.systemui.statusbar.notification.domain.interactor.activeNotificationsInteractor
 import com.android.systemui.statusbar.notification.domain.interactor.seenNotificationsInteractor
+import com.android.systemui.statusbar.notification.row.entryAdapterFactory
 import com.android.systemui.statusbar.notification.stack.domain.interactor.headsUpNotificationInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.sharedNotificationContainerInteractor
 import com.android.systemui.statusbar.phone.fakeAutoHideControllerStore
@@ -206,4 +207,5 @@
     val displayTracker by lazy { kosmos.displayTracker }
     val fakeShadeDisplaysRepository by lazy { kosmos.fakeShadeDisplaysRepository }
     val sysUIStateDispatcher by lazy { kosmos.sysUIStateDispatcher }
+    val entryAdapterFactory by lazy { kosmos.entryAdapterFactory }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
index 11bd4c7..54261c7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/model/SysUiStateKosmos.kt
@@ -38,7 +38,9 @@
     }
 }
 
-val Kosmos.fakeSysUIStatePerDisplayRepository by Fixture { FakePerDisplayRepository<SysUiState>() }
+val Kosmos.fakeSysUIStatePerDisplayRepository by Fixture {
+    FakePerDisplayRepository<SysUiState>().apply { add(Display.DEFAULT_DISPLAY, sysUiState) }
+}
 
 val Kosmos.sysuiStateInteractor by Fixture {
     SysUIStateDisplaysInteractor(fakeSysUIStatePerDisplayRepository, displayRepository)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorKosmos.kt
index bd54fd4..2cd270e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/EditTilesListInteractorKosmos.kt
@@ -19,7 +19,7 @@
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.panels.data.repository.iconAndNameCustomRepository
 import com.android.systemui.qs.panels.data.repository.stockTilesRepository
-import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider
+import com.android.systemui.qs.tiles.base.shared.model.qSTileConfigProvider
 
 val Kosmos.editTilesListInteractor by
     Kosmos.Fixture {
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FakeTileAvailabilityInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FakeTileAvailabilityInteractor.kt
index cc7eb6b..7887762 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FakeTileAvailabilityInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/FakeTileAvailabilityInteractor.kt
@@ -17,12 +17,11 @@
 package com.android.systemui.qs.panels.domain.interactor
 
 import android.os.UserHandle
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
 import kotlinx.coroutines.flow.Flow
 
-class FakeTileAvailabilityInteractor(
-        private val availabilityFlows: Map<Int, Flow<Boolean>>
-) : QSTileAvailabilityInteractor {
+class FakeTileAvailabilityInteractor(private val availabilityFlows: Map<Int, Flow<Boolean>>) :
+    QSTileAvailabilityInteractor {
     override fun availability(user: UserHandle): Flow<Boolean> {
         return availabilityFlows.getValue(user.identifier)
     }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorKosmos.kt
index 40e6c75..6a65706 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/domain/interactor/NewTilesAvailabilityInteractorKosmos.kt
@@ -17,16 +17,13 @@
 package com.android.systemui.qs.panels.domain.interactor
 
 import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.qs.tiles.base.interactor.QSTileAvailabilityInteractor
+import com.android.systemui.qs.tiles.base.domain.interactor.QSTileAvailabilityInteractor
 import com.android.systemui.user.data.repository.userRepository
 
-var Kosmos.tileAvailabilityInteractorsMap by Kosmos.Fixture {
-    emptyMap<String, QSTileAvailabilityInteractor>()
-}
+var Kosmos.tileAvailabilityInteractorsMap by
+    Kosmos.Fixture { emptyMap<String, QSTileAvailabilityInteractor>() }
 
-val Kosmos.newTilesAvailabilityInteractor by Kosmos.Fixture {
-    NewTilesAvailabilityInteractor(
-            tileAvailabilityInteractorsMap,
-            userRepository,
-    )
-}
+val Kosmos.newTilesAvailabilityInteractor by
+    Kosmos.Fixture {
+        NewTilesAvailabilityInteractor(tileAvailabilityInteractorsMap, userRepository)
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
index dc22905..56fd270 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/panels/ui/viewmodel/DetailsViewModelKosmos.kt
@@ -18,5 +18,11 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
+import com.android.systemui.shade.domain.interactor.shadeModeInteractor
 
-val Kosmos.detailsViewModel by Kosmos.Fixture { DetailsViewModel(currentTilesInteractor) }
+val Kosmos.detailsViewModel by Kosmos.Fixture {
+    DetailsViewModel(
+        currentTilesInteractor,
+        shadeModeInteractor
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt
index d97a5b2..4823607 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/pipeline/domain/interactor/CurrentTilesInteractorKosmos.kt
@@ -29,7 +29,7 @@
 import com.android.systemui.qs.pipeline.shared.logging.qsLogger
 import com.android.systemui.qs.pipeline.shared.pipelineFlagsRepository
 import com.android.systemui.qs.qsTileFactory
-import com.android.systemui.qs.tiles.di.newQSTileFactory
+import com.android.systemui.qs.tiles.base.ui.model.newQSTileFactory
 import com.android.systemui.settings.userTracker
 import com.android.systemui.user.data.repository.userRepository
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/FakeQSTileIntentUserInputHandler.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/FakeQSTileIntentUserInputHandler.kt
similarity index 89%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/FakeQSTileIntentUserInputHandler.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/FakeQSTileIntentUserInputHandler.kt
index f50443e..1319787 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/FakeQSTileIntentUserInputHandler.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/FakeQSTileIntentUserInputHandler.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.actions
+package com.android.systemui.qs.tiles.base.domain.actions
 
 import android.app.PendingIntent
 import android.content.Intent
@@ -34,7 +34,7 @@
     override fun handle(
         expandable: Expandable?,
         intent: Intent,
-        handleDismissShadeShowOverLockScreenWhenLocked: Boolean
+        handleDismissShadeShowOverLockScreenWhenLocked: Boolean,
     ) {
         mutableInputs.add(Input.Intent(expandable, intent))
     }
@@ -42,7 +42,7 @@
     override fun handle(
         expandable: Expandable?,
         pendingIntent: PendingIntent,
-        requestLaunchingDefaultActivity: Boolean
+        requestLaunchingDefaultActivity: Boolean,
     ) {
         mutableInputs.add(
             Input.PendingIntent(expandable, pendingIntent, requestLaunchingDefaultActivity)
@@ -51,10 +51,11 @@
 
     sealed interface Input {
         data class Intent(val expandable: Expandable?, val intent: android.content.Intent) : Input
+
         data class PendingIntent(
             val expandable: Expandable?,
             val pendingIntent: android.app.PendingIntent,
-            val requestLaunchingDefaultActivity: Boolean
+            val requestLaunchingDefaultActivity: Boolean,
         ) : Input
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerKosmos.kt
similarity index 92%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerKosmos.kt
index ccfb609..b884b8a 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerKosmos.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.actions
+package com.android.systemui.qs.tiles.base.domain.actions
 
 import com.android.systemui.kosmos.Kosmos
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerSubject.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerSubject.kt
similarity index 93%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerSubject.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerSubject.kt
index c1e689c..3b7810e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerSubject.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/actions/QSTileIntentUserInputHandlerSubject.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.actions
+package com.android.systemui.qs.tiles.base.domain.actions
 
 import com.google.common.truth.FailureMetadata
 import com.google.common.truth.Subject
@@ -24,11 +24,11 @@
 class QSTileIntentUserInputHandlerSubject
 private constructor(
     failureMetadata: FailureMetadata,
-    private val subject: FakeQSTileIntentUserInputHandler
+    private val subject: FakeQSTileIntentUserInputHandler,
 ) : Subject(failureMetadata, subject) {
 
     fun handledOneIntentInput(
-        intentAssertions: (FakeQSTileIntentUserInputHandler.Input.Intent) -> Unit = {},
+        intentAssertions: (FakeQSTileIntentUserInputHandler.Input.Intent) -> Unit = {}
     ) {
         // check that there are no other inputs
         check("handledInputs").that(subject.handledInputs).hasSize(1)
@@ -39,7 +39,7 @@
     }
 
     fun handledOnePendingIntentInput(
-        intentAssertions: (FakeQSTileIntentUserInputHandler.Input.PendingIntent) -> Unit = {},
+        intentAssertions: (FakeQSTileIntentUserInputHandler.Input.PendingIntent) -> Unit = {}
     ) {
         // check that there are no other inputs
         check("handledInputs").that(subject.handledInputs).hasSize(1)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorKosmos.kt
similarity index 92%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorKosmos.kt
index 9ad49f0..2ffc479 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/DisabledByPolicyInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/DisabledByPolicyInteractorKosmos.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.interactor
 
 import com.android.systemui.kosmos.Kosmos
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeDisabledByPolicyInteractor.kt
similarity index 94%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeDisabledByPolicyInteractor.kt
index fb6ba20..5bdeeab 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeDisabledByPolicyInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeDisabledByPolicyInteractor.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.interactor
 
 import android.os.UserHandle
 import com.android.settingslib.RestrictedLockUtils
@@ -23,7 +23,7 @@
 
     override suspend fun isDisabled(
         user: UserHandle,
-        userRestriction: String?
+        userRestriction: String?,
     ): DisabledByPolicyInteractor.PolicyResult =
         if (userRestriction == DISABLED_RESTRICTION || userRestriction == DISABLED_RESTRICTION_2) {
             DisabledByPolicyInteractor.PolicyResult.TileDisabled(
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileDataInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileDataInteractor.kt
similarity index 94%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileDataInteractor.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileDataInteractor.kt
index 3fcf8a9..6bd8152 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileDataInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileDataInteractor.kt
@@ -14,9 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.interactor
 
 import android.os.UserHandle
+import com.android.systemui.qs.tiles.base.domain.model.DataUpdateTrigger
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
 import kotlinx.coroutines.flow.flatMapLatest
@@ -26,6 +27,7 @@
     private val dataFlow: MutableSharedFlow<T> = MutableSharedFlow(replay = 1)
     val dataSubscriptionCount
         get() = dataFlow.subscriptionCount
+
     private val availabilityFlow: MutableSharedFlow<Boolean> = MutableSharedFlow(replay = 1)
     val availabilitySubscriptionCount
         get() = availabilityFlow.subscriptionCount
@@ -42,6 +44,7 @@
     suspend fun emitData(data: T): Unit = dataFlow.emit(data)
 
     fun tryEmitAvailability(isAvailable: Boolean): Boolean = availabilityFlow.tryEmit(isAvailable)
+
     suspend fun emitAvailability(isAvailable: Boolean) = availabilityFlow.emit(isAvailable)
 
     override fun tileData(user: UserHandle, triggers: Flow<DataUpdateTrigger>): Flow<T> {
@@ -58,5 +61,6 @@
     }
 
     data class DataRequest(val user: UserHandle)
+
     data class AvailabilityRequest(val user: UserHandle)
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileUserActionInteractor.kt
similarity index 86%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileUserActionInteractor.kt
index c058490..8fd87a3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/FakeQSTileUserActionInteractor.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/interactor/FakeQSTileUserActionInteractor.kt
@@ -14,10 +14,9 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.interactor
 
-import com.android.systemui.plugins.qs.TileDetailsViewModel
-import com.android.systemui.qs.FakeTileDetailsViewModel
+import com.android.systemui.qs.tiles.base.domain.model.QSTileInput
 import kotlinx.coroutines.sync.Mutex
 import kotlinx.coroutines.sync.withLock
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInputTestKtx.kt
similarity index 87%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInputTestKtx.kt
index 3943d1d..5c2b4a6 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/interactor/QSTileInputTestKtx.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/domain/model/QSTileInputTestKtx.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,11 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.interactor
+package com.android.systemui.qs.tiles.base.domain.model
 
 import android.os.UserHandle
 import com.android.systemui.animation.Expandable
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
 
 object QSTileInputTestKtx {
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/FakeQSTileConfigProvider.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/FakeQSTileConfigProvider.kt
similarity index 90%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/FakeQSTileConfigProvider.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/FakeQSTileConfigProvider.kt
index d231d63..97e6583 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/FakeQSTileConfigProvider.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/FakeQSTileConfigProvider.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import com.android.systemui.qs.pipeline.shared.TileSpec
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderKosmos.kt
similarity index 87%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderKosmos.kt
index 1d57979..d1b410c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigProviderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigProviderKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import com.android.systemui.kosmos.Kosmos
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigTestBuilder.kt
similarity index 79%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigTestBuilder.kt
index 73d9b32..8938ebc 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileConfigTestBuilder.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/shared/model/QSTileConfigTestBuilder.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.shared.model
 
 import com.android.internal.logging.InstanceId
 import com.android.systemui.qs.pipeline.shared.TileSpec
@@ -33,14 +33,6 @@
         var policy: QSTilePolicy = QSTilePolicy.NoRestrictions
         var category: TileCategory = TileCategory.UNKNOWN
 
-        fun build() =
-            QSTileConfig(
-                tileSpec,
-                uiConfig,
-                instanceId,
-                category,
-                metricsSpec,
-                policy,
-            )
+        fun build() = QSTileConfig(tileSpec, uiConfig, instanceId, category, metricsSpec, policy)
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsKosmos.kt
similarity index 93%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsKosmos.kt
index 146c1ad..753824b 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/analytics/QSTileAnalyticsKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/analytics/QSTileAnalyticsKosmos.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.analytics
+package com.android.systemui.qs.tiles.base.ui.analytics
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.util.mockito.mock
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactoryKosmos.kt
similarity index 80%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactoryKosmos.kt
index c223be4..3c29730 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/di/NewQSTileFactoryKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/NewQSTileFactoryKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.di
+package com.android.systemui.qs.tiles.base.ui.model
 
 import android.os.UserHandle
 import com.android.systemui.kosmos.Kosmos
@@ -22,14 +22,14 @@
 import com.android.systemui.qs.pipeline.domain.interactor.currentTilesInteractor
 import com.android.systemui.qs.pipeline.shared.TileSpec
 import com.android.systemui.qs.shared.model.TileCategory
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelFactory
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
-import com.android.systemui.qs.tiles.viewmodel.QSTileUIConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileUserAction
-import com.android.systemui.qs.tiles.viewmodel.QSTileViewModel
-import com.android.systemui.qs.tiles.viewmodel.qSTileConfigProvider
-import com.android.systemui.qs.tiles.viewmodel.qsTileViewModelAdaperFactory
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUIConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileUserAction
+import com.android.systemui.qs.tiles.base.shared.model.qSTileConfigProvider
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModel
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelFactory
+import com.android.systemui.qs.tiles.base.ui.viewmodel.qsTileViewModelAdaperFactory
 import com.android.systemui.util.mockito.any
 import com.android.systemui.util.mockito.mock
 import com.android.systemui.util.mockito.whenever
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/QSTileStateSubject.kt
similarity index 85%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/QSTileStateSubject.kt
index 657a95a..54e85f1 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/QSTileStateSubject.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/model/QSTileStateSubject.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2023 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,15 +14,11 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.impl.custom
+package com.android.systemui.qs.tiles.base.ui.model
 
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject.Companion.assertThat
-import com.android.systemui.qs.tiles.impl.custom.QSTileStateSubject.Companion.states
-import com.android.systemui.qs.tiles.impl.custom.TileSubject.Companion.assertThat
-import com.android.systemui.qs.tiles.viewmodel.QSTileState
+import com.android.systemui.qs.tiles.base.shared.model.QSTileState
 import com.google.common.truth.FailureMetadata
 import com.google.common.truth.Subject
-import com.google.common.truth.Subject.Factory
 import com.google.common.truth.Truth
 
 /**
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapterKosmos.kt
similarity index 91%
rename from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
rename to packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapterKosmos.kt
index de9f629..cbadf8e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/viewmodel/QSTileViewModelAdapterKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/ui/viewmodel/QSTileViewModelAdapterKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.viewmodel
+package com.android.systemui.qs.tiles.base.ui.viewmodel
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.applicationCoroutineScope
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt
index 42437d5a..77f561e 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/CustomTileKosmos.kt
@@ -22,11 +22,12 @@
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.plugins.activityStarter
 import com.android.systemui.qs.external.FakeCustomTileStatePersister
-import com.android.systemui.qs.external.tileServices
 import com.android.systemui.qs.external.tileServicesFacade
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.base.actions.FakeQSTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.domain.actions.FakeQSTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.shared.logging.QSTileLogger
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfig
+import com.android.systemui.qs.tiles.base.shared.model.QSTileConfigTestBuilder
 import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTileDefaultsRepository
 import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTilePackageUpdatesRepository
 import com.android.systemui.qs.tiles.impl.custom.data.repository.FakeCustomTileRepository
@@ -34,8 +35,6 @@
 import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileInteractor
 import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileServiceInteractor
 import com.android.systemui.qs.tiles.impl.custom.domain.interactor.CustomTileUserActionInteractor
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfig
-import com.android.systemui.qs.tiles.viewmodel.QSTileConfigTestBuilder
 import com.android.systemui.user.data.repository.userRepository
 import com.android.systemui.util.mockito.mock
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt
index ccba072..7b9d601 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileDefaultsRepository.kt
@@ -18,7 +18,7 @@
 
 import android.content.ComponentName
 import android.os.UserHandle
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
 import kotlinx.coroutines.channels.BufferOverflow
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableSharedFlow
@@ -31,7 +31,7 @@
     private val defaultsFlow =
         MutableSharedFlow<DefaultsRequest>(
             replay = 1,
-            onBufferOverflow = BufferOverflow.DROP_OLDEST
+            onBufferOverflow = BufferOverflow.DROP_OLDEST,
         )
 
     private val mutableDefaultsRequests: MutableList<DefaultsRequest> = mutableListOf()
@@ -51,7 +51,7 @@
     override fun requestNewDefaults(
         user: UserHandle,
         componentName: ComponentName,
-        force: Boolean
+        force: Boolean,
     ) {
         val request = DefaultsRequest(user, componentName, force)
         mutableDefaultsRequests.add(request)
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt
index c110da0..c9ed71c 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/custom/data/repository/FakeCustomTileRepository.kt
@@ -20,7 +20,7 @@
 import android.service.quicksettings.Tile
 import com.android.systemui.qs.external.FakeCustomTileStatePersister
 import com.android.systemui.qs.pipeline.shared.TileSpec
-import com.android.systemui.qs.tiles.impl.custom.data.entity.CustomTileDefaults
+import com.android.systemui.qs.tiles.impl.custom.data.model.CustomTileDefaults
 import kotlin.coroutines.CoroutineContext
 import kotlinx.coroutines.flow.Flow
 
@@ -54,11 +54,8 @@
 
     override suspend fun isTileToggleable(): Boolean = realDelegate.isTileToggleable()
 
-    override suspend fun updateWithTile(
-        user: UserHandle,
-        newTile: Tile,
-        isPersistable: Boolean,
-    ) = realDelegate.updateWithTile(user, newTile, isPersistable)
+    override suspend fun updateWithTile(user: UserHandle, newTile: Tile, isPersistable: Boolean) =
+        realDelegate.updateWithTile(user, newTile, isPersistable)
 
     override suspend fun updateWithDefaults(
         user: UserHandle,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt
index 3f07d05..f94da17 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/modes/domain/interactor/ModesTileUserActionInteractorKosmos.kt
@@ -18,7 +18,7 @@
 
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.mainCoroutineContext
-import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
 import com.android.systemui.statusbar.policy.ui.dialog.modesDialogDelegate
 import com.android.systemui.statusbar.policy.ui.dialog.modesDialogEventLogger
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
index 537be4f..5cd11e0 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/qr/QRCodeScannerTileKosmos.kt
@@ -23,17 +23,17 @@
 import com.android.systemui.kosmos.backgroundCoroutineContext
 import com.android.systemui.kosmos.testDispatcher
 import com.android.systemui.kosmos.testScope
-import com.android.systemui.qrcodescanner.dagger.QRCodeScannerModule
 import com.android.systemui.qrcodescanner.qrCodeScannerController
 import com.android.systemui.qs.qsEventLogger
-import com.android.systemui.qs.tiles.base.actions.qsTileIntentUserInputHandler
-import com.android.systemui.qs.tiles.base.analytics.qsTileAnalytics
-import com.android.systemui.qs.tiles.base.interactor.fakeDisabledByPolicyInteractor
-import com.android.systemui.qs.tiles.base.viewmodel.QSTileViewModelImpl
+import com.android.systemui.qs.tiles.base.domain.actions.qsTileIntentUserInputHandler
+import com.android.systemui.qs.tiles.base.domain.interactor.fakeDisabledByPolicyInteractor
+import com.android.systemui.qs.tiles.base.ui.analytics.qsTileAnalytics
+import com.android.systemui.qs.tiles.base.ui.viewmodel.QSTileViewModelImpl
 import com.android.systemui.qs.tiles.impl.custom.qsTileLogger
 import com.android.systemui.qs.tiles.impl.qr.domain.interactor.QRCodeScannerTileDataInteractor
 import com.android.systemui.qs.tiles.impl.qr.domain.interactor.QRCodeScannerTileUserActionInteractor
-import com.android.systemui.qs.tiles.impl.qr.ui.QRCodeScannerTileMapper
+import com.android.systemui.qs.tiles.impl.qr.ui.mapper.QRCodeScannerTileMapper
+import com.android.systemui.qs.tiles.impl.qr.ui.model.QRCodeScannerModule
 import com.android.systemui.user.data.repository.fakeUserRepository
 import com.android.systemui.util.time.systemClock
 
@@ -45,7 +45,7 @@
         QRCodeScannerTileDataInteractor(
             backgroundCoroutineContext,
             applicationCoroutineScope,
-            qrCodeScannerController
+            qrCodeScannerController,
         )
     }
 
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/uimodenight/UiModeNightTileModelHelper.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/uimodenight/UiModeNightTileModelHelper.kt
index 1fe18e3..0045960 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/uimodenight/UiModeNightTileModelHelper.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/impl/uimodenight/UiModeNightTileModelHelper.kt
@@ -17,7 +17,7 @@
 package com.android.systemui.qs.tiles.impl.uimodenight
 
 import android.content.res.Configuration
-import com.android.systemui.qs.tiles.impl.uimodenight.domain.model.UiModeNightTileModel
+import com.android.systemui.qs.tiles.impl.uimodenight.domain.interactor.model.UiModeNightTileModel
 import java.time.LocalTime
 
 object UiModeNightTileModelHelper {
@@ -34,7 +34,7 @@
         nighModeCustomType: Int = DEFAULT_NIGHT_MODE_CUSTOM_TYPE,
         is24HourFormat: Boolean = false,
         customNightModeEnd: LocalTime = defaultCustomNightEnd,
-        customNightModeStart: LocalTime = defaultCustomNightStart
+        customNightModeStart: LocalTime = defaultCustomNightStart,
     ): UiModeNightTileModel {
         return UiModeNightTileModel(
             uiMode,
@@ -44,7 +44,7 @@
             nighModeCustomType,
             is24HourFormat,
             customNightModeEnd,
-            customNightModeStart
+            customNightModeStart,
         )
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationEntryBuilderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationEntryBuilderKosmos.kt
deleted file mode 100644
index 59f5ecd..0000000
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/NotificationEntryBuilderKosmos.kt
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification
-
-import android.app.Notification
-import android.app.PendingIntent
-import android.app.Person
-import android.content.Intent
-import android.content.applicationContext
-import android.graphics.drawable.Icon
-import com.android.systemui.kosmos.Kosmos
-import com.android.systemui.statusbar.notification.collection.NotificationEntry
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
-import com.android.systemui.statusbar.notification.icon.IconPack
-import com.android.systemui.statusbar.notification.promoted.setPromotedContent
-import org.mockito.kotlin.mock
-
-fun Kosmos.setIconPackWithMockIconViews(entry: NotificationEntry) {
-    entry.icons =
-        IconPack.buildPack(
-            /* statusBarIcon = */ mock(),
-            /* statusBarChipIcon = */ mock(),
-            /* shelfIcon = */ mock(),
-            /* aodIcon = */ mock(),
-            /* source = */ null,
-        )
-}
-
-fun Kosmos.buildOngoingCallEntry(
-    promoted: Boolean = false,
-    block: NotificationEntryBuilder.() -> Unit = {},
-): NotificationEntry =
-    buildNotificationEntry(
-        tag = "call",
-        promoted = promoted,
-        style = makeOngoingCallStyle(),
-        block = block,
-    )
-
-fun Kosmos.buildPromotedOngoingEntry(
-    block: NotificationEntryBuilder.() -> Unit = {}
-): NotificationEntry =
-    buildNotificationEntry(tag = "ron", promoted = true, style = null, block = block)
-
-fun Kosmos.buildNotificationEntry(
-    tag: String? = null,
-    promoted: Boolean = false,
-    style: Notification.Style? = null,
-    block: NotificationEntryBuilder.() -> Unit = {},
-): NotificationEntry =
-    NotificationEntryBuilder()
-        .apply {
-            setTag(tag)
-            setFlag(applicationContext, Notification.FLAG_PROMOTED_ONGOING, promoted)
-            modifyNotification(applicationContext)
-                .setSmallIcon(Icon.createWithContentUri("content://null"))
-                .setStyle(style)
-        }
-        .apply(block)
-        .build()
-        .also {
-            setIconPackWithMockIconViews(it)
-            if (promoted) setPromotedContent(it)
-        }
-
-private fun Kosmos.makeOngoingCallStyle(): Notification.CallStyle {
-    val pendingIntent =
-        PendingIntent.getBroadcast(
-            applicationContext,
-            0,
-            Intent("action"),
-            PendingIntent.FLAG_IMMUTABLE,
-        )
-    val person = Person.Builder().setName("person").build()
-    return Notification.CallStyle.forOngoingCall(person, pendingIntent)
-}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java
index 4efcada..215df9d 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/GroupEntryBuilder.java
@@ -58,7 +58,7 @@
         return this;
     }
 
-    /** Sets the creation time. */
+    /** Sets the creation time. Should be SystemClock.elapsedRealtime */
     public GroupEntryBuilder setCreationTime(long creationTime) {
         mCreationTime = creationTime;
         return this;
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilderKosmos.kt
new file mode 100644
index 0000000..00c6c94
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryBuilderKosmos.kt
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification.collection
+
+import android.app.Notification
+import android.app.NotificationChannel
+import android.app.NotificationManager.IMPORTANCE_DEFAULT
+import android.app.PendingIntent
+import android.app.Person
+import android.content.Intent
+import android.content.applicationContext
+import android.graphics.Bitmap
+import android.graphics.drawable.Icon
+import com.android.systemui.activity.EmptyTestActivity
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.res.R
+import com.android.systemui.statusbar.notification.icon.IconPack
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.PeopleNotificationType
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_IMPORTANT_PERSON
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_NON_PERSON
+import com.android.systemui.statusbar.notification.promoted.setPromotedContent
+import org.mockito.kotlin.mock
+
+fun Kosmos.setIconPackWithMockIconViews(entry: NotificationEntry) {
+    entry.icons =
+        IconPack.buildPack(
+            /* statusBarIcon = */ mock(),
+            /* statusBarChipIcon = */ mock(),
+            /* shelfIcon = */ mock(),
+            /* aodIcon = */ mock(),
+            /* source = */ null,
+        )
+}
+
+fun Kosmos.buildPromotedOngoingEntry(
+    block: NotificationEntryBuilder.() -> Unit = {}
+): NotificationEntry =
+    buildNotificationEntry(tag = "ron", promoted = true, style = null, block = block)
+
+fun Kosmos.buildOngoingCallEntry(
+    promoted: Boolean = false,
+    block: NotificationEntryBuilder.() -> Unit = {},
+): NotificationEntry =
+    buildNotificationEntry(
+        tag = "call",
+        promoted = promoted,
+        style = makeOngoingCallStyle(),
+        block = block,
+    )
+
+fun Kosmos.buildNotificationEntry(
+    tag: String? = null,
+    promoted: Boolean = false,
+    style: Notification.Style? = null,
+    block: NotificationEntryBuilder.() -> Unit = {},
+): NotificationEntry =
+    NotificationEntryBuilder()
+        .apply {
+            setTag(tag)
+            setFlag(applicationContext, Notification.FLAG_PROMOTED_ONGOING, promoted)
+            modifyNotification(applicationContext)
+                .setSmallIcon(Icon.createWithContentUri("content://null"))
+                .setStyle(style)
+        }
+        .apply(block)
+        .build()
+        .also {
+            setIconPackWithMockIconViews(it)
+            if (promoted) setPromotedContent(it)
+        }
+
+private fun Kosmos.makeOngoingCallStyle(): Notification.CallStyle {
+    val pendingIntent =
+        PendingIntent.getBroadcast(
+            applicationContext,
+            0,
+            Intent("action"),
+            PendingIntent.FLAG_IMMUTABLE,
+        )
+    val person = Person.Builder().setName("person").build()
+    return Notification.CallStyle.forOngoingCall(person, pendingIntent)
+}
+
+private fun Kosmos.makeMessagingStyleNotification(): Notification.Builder {
+    val personIcon = Icon.createWithBitmap(Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888))
+    val person = Person.Builder().setIcon(personIcon).setName("Person").build()
+    val message = Notification.MessagingStyle.Message("Message!", 4323, person)
+    val bubbleIntent =
+        PendingIntent.getActivity(
+            applicationContext,
+            0,
+            Intent(applicationContext, EmptyTestActivity::class.java),
+            PendingIntent.FLAG_MUTABLE,
+        )
+
+    return Notification.Builder(applicationContext, "channelId")
+        .setSmallIcon(R.drawable.ic_person)
+        .setContentTitle("Title")
+        .setContentText("Text")
+        .setStyle(Notification.MessagingStyle(person).addMessage(message))
+        .setBubbleMetadata(
+            Notification.BubbleMetadata.Builder(
+                    bubbleIntent,
+                    Icon.createWithResource(applicationContext, R.drawable.android),
+                )
+                .setDeleteIntent(mock<PendingIntent>())
+                .setDesiredHeight(314)
+                .setAutoExpandBubble(false)
+                .build()
+        )
+}
+
+fun Kosmos.makeEntryOfPeopleType(@PeopleNotificationType type: Int): NotificationEntryBuilder {
+    val channel = NotificationChannel("messages", "messages", IMPORTANCE_DEFAULT)
+    channel.isImportantConversation = (type == TYPE_IMPORTANT_PERSON)
+    channel.setConversationId("parent", "convo")
+
+    val entry =
+        NotificationEntryBuilder().apply {
+            updateRanking {
+                it.setIsConversation(type != TYPE_NON_PERSON)
+                it.setShortcutInfo(if (type >= TYPE_FULL_PERSON) mock() else null)
+                it.setChannel(channel)
+            }
+            setNotification(makeMessagingStyleNotification().build())
+        }
+    return entry
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryKosmos.kt
similarity index 63%
copy from packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerKosmos.kt
copy to packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryKosmos.kt
index ccfb609..e127a70 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/qs/tiles/base/actions/QSTileIntentUserInputHandlerKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/collection/NotificationEntryKosmos.kt
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright (C) 2025 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-package com.android.systemui.qs.tiles.base.actions
+package com.android.systemui.statusbar.notification.collection
 
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier.Companion.TYPE_FULL_PERSON
 
-val Kosmos.qsTileIntentUserInputHandler by Kosmos.Fixture { FakeQSTileIntentUserInputHandler() }
+val Kosmos.msgStyleBubbleableFullPerson by
+    Kosmos.Fixture { makeEntryOfPeopleType(TYPE_FULL_PERSON).build() }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelKosmos.kt
index 7ccbdb7..2523975 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/row/ui/viewmodel/ActivatableNotificationViewModelKosmos.kt
@@ -19,11 +19,9 @@
 import com.android.systemui.accessibility.domain.interactor.accessibilityInteractor
 import com.android.systemui.kosmos.Kosmos
 import com.android.systemui.kosmos.Kosmos.Fixture
-import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor
 
 val Kosmos.activatableNotificationViewModel by Fixture {
     ActivatableNotificationViewModel.invoke(
         a11yInteractor = accessibilityInteractor,
-        windowRootViewBlurInteractor = windowRootViewBlurInteractor,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelKosmos.kt
index b906b60..81b1349 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/notification/shelf/ui/viewmodel/NotificationShelfViewModelKosmos.kt
@@ -20,10 +20,12 @@
 import com.android.systemui.kosmos.Kosmos.Fixture
 import com.android.systemui.statusbar.notification.row.ui.viewmodel.activatableNotificationViewModel
 import com.android.systemui.statusbar.notification.shelf.domain.interactor.notificationShelfInteractor
+import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor
 
 val Kosmos.notificationShelfViewModel by Fixture {
     NotificationShelfViewModel(
         interactor = notificationShelfInteractor,
+        windowRootViewBlurInteractor = windowRootViewBlurInteractor,
         activatableViewModel = activatableNotificationViewModel,
     )
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosKosmos.kt
new file mode 100644
index 0000000..83b8283
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/MobileIconsViewModelKairosKosmos.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
+
+import com.android.systemui.flags.featureFlagsClassic
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.statusbar.pipeline.airplane.domain.interactor.airplaneModeInteractor
+import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.mobileIconsInteractorKairos
+import com.android.systemui.statusbar.pipeline.mobile.ui.mobileViewLogger
+import com.android.systemui.util.mockito.mock
+
+@ExperimentalKairosApi
+val Kosmos.mobileIconsViewModelKairos by ActivatedKairosFixture {
+    MobileIconsViewModelKairos(
+        logger = mobileViewLogger,
+        verboseLogger = mock(),
+        interactor = mobileIconsInteractorKairos,
+        airplaneModeInteractor = airplaneModeInteractor,
+        constants = mock(),
+        flags = featureFlagsClassic,
+    )
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt
index 3ee3380..ad42a89 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKairosKosmos.kt
@@ -16,7 +16,11 @@
 
 package com.android.systemui.statusbar.pipeline.mobile.ui.viewmodel
 
+import com.android.systemui.kairos.ActivatedKairosFixture
+import com.android.systemui.kairos.ExperimentalKairosApi
 import com.android.systemui.kosmos.Kosmos
 
-val Kosmos.stackedMobileIconViewModelKairos by
-    Kosmos.Fixture { StackedMobileIconViewModelKairos(mobileIconsViewModel) }
+@ExperimentalKairosApi
+val Kosmos.stackedMobileIconViewModelKairos by ActivatedKairosFixture {
+    StackedMobileIconViewModelKairos(mobileIconsViewModelKairos)
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt
index 880ba5e..0a8e0a7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/pipeline/mobile/ui/viewmodel/StackedMobileIconViewModelKosmos.kt
@@ -18,5 +18,8 @@
 
 import com.android.systemui.kosmos.Kosmos
 
-val Kosmos.stackedMobileIconViewModel: StackedMobileIconViewModel by
-    Kosmos.Fixture { StackedMobileIconViewModel(mobileIconsViewModel) }
+var Kosmos.stackedMobileIconViewModel: StackedMobileIconViewModel by
+    Kosmos.Fixture { stackedMobileIconViewModelImpl }
+
+val Kosmos.stackedMobileIconViewModelImpl by
+    Kosmos.Fixture { StackedMobileIconViewModelImpl(mobileIconsViewModel) }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt
index f31697e8..a6332bf 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/util/settings/FakeSettings.kt
@@ -289,6 +289,37 @@
         return putString(name, value)
     }
 
+    override fun getInt(name: String): Int {
+        return getIntForUser(name, userId)
+    }
+
+    override fun getInt(name: String, default: Int): Int {
+        return getIntForUser(name, default, userId)
+    }
+
+    override fun getIntForUser(name: String, userHandle: Int): Int {
+        return getIntForUser(name, 0, userHandle)
+    }
+
+    override fun getIntForUser(name: String, default: Int, userHandle: Int): Int {
+        return values[SettingsKey(userHandle, getUriFor(name).toString())]?.toInt() ?: default
+    }
+
+    override fun putIntForUser(name: String, value: Int, userHandle: Int): Boolean {
+        val key = SettingsKey(userHandle, getUriFor(name).toString())
+        values[key] = value.toString()
+        val uri = getUriFor(name)
+        contentObservers[key]?.onEach { it.dispatchChange(false, listOf(uri), 0, userHandle) }
+        contentObserversAllUsers[uri.toString()]?.onEach {
+            it.dispatchChange(false, listOf(uri), 0, userHandle)
+        }
+        return true
+    }
+
+    override fun putInt(name: String, value: Int): Boolean {
+        return putIntForUser(name, value, userId)
+    }
+
     /** Runs current jobs on dispatcher after calling the method. */
     private fun <T> advanceDispatcher(f: () -> T): T {
         val result = f()
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProviderKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProviderKosmos.kt
index 09f9f1c..44d7a22 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProviderKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/dialog/sliders/ui/viewmodel/VolumeDialogSliderIconProviderKosmos.kt
@@ -18,6 +18,7 @@
 
 import android.content.applicationContext
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.backgroundCoroutineContext
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
 import com.android.systemui.volume.domain.interactor.audioVolumeInteractor
 
@@ -25,6 +26,7 @@
     Kosmos.Fixture {
         VolumeDialogSliderIconProvider(
             context = applicationContext,
+            uiBackgroundContext = backgroundCoroutineContext,
             audioVolumeInteractor = audioVolumeInteractor,
             zenModeInteractor = zenModeInteractor,
         )
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt
index 8c8d024..6e43d79 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioSharingStreamSliderViewModelKosmos.kt
@@ -16,9 +16,11 @@
 
 package com.android.systemui.volume.panel.component.volume.slider.ui.viewmodel
 
+import android.content.applicationContext
 import com.android.internal.logging.uiEventLogger
 import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.backgroundCoroutineContext
 import com.android.systemui.volume.domain.interactor.audioSharingInteractor
 import com.android.systemui.volume.shared.volumePanelLogger
 import kotlinx.coroutines.CoroutineScope
@@ -28,7 +30,9 @@
         object : AudioSharingStreamSliderViewModel.Factory {
             override fun create(coroutineScope: CoroutineScope): AudioSharingStreamSliderViewModel {
                 return AudioSharingStreamSliderViewModel(
+                    applicationContext,
                     coroutineScope,
+                    backgroundCoroutineContext,
                     audioSharingInteractor,
                     uiEventLogger,
                     sliderHapticsViewModelFactory,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
index 88c716e..47016e5 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/AudioStreamSliderViewModelKosmos.kt
@@ -20,6 +20,7 @@
 import com.android.internal.logging.uiEventLogger
 import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.backgroundCoroutineContext
 import com.android.systemui.statusbar.policy.domain.interactor.zenModeInteractor
 import com.android.systemui.volume.domain.interactor.audioSharingInteractor
 import com.android.systemui.volume.domain.interactor.audioVolumeInteractor
@@ -37,6 +38,7 @@
                 return AudioStreamSliderViewModel(
                     audioStream,
                     coroutineScope,
+                    backgroundCoroutineContext,
                     applicationContext,
                     audioVolumeInteractor,
                     zenModeInteractor,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModelKosmos.kt
index 6875619..ed51e05 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/volume/panel/component/volume/slider/ui/viewmodel/CastVolumeSliderViewModelKosmos.kt
@@ -19,6 +19,7 @@
 import android.content.applicationContext
 import com.android.systemui.haptics.slider.sliderHapticsViewModelFactory
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.backgroundCoroutineContext
 import com.android.systemui.volume.mediaDeviceSessionInteractor
 import com.android.systemui.volume.panel.component.mediaoutput.shared.model.MediaDeviceSession
 import com.android.systemui.volume.shared.volumePanelLogger
@@ -34,6 +35,7 @@
                 return CastVolumeSliderViewModel(
                     session,
                     coroutineScope,
+                    backgroundCoroutineContext,
                     applicationContext,
                     mediaDeviceSessionInteractor,
                     sliderHapticsViewModelFactory,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt
index 5a02bfb..e56f32f3 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/window/ui/viewmodel/WindowRootViewModelKosmos.kt
@@ -16,9 +16,11 @@
 
 package com.android.systemui.window.ui.viewmodel
 
+import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
 import com.android.systemui.keyguard.ui.transitions.FakeBouncerTransition
 import com.android.systemui.keyguard.ui.transitions.FakeGlanceableHubTransition
 import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.shade.domain.interactor.shadeInteractor
 import com.android.systemui.window.domain.interactor.windowRootViewBlurInteractor
 import org.mockito.internal.util.collections.Sets
 
@@ -38,5 +40,7 @@
             fakeBouncerTransitions,
             fakeGlanceableHubTransitions,
             windowRootViewBlurInteractor,
+            keyguardInteractor,
+            shadeInteractor,
         )
     }
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Graph.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Graph.kt
index b956e44..90a9271 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Graph.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/Graph.kt
@@ -281,7 +281,6 @@
                             },
                     )
                 }
-                downstreamSet.clear()
             }
         }
         reset()
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxDeferred.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxDeferred.kt
index c11eb12..81f3702 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxDeferred.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxDeferred.kt
@@ -145,7 +145,14 @@
                 val conn = branchNode.upstream
                 severed.add(conn)
                 conn.removeDownstream(downstream = branchNode.schedulable)
-                depthTracker.removeDirectUpstream(conn.depthTracker.snapshotDirectDepth)
+                if (conn.depthTracker.snapshotIsDirect) {
+                    depthTracker.removeDirectUpstream(conn.depthTracker.snapshotDirectDepth)
+                } else {
+                    depthTracker.removeIndirectUpstream(conn.depthTracker.snapshotIndirectDepth)
+                    depthTracker.updateIndirectRoots(
+                        removals = conn.depthTracker.snapshotIndirectRoots
+                    )
+                }
             }
         }
 
@@ -156,7 +163,14 @@
                 val conn = branchNode.upstream
                 severed.add(conn)
                 conn.removeDownstream(downstream = branchNode.schedulable)
-                depthTracker.removeDirectUpstream(conn.depthTracker.snapshotDirectDepth)
+                if (conn.depthTracker.snapshotIsDirect) {
+                    depthTracker.removeDirectUpstream(conn.depthTracker.snapshotDirectDepth)
+                } else {
+                    depthTracker.removeIndirectUpstream(conn.depthTracker.snapshotIndirectDepth)
+                    depthTracker.updateIndirectRoots(
+                        removals = conn.depthTracker.snapshotIndirectRoots
+                    )
+                }
             }
 
             // add new
@@ -343,13 +357,8 @@
                 val (patchesConn, needsEval) =
                     getPatches(evalScope).activate(evalScope, downstream = muxNode.schedulable)
                         ?: run {
-                            // Turns out we can't connect to patches, so update our depth and
-                            // propagate
-                            if (muxNode.depthTracker.setIsIndirectRoot(false)) {
-                                // TODO: schedules might not be necessary now that we're not
-                                // parallel?
-                                muxNode.depthTracker.schedule(evalScope.scheduler, muxNode)
-                            }
+                            // Turns out we can't connect to patches, so update our depth
+                            muxNode.depthTracker.setIsIndirectRoot(false)
                             return
                         }
                 muxNode.patches = patchesConn
diff --git a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxPrompt.kt b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxPrompt.kt
index cb2c6e5..faef6a2 100644
--- a/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxPrompt.kt
+++ b/packages/SystemUI/utils/kairos/src/com/android/systemui/kairos/internal/MuxPrompt.kt
@@ -109,7 +109,14 @@
                 val conn: NodeConnection<V> = branchNode.upstream
                 severed.add(conn)
                 conn.removeDownstream(downstream = branchNode.schedulable)
-                depthTracker.removeDirectUpstream(conn.depthTracker.snapshotDirectDepth)
+                if (conn.depthTracker.snapshotIsDirect) {
+                    depthTracker.removeDirectUpstream(conn.depthTracker.snapshotDirectDepth)
+                } else {
+                    depthTracker.removeIndirectUpstream(conn.depthTracker.snapshotIndirectDepth)
+                    depthTracker.updateIndirectRoots(
+                        removals = conn.depthTracker.snapshotIndirectRoots
+                    )
+                }
             }
         }
 
@@ -123,7 +130,14 @@
                 val conn: NodeConnection<V> = oldBranch.upstream
                 severed.add(conn)
                 conn.removeDownstream(downstream = oldBranch.schedulable)
-                depthTracker.removeDirectUpstream(conn.depthTracker.snapshotDirectDepth)
+                if (conn.depthTracker.snapshotIsDirect) {
+                    depthTracker.removeDirectUpstream(conn.depthTracker.snapshotDirectDepth)
+                } else {
+                    depthTracker.removeIndirectUpstream(conn.depthTracker.snapshotIndirectDepth)
+                    depthTracker.updateIndirectRoots(
+                        removals = conn.depthTracker.snapshotIndirectRoots
+                    )
+                }
             }
 
             // add new
diff --git a/packages/WallpaperBackup/Android.bp b/packages/WallpaperBackup/Android.bp
index b8e0d42..b0c0c3a 100644
--- a/packages/WallpaperBackup/Android.bp
+++ b/packages/WallpaperBackup/Android.bp
@@ -48,7 +48,9 @@
     static_libs: [
         "androidx.test.core",
         "androidx.test.rules",
+        "flag-junit",
         "mockito-target-minus-junit4",
+        "platform-test-annotations",
         "truth",
     ],
     resource_dirs: ["test/res"],
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
index 44ea9a2..a80a64d 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperBackupAgent.java
@@ -16,6 +16,7 @@
 
 package com.android.wallpaperbackup;
 
+import static android.app.Flags.liveWallpaperContentHandling;
 import static android.app.WallpaperManager.FLAG_LOCK;
 import static android.app.WallpaperManager.FLAG_SYSTEM;
 import static android.app.WallpaperManager.ORIENTATION_UNKNOWN;
@@ -27,6 +28,7 @@
 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED;
 import static com.android.window.flags.Flags.multiCrop;
 
+import android.annotation.Nullable;
 import android.app.AppGlobals;
 import android.app.WallpaperManager;
 import android.app.backup.BackupAgent;
@@ -35,6 +37,7 @@
 import android.app.backup.BackupManager;
 import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
 import android.app.backup.FullBackupDataOutput;
+import android.app.wallpaper.WallpaperDescription;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.SharedPreferences;
@@ -493,11 +496,13 @@
 
             // First parse the live component name so that we know for logging if we care about
             // logging errors with the image restore.
-            ComponentName wpService = parseWallpaperComponent(infoStage, "wp");
-            mSystemHasLiveComponent = wpService != null;
+            Pair<ComponentName, WallpaperDescription> wpService = parseWallpaperComponent(infoStage,
+                    "wp");
+            mSystemHasLiveComponent = wpService.first != null;
 
-            ComponentName kwpService = parseWallpaperComponent(infoStage, "kwp");
-            mLockHasLiveComponent = kwpService != null;
+            Pair<ComponentName, WallpaperDescription> kwpService = parseWallpaperComponent(
+                    infoStage, "kwp");
+            mLockHasLiveComponent = kwpService.first != null;
             boolean separateLockWallpaper = mLockHasLiveComponent || lockImageStage.exists();
 
             // if there's no separate lock wallpaper, apply the system wallpaper to both screens.
@@ -586,25 +591,39 @@
     }
 
     @VisibleForTesting
-    void updateWallpaperComponent(ComponentName wpService, int which)
+    void updateWallpaperComponent(Pair<ComponentName, WallpaperDescription> wpService, int which)
             throws IOException {
-        if (servicePackageExists(wpService)) {
-            Slog.i(TAG, "Using wallpaper service " + wpService);
-            mWallpaperManager.setWallpaperComponentWithFlags(wpService, which);
-            if ((which & FLAG_LOCK) != 0) {
-                mEventLogger.onLockLiveWallpaperRestored(wpService);
-            }
-            if ((which & FLAG_SYSTEM) != 0) {
-                mEventLogger.onSystemLiveWallpaperRestored(wpService);
+        WallpaperDescription description = wpService.second;
+        boolean hasDescription = (liveWallpaperContentHandling() && description != null);
+        ComponentName component = hasDescription ? description.getComponent() : wpService.first;
+        if (servicePackageExists(component)) {
+            if (hasDescription) {
+                Slog.i(TAG, "Using wallpaper description " + description);
+                mWallpaperManager.setWallpaperComponentWithDescription(description, which);
+                if ((which & FLAG_LOCK) != 0) {
+                    mEventLogger.onLockLiveWallpaperRestoredWithDescription(description);
+                }
+                if ((which & FLAG_SYSTEM) != 0) {
+                    mEventLogger.onSystemLiveWallpaperRestoredWithDescription(description);
+                }
+            } else {
+                Slog.i(TAG, "Using wallpaper service " + component);
+                mWallpaperManager.setWallpaperComponentWithFlags(component, which);
+                if ((which & FLAG_LOCK) != 0) {
+                    mEventLogger.onLockLiveWallpaperRestored(component);
+                }
+                if ((which & FLAG_SYSTEM) != 0) {
+                    mEventLogger.onSystemLiveWallpaperRestored(component);
+                }
             }
         } else {
             // If we've restored a live wallpaper, but the component doesn't exist,
             // we should log it as an error so we can easily identify the problem
             // in reports from users
-            if (wpService != null) {
+            if (component != null) {
                 // TODO(b/268471749): Handle delayed case
-                applyComponentAtInstall(wpService, which);
-                Slog.w(TAG, "Wallpaper service " + wpService + " isn't available. "
+                applyComponentAtInstall(component, description, which);
+                Slog.w(TAG, "Wallpaper service " + component + " isn't available. "
                         + " Will try to apply later");
             }
         }
@@ -697,7 +716,6 @@
      * (thereby preserving the center point). Then finally, adding any leftover image real-estate
      * (i.e. space left over on the horizontal axis) to add parallax effect. Parallax is only added
      * if was present in the old device's settings.
-     *
      */
     private Rect findNewCropfromOldCrop(Rect oldCrop, Point oldDisplaySize, boolean oldRtl,
             Point newDisplaySize, Point bitmapSize, boolean newRtl) {
@@ -976,10 +994,12 @@
         return cropHints;
     }
 
-    private ComponentName parseWallpaperComponent(File wallpaperInfo, String sectionTag) {
+    private Pair<ComponentName, WallpaperDescription> parseWallpaperComponent(File wallpaperInfo,
+            String sectionTag) {
         ComponentName name = null;
+        WallpaperDescription description = null;
         try (FileInputStream stream = new FileInputStream(wallpaperInfo)) {
-            final XmlPullParser parser = Xml.resolvePullParser(stream);
+            final TypedXmlPullParser parser = Xml.resolvePullParser(stream);
 
             int type;
             do {
@@ -991,6 +1011,7 @@
                         name = (parsedName != null)
                                 ? ComponentName.unflattenFromString(parsedName)
                                 : null;
+                        description = parseWallpaperDescription(parser, name);
                         break;
                     }
                 }
@@ -998,9 +1019,30 @@
         } catch (Exception e) {
             // Whoops; can't process the info file at all.  Report failure.
             Slog.w(TAG, "Failed to parse restored component: " + e.getMessage());
-            return null;
+            return new Pair<>(null, null);
         }
-        return name;
+        return new Pair<>(name, description);
+    }
+
+    // Copied from com.android.server.wallpaper.WallpaperDataParser
+    private WallpaperDescription parseWallpaperDescription(TypedXmlPullParser parser,
+            ComponentName component) throws XmlPullParserException, IOException {
+
+        WallpaperDescription description = null;
+        int type = parser.next();
+        if (type == XmlPullParser.START_TAG && "description".equals(parser.getName())) {
+            // Always read the description if it's there - there may be one from a previous save
+            // with content handling enabled even if it's enabled now
+            description = WallpaperDescription.restoreFromXml(parser);
+            if (liveWallpaperContentHandling()) {
+                // null component means that wallpaper was last saved without content handling, so
+                // populate description from saved component
+                if (description.getComponent() == null) {
+                    description = description.toBuilder().setComponent(component).build();
+                }
+            }
+        }
+        return description;
     }
 
     private int getAttributeInt(XmlPullParser parser, String name, int defValue) {
@@ -1037,14 +1079,16 @@
         // Intentionally blank
     }
 
-    private void applyComponentAtInstall(ComponentName componentName, int which) {
-        PackageMonitor packageMonitor = getWallpaperPackageMonitor(
-                componentName, which);
+    private void applyComponentAtInstall(ComponentName componentName,
+            @Nullable WallpaperDescription description, int which) {
+        PackageMonitor packageMonitor = getWallpaperPackageMonitor(componentName, description,
+                which);
         packageMonitor.register(getBaseContext(), null, UserHandle.ALL, true);
     }
 
     @VisibleForTesting
-    PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, int which) {
+    PackageMonitor getWallpaperPackageMonitor(ComponentName componentName,
+            @Nullable WallpaperDescription description, int which) {
         return new PackageMonitor() {
             @Override
             public void onPackageAdded(String packageName, int uid) {
@@ -1068,7 +1112,33 @@
                     return;
                 }
 
-                if (componentName.getPackageName().equals(packageName)) {
+                boolean useDescription = (liveWallpaperContentHandling() && description != null
+                        && description.getComponent() != null);
+                if (useDescription && description.getComponent().getPackageName().equals(
+                        packageName)) {
+                    Slog.d(TAG, "Applying description " + description);
+                    boolean success = mWallpaperManager.setWallpaperComponentWithDescription(
+                            description, which);
+                    WallpaperEventLogger logger = new WallpaperEventLogger(
+                            mBackupManager.getDelayedRestoreLogger());
+                    if (success) {
+                        if ((which & FLAG_SYSTEM) != 0) {
+                            logger.onSystemLiveWallpaperRestoredWithDescription(description);
+                        }
+                        if ((which & FLAG_LOCK) != 0) {
+                            logger.onLockLiveWallpaperRestoredWithDescription(description);
+                        }
+                    } else {
+                        if ((which & FLAG_SYSTEM) != 0) {
+                            logger.onSystemLiveWallpaperRestoreFailed(
+                                    WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+                        }
+                        if ((which & FLAG_LOCK) != 0) {
+                            logger.onLockLiveWallpaperRestoreFailed(
+                                    WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+                        }
+                    }
+                } else if (componentName.getPackageName().equals(packageName)) {
                     Slog.d(TAG, "Applying component " + componentName);
                     boolean success = mWallpaperManager.setWallpaperComponentWithFlags(
                             componentName, which);
@@ -1191,4 +1261,4 @@
     void setBackupManagerForTesting(BackupManager backupManager) {
         mBackupManager = backupManager;
     }
-}
\ No newline at end of file
+}
diff --git a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
index b25f95a..69469e4 100644
--- a/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
+++ b/packages/WallpaperBackup/src/com/android/wallpaperbackup/WallpaperEventLogger.java
@@ -16,12 +16,14 @@
 
 package com.android.wallpaperbackup;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.WallpaperInfo;
 import android.app.backup.BackupManager;
 import android.app.backup.BackupRestoreEventLogger;
 import android.app.backup.BackupRestoreEventLogger.BackupRestoreDataType;
 import android.app.backup.BackupRestoreEventLogger.BackupRestoreError;
+import android.app.wallpaper.WallpaperDescription;
 import android.content.ComponentName;
 
 import com.android.internal.annotations.VisibleForTesting;
@@ -53,6 +55,16 @@
     @VisibleForTesting
     static final String WALLPAPER_LIVE_LOCK = "wlp_live_lock";
 
+    /* Live component used as system (or home) screen wallpaper */
+    @BackupRestoreDataType
+    @VisibleForTesting
+    static final String WALLPAPER_DESCRIPTION_SYSTEM = "wlp_description_system";
+
+    /* Live component used as lock screen wallpaper */
+    @BackupRestoreDataType
+    @VisibleForTesting
+    static final String WALLPAPER_DESCRIPTION_LOCK = "wlp_description_lock";
+
     @BackupRestoreError
     static final String ERROR_INELIGIBLE = "ineligible";
     @BackupRestoreError
@@ -64,6 +76,8 @@
     @BackupRestoreError
     static final String ERROR_SET_COMPONENT_EXCEPTION = "exception_in_set_component";
     @BackupRestoreError
+    static final String ERROR_SET_DESCRIPTION_EXCEPTION = "exception_in_set_description";
+    @BackupRestoreError
     static final String ERROR_LIVE_PACKAGE_NOT_INSTALLED = "live_pkg_not_installed_in_restore";
 
     private final BackupRestoreEventLogger mLogger;
@@ -115,11 +129,11 @@
     }
 
     void onSystemImageWallpaperRestored() {
-        logRestoreSuccessInternal(WALLPAPER_IMG_SYSTEM, /* liveComponentWallpaperInfo */ null);
+        logRestoreSuccessInternal(WALLPAPER_IMG_SYSTEM, (ComponentName) null);
     }
 
     void onLockImageWallpaperRestored() {
-        logRestoreSuccessInternal(WALLPAPER_IMG_LOCK, /* liveComponentWallpaperInfo */ null);
+        logRestoreSuccessInternal(WALLPAPER_IMG_LOCK, (ComponentName) null);
     }
 
     void onSystemLiveWallpaperRestored(ComponentName wpService) {
@@ -146,6 +160,13 @@
         logRestoreFailureInternal(WALLPAPER_LIVE_LOCK, error);
     }
 
+    void onSystemLiveWallpaperRestoredWithDescription(@NonNull WallpaperDescription description) {
+        logRestoreSuccessInternal(WALLPAPER_DESCRIPTION_SYSTEM, description);
+    }
+
+    void onLockLiveWallpaperRestoredWithDescription(@NonNull WallpaperDescription description) {
+        logRestoreSuccessInternal(WALLPAPER_DESCRIPTION_LOCK, description);
+    }
 
 
     /**
@@ -168,15 +189,17 @@
      */
     void onRestoreException(Exception exception) {
         String error = exception.getClass().getName();
-        if (!mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) && !mProcessedDataTypes.contains(
-                WALLPAPER_LIVE_SYSTEM)) {
+        if (!(mProcessedDataTypes.contains(WALLPAPER_IMG_SYSTEM) || mProcessedDataTypes.contains(
+                WALLPAPER_LIVE_SYSTEM) || mProcessedDataTypes.contains(
+                WALLPAPER_DESCRIPTION_SYSTEM))) {
             mLogger.logItemsRestoreFailed(WALLPAPER_IMG_SYSTEM, /* count */ 1, error);
         }
-        if (!mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) && !mProcessedDataTypes.contains(
-                WALLPAPER_LIVE_LOCK)) {
+        if (!(mProcessedDataTypes.contains(WALLPAPER_IMG_LOCK) || mProcessedDataTypes.contains(
+                WALLPAPER_LIVE_LOCK) || mProcessedDataTypes.contains(WALLPAPER_DESCRIPTION_LOCK))) {
             mLogger.logItemsRestoreFailed(WALLPAPER_IMG_LOCK, /* count */ 1, error);
         }
     }
+
     private void logBackupSuccessInternal(@BackupRestoreDataType String which,
             @Nullable WallpaperInfo liveComponentWallpaperInfo) {
         mLogger.logItemsBackedUp(which, /* count */ 1);
@@ -197,6 +220,13 @@
         mProcessedDataTypes.add(which);
     }
 
+    private void logRestoreSuccessInternal(@BackupRestoreDataType String which,
+            @NonNull WallpaperDescription description) {
+        mLogger.logItemsRestored(which, /* count */ 1);
+        logRestoredLiveWallpaperDescription(which, description);
+        mProcessedDataTypes.add(which);
+    }
+
     private void logRestoreFailureInternal(@BackupRestoreDataType String which,
             @BackupRestoreError String error) {
         mLogger.logItemsRestoreFailed(which, /* count */ 1, error);
@@ -216,4 +246,11 @@
             mLogger.logRestoreMetadata(wallpaperType, wpService.getClassName());
         }
     }
+
+    private void logRestoredLiveWallpaperDescription(@BackupRestoreDataType String wallpaperType,
+            WallpaperDescription description) {
+        if (description != null) {
+            mLogger.logRestoreMetadata(wallpaperType, description.toString());
+        }
+    }
 }
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
index f5fb644..c9f1b58 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperBackupAgentTest.java
@@ -16,6 +16,7 @@
 
 package com.android.wallpaperbackup;
 
+import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
 import static android.app.WallpaperManager.FLAG_LOCK;
 import static android.app.WallpaperManager.FLAG_SYSTEM;
 import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
@@ -27,6 +28,8 @@
 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_METADATA;
 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_NO_WALLPAPER;
 import static com.android.wallpaperbackup.WallpaperEventLogger.ERROR_QUOTA_EXCEEDED;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_SYSTEM;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK;
@@ -54,6 +57,7 @@
 import android.app.backup.BackupRestoreEventLogger;
 import android.app.backup.BackupRestoreEventLogger.DataTypeResult;
 import android.app.backup.FullBackupDataOutput;
+import android.app.wallpaper.WallpaperDescription;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
@@ -63,7 +67,10 @@
 import android.os.FileUtils;
 import android.os.ParcelFileDescriptor;
 import android.os.UserHandle;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.wallpaper.WallpaperService;
+import android.util.Pair;
 import android.util.SparseArray;
 import android.util.Xml;
 
@@ -79,6 +86,7 @@
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
+import org.junit.rules.RuleChain;
 import org.junit.rules.TemporaryFolder;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatcher;
@@ -113,12 +121,15 @@
     @Mock
     private BackupManager mBackupManager;
 
-    @Rule
-    public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
-
     private ContextWithServiceOverrides mContext;
     private IsolatedWallpaperBackupAgent mWallpaperBackupAgent;
     private ComponentName mWallpaperComponent;
+    private WallpaperDescription mWallpaperDescription;
+
+    private final TemporaryFolder mTemporaryFolder = new TemporaryFolder();
+
+    @Rule
+    public RuleChain mRuleChain = RuleChain.outerRule(new SetFlagsRule()).around(mTemporaryFolder);
 
     @Before
     public void setUp() {
@@ -135,6 +146,8 @@
                 BackupAnnotations.OperationType.BACKUP);
 
         mWallpaperComponent = new ComponentName(TEST_WALLPAPER_PACKAGE, "");
+        mWallpaperDescription = new WallpaperDescription.Builder().setComponent(
+                mWallpaperComponent).setId("id").build();
     }
 
     @After
@@ -366,11 +379,128 @@
     }
 
     @Test
-    public void testUpdateWallpaperComponent_systemAndLock() throws IOException {
-        mWallpaperBackupAgent.mIsDeviceInRestore = true;
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+    public void testUpdateWallpaperComponent_immediate_systemAndLock() throws IOException {
+        mWallpaperBackupAgent.mPackageExists = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
 
+        assertThat(mWallpaperBackupAgent.mGetPackageMonitorCallCount).isEqualTo(0);
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    public void testUpdateWallpaperComponent_immediate_systemOnly()
+            throws IOException {
+        mWallpaperBackupAgent.mPackageExists = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
+                /* which */ FLAG_SYSTEM);
+
+        assertThat(mWallpaperBackupAgent.mGetPackageMonitorCallCount).isEqualTo(0);
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithFlags(mWallpaperComponent, FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_immediate_systemAndLock()
+            throws IOException {
+        mWallpaperBackupAgent.mPackageExists = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(
+                new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */
+                FLAG_LOCK | FLAG_SYSTEM);
+
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithDescription(mWallpaperDescription,
+                        FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_immediate_systemOnly() throws IOException {
+        mWallpaperBackupAgent.mPackageExists = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(
+                new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ FLAG_SYSTEM);
+
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription,
+                        FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_delayed_systemAndLock()
+            throws IOException {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+        mWallpaperBackupAgent.updateWallpaperComponent(
+                new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */
+                FLAG_LOCK | FLAG_SYSTEM);
+
+        // Imitate wallpaper component installation.
+        mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+                /* uid */0);
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithDescription(mWallpaperDescription,
+                        FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_delayed_systemOnly() throws IOException {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(
+                new Pair<>(mWallpaperComponent, mWallpaperDescription), /* which */ FLAG_SYSTEM);
+
+        // Imitate wallpaper component installation.
+        mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+                /* uid */0);
+
+        verify(mWallpaperManager, times(1))
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_SYSTEM);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription, FLAG_LOCK);
+        verify(mWallpaperManager, never())
+                .setWallpaperComponentWithDescription(mWallpaperDescription,
+                        FLAG_LOCK | FLAG_SYSTEM);
+        verify(mWallpaperManager, never()).clear(anyInt());
+    }
+
+    @Test
+    public void testUpdateWallpaperComponent_delayed_systemAndLock() throws IOException {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
+                /* which */ FLAG_LOCK | FLAG_SYSTEM);
         // Imitate wallpaper component installation.
         mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
                 /* uid */0);
@@ -384,13 +514,12 @@
     }
 
     @Test
-    public void testUpdateWallpaperComponent_systemOnly()
+    public void testUpdateWallpaperComponent_delayed_systemOnly()
             throws IOException {
         mWallpaperBackupAgent.mIsDeviceInRestore = true;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_SYSTEM);
-
         // Imitate wallpaper component installation.
         mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
                 /* uid */0);
@@ -405,11 +534,11 @@
     }
 
     @Test
-    public void testUpdateWallpaperComponent_deviceNotInRestore_doesNotApply()
+    public void testUpdateWallpaperComponent_delayed_deviceNotInRestore_doesNotApply()
             throws IOException {
         mWallpaperBackupAgent.mIsDeviceInRestore = false;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
 
         // Imitate wallpaper component installation.
@@ -421,11 +550,11 @@
     }
 
     @Test
-    public void testUpdateWallpaperComponent_differentPackageInstalled_doesNotApply()
+    public void testUpdateWallpaperComponent_delayed_differentPackageInstalled_doesNotApply()
             throws IOException {
         mWallpaperBackupAgent.mIsDeviceInRestore = false;
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
 
         // Imitate "wrong" wallpaper component installation.
@@ -745,9 +874,8 @@
     }
 
     @Test
-    public void testUpdateWallpaperComponent_delayedRestore_logsSuccess() throws Exception {
+    public void testUpdateWallpaperComponent_delayed_succeeds_logsSuccess() throws Exception {
         mWallpaperBackupAgent.mIsDeviceInRestore = true;
-        when(mWallpaperManager.setWallpaperComponent(any())).thenReturn(true);
         when(mWallpaperManager.setWallpaperComponentWithFlags(any(), eq(FLAG_LOCK | FLAG_SYSTEM)))
                 .thenReturn(true);
         BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
@@ -755,7 +883,7 @@
         when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
         mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
         // Imitate wallpaper component installation.
         mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -771,15 +899,41 @@
 
 
     @Test
-    public void testUpdateWallpaperComponent_delayedRestoreFails_logsFailure() throws Exception {
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_delayed_succeeds_logsSuccess() throws Exception {
         mWallpaperBackupAgent.mIsDeviceInRestore = true;
-        when(mWallpaperManager.setWallpaperComponent(any())).thenReturn(false);
+        when(mWallpaperManager.setWallpaperComponentWithDescription(any(),
+                eq(FLAG_LOCK | FLAG_SYSTEM))).thenReturn(true);
         BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
                 BackupAnnotations.OperationType.RESTORE);
         when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
         mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(null, mWallpaperDescription),
+                /* which */ FLAG_LOCK | FLAG_SYSTEM);
+        // Imitate wallpaper component installation.
+        mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+                /* uid */0);
+
+        DataTypeResult system = getLoggingResult(WALLPAPER_DESCRIPTION_SYSTEM,
+                logger.getLoggingResults());
+        DataTypeResult lock = getLoggingResult(WALLPAPER_DESCRIPTION_LOCK,
+                logger.getLoggingResults());
+        assertThat(system).isNotNull();
+        assertThat(system.getSuccessCount()).isEqualTo(1);
+        assertThat(lock).isNotNull();
+        assertThat(lock.getSuccessCount()).isEqualTo(1);
+    }
+
+    @Test
+    public void testUpdateWallpaperComponent_delayed_fails_logsFailure() throws Exception {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+        BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
+                BackupAnnotations.OperationType.RESTORE);
+        when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
+        mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
+
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
         // Imitate wallpaper component installation.
         mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
@@ -793,7 +947,29 @@
     }
 
     @Test
-    public void testUpdateWallpaperComponent_delayedRestore_packageNotInstalled_logsFailure()
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void testUpdateWallpaperDescription_delayed_fails_logsFailure() throws Exception {
+        mWallpaperBackupAgent.mIsDeviceInRestore = true;
+        BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
+                BackupAnnotations.OperationType.RESTORE);
+        when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
+        mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
+
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(null, mWallpaperDescription),
+                /* which */ FLAG_LOCK | FLAG_SYSTEM);
+        // Imitate wallpaper component installation.
+        mWallpaperBackupAgent.mWallpaperPackageMonitor.onPackageAdded(TEST_WALLPAPER_PACKAGE,
+                /* uid */0);
+
+        DataTypeResult system = getLoggingResult(WALLPAPER_LIVE_SYSTEM, logger.getLoggingResults());
+        assertThat(system).isNotNull();
+        assertThat(system.getFailCount()).isEqualTo(1);
+        assertThat(system.getErrors()).containsKey(
+                WallpaperEventLogger.ERROR_SET_DESCRIPTION_EXCEPTION);
+    }
+
+    @Test
+    public void testUpdateWallpaperComponent_delayed_packageNotInstalled_logsFailure()
             throws Exception {
         mWallpaperBackupAgent.mIsDeviceInRestore = false;
         BackupRestoreEventLogger logger = new BackupRestoreEventLogger(
@@ -801,7 +977,7 @@
         when(mBackupManager.getDelayedRestoreLogger()).thenReturn(logger);
         mWallpaperBackupAgent.setBackupManagerForTesting(mBackupManager);
 
-        mWallpaperBackupAgent.updateWallpaperComponent(mWallpaperComponent,
+        mWallpaperBackupAgent.updateWallpaperComponent(new Pair<>(mWallpaperComponent, null),
                 /* which */ FLAG_LOCK | FLAG_SYSTEM);
 
         // Imitate wallpaper component installation.
@@ -990,6 +1166,8 @@
         List<File> mBackedUpFiles = new ArrayList<>();
         PackageMonitor mWallpaperPackageMonitor;
         boolean mIsDeviceInRestore = false;
+        boolean mPackageExists = false;
+        int mGetPackageMonitorCallCount = 0;
 
         @Override
         protected void backupFile(File file, FullBackupDataOutput data) {
@@ -998,7 +1176,7 @@
 
         @Override
         boolean servicePackageExists(ComponentName comp) {
-            return false;
+            return mPackageExists;
         }
 
         @Override
@@ -1007,8 +1185,11 @@
         }
 
         @Override
-        PackageMonitor getWallpaperPackageMonitor(ComponentName componentName, int which) {
-            mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, which);
+        PackageMonitor getWallpaperPackageMonitor(ComponentName componentName,
+                WallpaperDescription description, int which) {
+            mGetPackageMonitorCallCount++;
+            mWallpaperPackageMonitor = super.getWallpaperPackageMonitor(componentName, description,
+                    which);
             return mWallpaperPackageMonitor;
         }
 
diff --git a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
index 383bf2f..09aa23e 100644
--- a/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
+++ b/packages/WallpaperBackup/test/src/com/android/wallpaperbackup/WallpaperEventLoggerTest.java
@@ -16,6 +16,10 @@
 
 package com.android.wallpaperbackup;
 
+import static android.app.Flags.FLAG_LIVE_WALLPAPER_CONTENT_HANDLING;
+
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_LOCK;
+import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_DESCRIPTION_SYSTEM;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_LOCK;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_IMG_SYSTEM;
 import static com.android.wallpaperbackup.WallpaperEventLogger.WALLPAPER_LIVE_LOCK;
@@ -31,16 +35,20 @@
 import android.app.backup.BackupAnnotations;
 import android.app.backup.BackupManager;
 import android.app.backup.BackupRestoreEventLogger;
+import android.app.wallpaper.WallpaperDescription;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.wallpaper.WallpaperService;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -63,6 +71,10 @@
 
     private WallpaperEventLogger mWallpaperEventLogger;
     private WallpaperInfo mWallpaperInfo;
+    private WallpaperDescription mWallpaperDescription;
+
+    @Rule
+    public SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     @Before
     public void setUp() throws Exception {
@@ -73,6 +85,8 @@
 
         mWallpaperInfo = getWallpaperInfo();
         mWallpaperEventLogger = new WallpaperEventLogger(mMockBackupManager, mMockBackupAgent);
+        mWallpaperDescription = new WallpaperDescription.Builder().setComponent(
+                mWallpaperInfo.getComponent()).build();
     }
 
     @Test
@@ -263,6 +277,19 @@
     }
 
     @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void onSystemLiveWallpaperRestoredWithDescription_logsSuccess() {
+        setUpLoggerForRestore();
+
+        mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(
+                WALLPAPER_DESCRIPTION_SYSTEM);
+
+        assertThat(result).isNotNull();
+        assertThat(result.getSuccessCount()).isEqualTo(1);
+    }
+
+    @Test
     public void onLockLiveWallpaperRestored_logsSuccess() {
         setUpLoggerForRestore();
 
@@ -274,6 +301,17 @@
     }
 
     @Test
+    public void onLockLiveWallpaperRestoredWithDescription_logsSuccess() {
+        setUpLoggerForRestore();
+
+        mWallpaperEventLogger.onLockLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_DESCRIPTION_LOCK);
+
+        assertThat(result).isNotNull();
+        assertThat(result.getSuccessCount()).isEqualTo(1);
+    }
+
+    @Test
     public void onImgWallpaperRestored_nullInfo_doesNotLogMetadata() {
         setUpLoggerForRestore();
 
@@ -286,7 +324,7 @@
 
 
     @Test
-    public void onLiveWallpaperRestored_logsMetadata() {
+    public void onSystemLiveWallpaperRestored_logsMetadata() {
         setUpLoggerForRestore();
 
         mWallpaperEventLogger.onSystemLiveWallpaperRestored(mWallpaperInfo.getComponent());
@@ -296,6 +334,19 @@
         assertThat(result.getMetadataHash()).isNotNull();
     }
 
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void onSystemLiveWallpaperRestoredDescription_logsMetadata() {
+        setUpLoggerForRestore();
+
+        mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(
+                WALLPAPER_DESCRIPTION_SYSTEM);
+
+        assertThat(result).isNotNull();
+        assertThat(result.getMetadataHash()).isNotNull();
+    }
+
 
     @Test
     public void onSystemImgWallpaperRestoreFailed_logsFail() {
@@ -373,7 +424,7 @@
     }
 
     @Test
-    public void onWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
+    public void onSystemWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
         setUpLoggerForRestore();
         mWallpaperEventLogger.onSystemLiveWallpaperRestored(mWallpaperInfo.getComponent());
 
@@ -383,6 +434,41 @@
         assertThat(result).isNull();
     }
 
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void onSystemWallpaperRestoreException_descriptionProcessed_doesNotLogForSameImgType() {
+        setUpLoggerForRestore();
+        mWallpaperEventLogger.onSystemLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+
+        mWallpaperEventLogger.onRestoreException(new Exception());
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_SYSTEM);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    public void onLockWallpaperRestoreException_liveTypeProcessed_doesNotLogForSameImgType() {
+        setUpLoggerForRestore();
+        mWallpaperEventLogger.onLockLiveWallpaperRestored(mWallpaperInfo.getComponent());
+
+        mWallpaperEventLogger.onRestoreException(new Exception());
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_LOCK);
+
+        assertThat(result).isNull();
+    }
+
+    @Test
+    @EnableFlags(FLAG_LIVE_WALLPAPER_CONTENT_HANDLING)
+    public void onLockWallpaperRestoreException_descriptionProcessed_doesNotLogForSameImgType() {
+        setUpLoggerForRestore();
+        mWallpaperEventLogger.onLockLiveWallpaperRestoredWithDescription(mWallpaperDescription);
+
+        mWallpaperEventLogger.onRestoreException(new Exception());
+        BackupRestoreEventLogger.DataTypeResult result = getLogsForType(WALLPAPER_IMG_LOCK);
+
+        assertThat(result).isNull();
+    }
+
     private BackupRestoreEventLogger.DataTypeResult getLogsForType(String dataType) {
         for (BackupRestoreEventLogger.DataTypeResult result :  mEventLogger.getLoggingResults()) {
             if ((result.getDataType()).equals(dataType)) {
diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING
index 1148539..083d2aa 100644
--- a/ravenwood/TEST_MAPPING
+++ b/ravenwood/TEST_MAPPING
@@ -180,9 +180,11 @@
     // AUTO-GENERATED-END
   ],
   "ravenwood-postsubmit": [
-    {
-      "name": "SystemUiRavenTests",
-      "host": true
-    }
+    // We haven't maintained SystemUiRavenTests, and as a result, it's been demoted already.
+    // Disable it until we fix the issues: b/319647875
+    // {
+    //   "name": "SystemUiRavenTests",
+    //   "host": true
+    // }
   ]
 }
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java
index 3cb2c67..aa37d12 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodEnablementChecker.java
@@ -19,7 +19,6 @@
 import android.annotation.Nullable;
 import android.platform.test.annotations.DisabledOnRavenwood;
 import android.platform.test.annotations.EnabledOnRavenwood;
-import android.platform.test.annotations.IgnoreUnderRavenwood;
 
 import org.junit.runner.Description;
 
@@ -51,8 +50,6 @@
                 result = true;
             } else if (description.getAnnotation(DisabledOnRavenwood.class) != null) {
                 result = false;
-            } else if (description.getAnnotation(IgnoreUnderRavenwood.class) != null) {
-                result = false;
             }
             if (result != null) {
                 if (takeIntoAccountRunDisabledTestsFlag
@@ -78,8 +75,6 @@
             result = true;
         } else if (testClass.getAnnotation(DisabledOnRavenwood.class) != null) {
             result = false;
-        } else if (testClass.getAnnotation(IgnoreUnderRavenwood.class) != null) {
-            result = false;
         }
         if (!result) {
             if (takeIntoAccountRunDisabledTestsFlag
diff --git a/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java b/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java
deleted file mode 100644
index 1c06829..0000000
--- a/ravenwood/junit-src/android/platform/test/annotations/IgnoreUnderRavenwood.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package android.platform.test.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Test methods marked with this annotation are quietly ignored when running under a Ravenwood test
- * environment. The test continues to execute normally under all other non-Ravenwood test
- * environments.
- *
- * This annotation only takes effect when the containing class has a {@code
- * RavenwoodRule} configured. Ignoring is accomplished by throwing an {@code org.junit
- * .AssumptionViolatedException} which test infrastructure treats as being ignored.
- *
- * Developers are encouraged to use either the {@code blockedBy} and/or {@code reason} arguments
- * to document why a test is being ignored, to aid in future audits of tests that are candidates
- * to be enabled.
- *
- * @hide
- *
- * @deprecated Use {@link DisabledOnRavenwood} instead.
- */
-@Target({ElementType.METHOD, ElementType.TYPE})
-@Retention(RetentionPolicy.RUNTIME)
-@Deprecated
-public @interface IgnoreUnderRavenwood {
-    /**
-     * One or more classes that aren't yet supported by Ravenwood, which this test depends on.
-     */
-    Class<?>[] blockedBy() default {};
-
-    /**
-     * General free-form description of why this test is being ignored.
-     */
-    String reason() default "";
-
-    /**
-     * Tracking bug number, if any.
-     */
-    long bug() default 0;
-}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java
deleted file mode 100644
index 85297fe..0000000
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodClassRule.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2024 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.platform.test.ravenwood;
-
-import org.junit.rules.TestRule;
-import org.junit.runner.Description;
-import org.junit.runners.model.Statement;
-
-/**
- * No longer needed.
- *
- * @deprecated this class used to be used to handle the class level annotation, which
- * is now done by the test runner, so this class is not needed.
- */
-@Deprecated
-public class RavenwoodClassRule implements TestRule {
-    @Override
-    public Statement apply(Statement base, Description description) {
-        return base;
-    }
-}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index ffe5f6c..b0b4c68 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -100,38 +100,6 @@
         }
 
         /**
-         * @deprecated no longer used. We always use an app UID.
-         */
-        @Deprecated
-        public Builder setProcessSystem() {
-            return this;
-        }
-
-        /**
-         * @deprecated no longer used. We always use an app UID.
-         */
-        @Deprecated
-        public Builder setProcessApp() {
-            return this;
-        }
-
-        /**
-         * @deprecated no longer used.
-         */
-        @Deprecated
-        public Builder setPackageName(@NonNull String packageName) {
-            return this;
-        }
-
-        /**
-         * @deprecated no longer used. Main thread is always available.
-         */
-        @Deprecated
-        public Builder setProvideMainThread(boolean provideMainThread) {
-            return this;
-        }
-
-        /**
          * Configure the given system property as immutable for the duration of the test.
          * Read access to the key is allowed, and write access will fail. When {@code value} is
          * {@code null}, the value is left as undefined.
@@ -163,28 +131,12 @@
             return this;
         }
 
-        /**
-         * @deprecated no longer used. All supported services are available.
-         */
-        @Deprecated
-        public Builder setServicesRequired(@NonNull Class<?>... services) {
-            return this;
-        }
-
         public RavenwoodRule build() {
             return mRule;
         }
     }
 
     /**
-     * @deprecated replaced by {@link #isOnRavenwood()}
-     */
-    @Deprecated
-    public static boolean isUnderRavenwood() {
-        return IS_ON_RAVENWOOD;
-    }
-
-    /**
      * Return if the current process is running on a Ravenwood test environment.
      */
     public static boolean isOnRavenwood() {
@@ -197,26 +149,6 @@
         }
     }
 
-    /**
-     * @deprecated Use
-     * {@code androidx.test.platform.app.InstrumentationRegistry.getInstrumentation().getContext()}
-     * instead.
-     */
-    @Deprecated
-    public Context getContext() {
-        return InstrumentationRegistry.getInstrumentation().getContext();
-    }
-
-    /**
-     * @deprecated Use
-     * {@code androidx.test.platform.app.InstrumentationRegistry.getInstrumentation()}
-     * instead.
-     */
-    @Deprecated
-    public Instrumentation getInstrumentation() {
-        return InstrumentationRegistry.getInstrumentation();
-    }
-
     @Override
     public Statement apply(Statement base, Description description) {
         if (!IS_ON_RAVENWOOD) {
diff --git a/ravenwood/scripts/ravenwood-stats-collector.sh b/ravenwood/scripts/ravenwood-stats-collector.sh
index b83216a..c2bf8d8 100755
--- a/ravenwood/scripts/ravenwood-stats-collector.sh
+++ b/ravenwood/scripts/ravenwood-stats-collector.sh
@@ -29,21 +29,46 @@
 mkdir -p $keep_all_dir
 mkdir -p $dump_dir
 
-# Where the input files are.
-path=$ANDROID_BUILD_TOP/out/host/linux-x86/testcases/ravenwood-stats-checker/x86_64/
+
+stats_checker_module="ravenwood-stats-checker"
+minfo=$OUT/module-info.json
 
 timestamp="$(date --iso-8601=seconds)"
 
-m() {
-    ${ANDROID_BUILD_TOP}/build/soong/soong_ui.bash --make-mode "$@"
-}
+# First, use jq to get the output files from the checker module. This will be something like this:
+#
+# ---
+# out/host/linux-x86/nativetest64/ravenwood-stats-checker/framework-configinfrastructure_apis.csv
+# out/host/linux-x86/nativetest64/ravenwood-stats-checker/framework-configinfrastructure_dump.txt
+#  :
+# out/host/linux-x86/nativetest64/ravenwood-stats-checker/hoststubgen_services.core_stats.csv
+# out/host/linux-x86/nativetest64/ravenwood-stats-checker/ravenwood-stats-checker
+# ---
+# Then, use grep to find the script's path (the last line in the above examle)
+script_path="$(
+    jq -r ".\"$stats_checker_module\".installed | .[]" $minfo |
+    grep '/ravenwood-stats-checker$'
+)"
 
-# Building this will generate the files we need.
-m ravenwood-stats-checker
+if [[ "$script_path" == "" ]] ; then
+    echo "Error: $stats_checker_module script not found from $minfo"
+    exit 1
+fi
+
+# This is the directory where our input files are.
+script_dir="$ANDROID_BUILD_TOP/$(dirname "$script_path")"
+
+# Clear it before (re-)buildign the script, to make sure we won't have stale files.
+rm -fr "$script_dir"
+
+# Then build it, which will also collect the input files in the same dir.
+echo "Collecting the input files..."
+m "$stats_checker_module"
 
 # Start...
 
-cd $path
+echo "Files directory is: $script_dir"
+cd "$script_dir"
 
 dump() {
     local jar=$1
@@ -55,6 +80,7 @@
 
 collect_stats() {
     local out="$1"
+    local desc="$2"
     {
         # Copy the header, with the first column appended.
         echo -n "Jar,Generated Date,"
@@ -66,11 +92,12 @@
         dump "framework-statsd"  framework-statsd_stats.csv
     } > "$out"
 
-    echo "Stats CVS created at $out"
+    echo "Stats CVS created at $out$desc"
 }
 
 collect_apis() {
     local out="$1"
+    local desc="$2"
     {
         # Copy the header, with the first column appended.
         echo -n "Jar,Generated Date,"
@@ -82,12 +109,12 @@
         dump "framework-statsd"  framework-statsd_apis.csv
     } > "$out"
 
-    echo "API CVS created at $out"
+    echo "API CVS created at $out$desc"
 }
 
 
-collect_stats $stats
-collect_apis $apis
+collect_stats $stats " (import it as 'ravenwood_stats')"
+collect_apis $apis " (import it as 'ravenwood_supported_apis')"
 
 cp *keep_all.txt $keep_all_dir
 echo "Keep all files created at:"
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodClassRuleDeviceOnlyTest.java b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodClassRuleDeviceOnlyTest.java
index e8f59db..da27778 100644
--- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodClassRuleDeviceOnlyTest.java
+++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodClassRuleDeviceOnlyTest.java
@@ -16,13 +16,11 @@
 package com.android.ravenwoodtest.bivalenttest;
 
 import android.platform.test.annotations.DisabledOnRavenwood;
-import android.platform.test.ravenwood.RavenwoodClassRule;
 import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
 import org.junit.Assert;
-import org.junit.ClassRule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -33,9 +31,6 @@
 @RunWith(AndroidJUnit4.class)
 @DisabledOnRavenwood
 public class RavenwoodClassRuleDeviceOnlyTest {
-    @ClassRule
-    public static final RavenwoodClassRule sRavenwood = new RavenwoodClassRule();
-
     @Test
     public void testDeviceOnly() {
         Assert.assertFalse(RavenwoodRule.isOnRavenwood());
diff --git a/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java b/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java
index b1a40f0..0928625 100644
--- a/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java
+++ b/ravenwood/tests/minimum-test/test/com/android/ravenwoodtest/RavenwoodMinimumTest.java
@@ -15,7 +15,7 @@
  */
 package com.android.ravenwoodtest;
 
-import android.platform.test.annotations.IgnoreUnderRavenwood;
+import android.platform.test.annotations.DisabledOnRavenwood;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
 
@@ -37,7 +37,7 @@
     }
 
     @Test
-    @IgnoreUnderRavenwood
+    @DisabledOnRavenwood
     public void testIgnored() {
         throw new RuntimeException("Shouldn't be executed under ravenwood");
     }
diff --git a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesDependenciesTest.java b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesDependenciesTest.java
index f833782..2ff5dab 100644
--- a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesDependenciesTest.java
+++ b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesDependenciesTest.java
@@ -18,37 +18,28 @@
 
 import static org.junit.Assert.assertEquals;
 
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.ravenwood.example.BlueManager;
 import android.ravenwood.example.RedManager;
 
 import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 @RunWith(AndroidJUnit4.class)
 public class RavenwoodServicesDependenciesTest {
-    // NOTE: we carefully only ask for RedManager here, and rely on Ravenwood internals to spin
-    // up the implicit dependency on BlueManager
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProcessSystem()
-            .setServicesRequired(RedManager.class)
-            .build();
-
     @Test
     public void testDirect() {
-        final RedManager red = mRavenwood.getContext().getSystemService(
-                RedManager.class);
+        final RedManager red = InstrumentationRegistry.getInstrumentation().getContext()
+                .getSystemService(RedManager.class);
         assertEquals("blue+red", red.getInterfaceDescriptor());
     }
 
     @Test
     public void testIndirect() {
-        final BlueManager blue = mRavenwood.getContext().getSystemService(
-                BlueManager.class);
+        final BlueManager blue = InstrumentationRegistry.getInstrumentation().getContext()
+                .getSystemService(BlueManager.class);
         assertEquals("blue", blue.getInterfaceDescriptor());
     }
 }
diff --git a/ravenwood/tools/hoststubgen/Android.bp b/ravenwood/tools/hoststubgen/Android.bp
index 004834e..e605318 100644
--- a/ravenwood/tools/hoststubgen/Android.bp
+++ b/ravenwood/tools/hoststubgen/Android.bp
@@ -99,6 +99,7 @@
         "ow2-asm-commons",
         "ow2-asm-tree",
         "ow2-asm-util",
+        "apache-commons-compress",
     ],
 }
 
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt
index 9045db2..ea8c25b 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/HostStubGenStats.kt
@@ -15,13 +15,24 @@
  */
 package com.android.hoststubgen
 
+import com.android.hoststubgen.asm.ClassNodes
 import com.android.hoststubgen.asm.getOuterClassNameFromFullClassName
 import com.android.hoststubgen.asm.getPackageNameFromFullClassName
 import com.android.hoststubgen.filters.FilterPolicyWithReason
+import com.android.hoststubgen.filters.StatsLabel
 import org.objectweb.asm.Opcodes
 import java.io.PrintWriter
 
-open class HostStubGenStats {
+/**
+ * TODO This is for the legacy API coverage stats CSV that shows how many APIs are "supported"
+ * in each class with some heuristics. We created [ApiDumper] later, which dumpps all methods
+ * with the "supported" status. We should update the coverage dashboard to use the [ApiDumper]
+ * output and remove this class, once we port all the heuristics to [ApiDumper] as well.
+ * (For example, this class ignores non-public and/or abstract methods, but [ApiDumper] shows
+ * all of them in the same way. We should probably mark them as "Boring" or maybe "Ignore"
+ * for [ApiDumper])
+ */
+open class HostStubGenStats(val classes: ClassNodes) {
     data class Stats(
             var supported: Int = 0,
             var total: Int = 0,
@@ -30,14 +41,6 @@
 
     private val stats = mutableMapOf<String, Stats>()
 
-    data class Api(
-        val fullClassName: String,
-        val methodName: String,
-        val methodDesc: String,
-    )
-
-    private val apis = mutableListOf<Api>()
-
     fun onVisitPolicyForMethod(
         fullClassName: String,
         methodName: String,
@@ -45,16 +48,16 @@
         policy: FilterPolicyWithReason,
         access: Int
     ) {
-        if (policy.policy.isSupported) {
-            apis.add(Api(fullClassName, methodName, descriptor))
-        }
-
         // Ignore methods that aren't public
         if ((access and Opcodes.ACC_PUBLIC) == 0) return
         // Ignore methods that are abstract
         if ((access and Opcodes.ACC_ABSTRACT) != 0) return
+
         // Ignore methods where policy isn't relevant
-        if (policy.isIgnoredForStats) return
+        val statsLabel = policy.statsLabel
+        if (statsLabel == StatsLabel.Ignored) return
+
+        val cn = classes.findClass(fullClassName) ?: return
 
         val packageName = getPackageNameFromFullClassName(fullClassName)
         val className = getOuterClassNameFromFullClassName(fullClassName)
@@ -70,7 +73,7 @@
         val packageStats = stats.getOrPut(packageName) { Stats() }
         val classStats = packageStats.children.getOrPut(className) { Stats() }
 
-        if (policy.policy.isSupported) {
+        if (statsLabel == StatsLabel.Supported) {
             packageStats.supported += 1
             classStats.supported += 1
         }
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt
index b2af782..a62f66d 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/Utils.kt
@@ -16,6 +16,15 @@
 package com.android.hoststubgen
 
 import java.io.PrintWriter
+import java.util.zip.CRC32
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
+import org.apache.commons.compress.archivers.zip.ZipFile
+
+/**
+ * Whether to skip compression when adding processed entries back to a zip file.
+ */
+private const val SKIP_COMPRESSION = false
 
 /**
  * Name of this executable. Set it in the main method.
@@ -118,3 +127,29 @@
 
     System.exit(if (success) 0 else 1 )
 }
+
+/**
+ * Copy a single ZIP entry to the output.
+ */
+fun copyZipEntry(
+    inZip: ZipFile,
+    entry: ZipArchiveEntry,
+    out: ZipArchiveOutputStream,
+) {
+    inZip.getRawInputStream(entry).use { out.addRawArchiveEntry(entry, it) }
+}
+
+/**
+ * Add a single ZIP entry with data.
+ */
+fun ZipArchiveOutputStream.addBytesEntry(name: String, data: ByteArray) {
+    val newEntry = ZipArchiveEntry(name)
+    if (SKIP_COMPRESSION) {
+        newEntry.method = 0
+        newEntry.size = data.size.toLong()
+        newEntry.crc = CRC32().apply { update(data) }.value
+    }
+    putArchiveEntry(newEntry)
+    write(data)
+    closeArchiveEntry()
+}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt
index e2647eb..40d343a 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/asm/ClassNodes.kt
@@ -18,21 +18,20 @@
 import com.android.hoststubgen.ClassParseException
 import com.android.hoststubgen.InvalidJarFileException
 import com.android.hoststubgen.log
-import org.objectweb.asm.ClassReader
-import org.objectweb.asm.tree.AnnotationNode
-import org.objectweb.asm.tree.ClassNode
-import org.objectweb.asm.tree.FieldNode
-import org.objectweb.asm.tree.MethodNode
-import org.objectweb.asm.tree.TypeAnnotationNode
-import java.io.BufferedInputStream
 import java.io.PrintWriter
 import java.util.Arrays
 import java.util.concurrent.Executors
 import java.util.concurrent.TimeUnit
 import java.util.concurrent.atomic.AtomicReference
 import java.util.function.Consumer
-import java.util.zip.ZipEntry
-import java.util.zip.ZipFile
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipFile
+import org.objectweb.asm.ClassReader
+import org.objectweb.asm.tree.AnnotationNode
+import org.objectweb.asm.tree.ClassNode
+import org.objectweb.asm.tree.FieldNode
+import org.objectweb.asm.tree.MethodNode
+import org.objectweb.asm.tree.TypeAnnotationNode
 
 /**
  * Stores all classes loaded from a jar file, in a form of [ClassNode]
@@ -189,7 +188,8 @@
          * Load all the classes, without code.
          */
         fun loadClassStructures(
-            inJar: String,
+            inJar: ZipFile,
+            jarName: String,
             timeCollector: Consumer<Double>? = null,
         ): ClassNodes {
             val allClasses = ClassNodes()
@@ -201,20 +201,19 @@
             val exception = AtomicReference<Throwable>()
 
             // Called on a BG thread. Read a single jar entry and add it to [allClasses].
-            fun parseClass(inZip: ZipFile, entry: ZipEntry) {
+            fun parseClass(inZip: ZipFile, entry: ZipArchiveEntry) {
                 try {
-                    inZip.getInputStream(entry).use { ins ->
-                        val cr = ClassReader(BufferedInputStream(ins))
-                        val cn = ClassNode()
-                        cr.accept(
-                            cn, ClassReader.SKIP_CODE
-                                    or ClassReader.SKIP_DEBUG
-                                    or ClassReader.SKIP_FRAMES
-                        )
-                        synchronized(allClasses) {
-                            if (!allClasses.addClass(cn)) {
-                                log.w("Duplicate class found: ${cn.name}")
-                            }
+                    val classBytes = inZip.getInputStream(entry).use { it.readAllBytes() }
+                    val cr = ClassReader(classBytes)
+                    val cn = ClassNode()
+                    cr.accept(
+                        cn, ClassReader.SKIP_CODE
+                                or ClassReader.SKIP_DEBUG
+                                or ClassReader.SKIP_FRAMES
+                    )
+                    synchronized(allClasses) {
+                        if (!allClasses.addClass(cn)) {
+                            log.w("Duplicate class found: ${cn.name}")
                         }
                     }
                 } catch (e: Throwable) {
@@ -224,35 +223,30 @@
             }
 
             // Actually open the jar and read it on worker threads.
-            val time = log.iTime("Reading class structure from $inJar") {
+            val time = log.iTime("Reading class structure from $jarName") {
                 log.withIndent {
-                    ZipFile(inJar).use { inZip ->
-                        val inEntries = inZip.entries()
-
-                        while (inEntries.hasMoreElements()) {
-                            val entry = inEntries.nextElement()
-
-                            if (entry.name.endsWith(".class")) {
-                                executor.submit {
-                                    parseClass(inZip, entry)
-                                }
-                            } else if (entry.name.endsWith(".dex")) {
-                                // Seems like it's an ART jar file. We can't process it.
-                                // It's a fatal error.
-                                throw InvalidJarFileException(
-                                    "$inJar is not a desktop jar file."
-                                            + " It contains a *.dex file."
-                                )
-                            } else {
-                                // Unknown file type. Skip.
+                    inJar.entries.asSequence().forEach { entry ->
+                        if (entry.name.endsWith(".class")) {
+                            executor.submit {
+                                parseClass(inJar, entry)
                             }
+                        } else if (entry.name.endsWith(".dex")) {
+                            // Seems like it's an ART jar file. We can't process it.
+                            // It's a fatal error.
+                            throw InvalidJarFileException(
+                                "$jarName is not a desktop jar file."
+                                        + " It contains a *.dex file."
+                            )
+                        } else {
+                            // Unknown file type. Skip.
                         }
-                        // Wait for all the work to complete. (must do it before closing the zip)
-                        log.i("Waiting for all loaders to finish...")
-                        executor.shutdown()
-                        executor.awaitTermination(5, TimeUnit.MINUTES)
-                        log.i("All loaders to finished.")
                     }
+
+                    // Wait for all the work to complete. (must do it before closing the zip)
+                    log.i("Waiting for all loaders to finish...")
+                    executor.shutdown()
+                    executor.awaitTermination(5, TimeUnit.MINUTES)
+                    log.i("All loaders to finished.")
                 }
 
                 // If any exception is detected, throw it.
@@ -261,13 +255,13 @@
                 }
 
                 if (allClasses.size == 0) {
-                    log.w("$inJar contains no *.class files.")
+                    log.w("$jarName contains no *.class files.")
                 } else {
-                    log.i("Loaded ${allClasses.size} classes from $inJar.")
+                    log.i("Loaded ${allClasses.size} classes from $jarName.")
                 }
             }
             timeCollector?.accept(time)
             return allClasses
         }
     }
-}
\ No newline at end of file
+}
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt
index 5e4e70f..bb8cdcc 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/dumper/ApiDumper.kt
@@ -25,6 +25,7 @@
 import com.android.hoststubgen.filters.FilterPolicy
 import com.android.hoststubgen.filters.FilterPolicyWithReason
 import com.android.hoststubgen.filters.OutputFilter
+import com.android.hoststubgen.filters.StatsLabel
 import com.android.hoststubgen.log
 import org.objectweb.asm.Type
 import org.objectweb.asm.tree.ClassNode
@@ -44,7 +45,10 @@
         val descriptor: String,
     )
 
-    private val javaStandardApiPolicy = FilterPolicy.Keep.withReason("Java standard API")
+    private val javaStandardApiPolicy = FilterPolicy.Keep.withReason(
+        "Java standard API",
+        StatsLabel.Supported,
+    )
 
     private val shownMethods = mutableSetOf<MethodKey>()
 
@@ -53,7 +57,7 @@
      */
     fun dump() {
         pw.printf("PackageName,ClassName,FromSubclass,DeclareClass,MethodName,MethodDesc" +
-                ",Supported,Policy,Reason\n")
+                ",Supported,Policy,Reason,SupportedLabel\n")
 
         classes.forEach { classNode ->
             shownMethods.clear()
@@ -68,23 +72,36 @@
         methodClassName: String,
         methodName: String,
         methodDesc: String,
-        policy: FilterPolicyWithReason,
+        classPolicy: FilterPolicyWithReason,
+        methodPolicy: FilterPolicyWithReason,
     ) {
+        if (methodPolicy.statsLabel == StatsLabel.Ignored) {
+            return
+        }
+        // Label hack -- if the method is supported, but the class is boring, then the
+        // method is boring too.
+        var methodLabel = methodPolicy.statsLabel
+        if (methodLabel == StatsLabel.SupportedButBoring
+            && classPolicy.statsLabel == StatsLabel.SupportedButBoring) {
+            methodLabel = classPolicy.statsLabel
+        }
+
         pw.printf(
-            "%s,%s,%d,%s,%s,%s,%d,%s,%s\n",
+            "%s,%s,%d,%s,%s,%s,%d,%s,%s,%s\n",
             csvEscape(classPackage),
             csvEscape(className),
             if (isSuperClass) { 1 } else { 0 },
             csvEscape(methodClassName),
             csvEscape(methodName),
             csvEscape(methodDesc),
-            if (policy.policy.isSupported) { 1 } else { 0 },
-            policy.policy,
-            csvEscape(policy.reason),
+            methodLabel.statValue,
+            methodPolicy.policy,
+            csvEscape(methodPolicy.reason),
+            methodLabel,
         )
     }
 
-    private fun isDuplicate(methodName: String, methodDesc: String): Boolean {
+    private fun shownAlready(methodName: String, methodDesc: String): Boolean {
         val methodKey = MethodKey(methodName, methodDesc)
 
         if (shownMethods.contains(methodKey)) {
@@ -98,6 +115,12 @@
         dumpClass: ClassNode,
         methodClass: ClassNode,
         ) {
+        val classPolicy = filter.getPolicyForClass(dumpClass.name)
+        if (classPolicy.statsLabel == StatsLabel.Ignored) {
+            return
+        }
+        log.d("Class ${dumpClass.name} -- policy $classPolicy")
+
         val pkg = getPackageNameFromFullClassName(dumpClass.name).toHumanReadableClassName()
         val cls = getClassNameFromFullClassName(dumpClass.name).toHumanReadableClassName()
 
@@ -112,23 +135,23 @@
                 }
             }
             // If we already printed the method from a subclass, don't print it.
-            if (isDuplicate(method.name, method.desc)) {
+            if (shownAlready(method.name, method.desc)) {
                 return@forEach
             }
 
-            val policy = filter.getPolicyForMethod(methodClass.name, method.name, method.desc)
+            val methodPolicy = filter.getPolicyForMethod(methodClass.name, method.name, method.desc)
 
             // Let's skip "Remove" APIs. Ideally we want to print it, just to make the CSV
             // complete, we still need to hide methods substituted (== @RavenwoodReplace) methods
             // and for now we don't have an easy way to detect it.
-            if (policy.policy == FilterPolicy.Remove) {
+            if (methodPolicy.policy == FilterPolicy.Remove) {
                 return@forEach
             }
 
             val renameTo = filter.getRenameTo(methodClass.name, method.name, method.desc)
 
             dumpMethod(pkg, cls, isSuperClass, methodClass.name.toHumanReadableClassName(),
-                renameTo ?: method.name, method.desc, policy)
+                renameTo ?: method.name, method.desc, classPolicy, methodPolicy)
        }
 
         // Dump super class methods.
@@ -155,10 +178,13 @@
             dump(dumpClass, methodClass)
             return
         }
-        if (methodClassName.startsWith("java/") ||
-            methodClassName.startsWith("javax/")
-            ) {
-            dumpStandardClass(dumpClass, methodClassName)
+
+        // Dump overriding methods from Java standard classes, except for the Object methods,
+        // which are obvious.
+        if (methodClassName.startsWith("java/") || methodClassName.startsWith("javax/")) {
+            if (methodClassName != "java/lang/Object") {
+               dumpStandardClass(dumpClass, methodClassName)
+            }
             return
         }
         log.w("Super class or interface $methodClassName (used by ${dumpClass.name}) not found.")
@@ -188,12 +214,12 @@
                 val methodDesc = Type.getMethodDescriptor(method)
 
                 // If we already printed the method from a subclass, don't print it.
-                if (isDuplicate(methodName, methodDesc)) {
+                if (shownAlready(methodName, methodDesc)) {
                     return@forEach
                 }
 
                 dumpMethod(pkg, cls, true, methodClassName,
-                    methodName, methodDesc, javaStandardApiPolicy)
+                    methodName, methodDesc, javaStandardApiPolicy, javaStandardApiPolicy)
             }
         } catch (e: ClassNotFoundException) {
             log.w("JVM type $methodClassName (used by ${dumpClass.name}) not found.")
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt
index 81c26ff..c3c870f 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicy.kt
@@ -155,7 +155,10 @@
     /**
      * Create a [FilterPolicyWithReason] with a given reason.
      */
-    fun withReason(reason: String): FilterPolicyWithReason {
-        return FilterPolicyWithReason(this, reason)
+    fun withReason(
+        reason: String,
+        statsLabelOverride: StatsLabel? = null,
+    ): FilterPolicyWithReason {
+        return FilterPolicyWithReason(this, reason, statsLabelOverride = statsLabelOverride)
     }
 }
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
index b10165b..7358a0b 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/FilterPolicyWithReason.kt
@@ -16,32 +16,54 @@
 package com.android.hoststubgen.filters
 
 /**
+ * How each entry should be handled on the dashboard.
+ */
+enum class StatsLabel(val statValue: Int, val label: String) {
+    /** Entry shouldn't show up in the dashboard. */
+    Ignored(-1, ""),
+
+    /** Entry should be shown as "not supported" */
+    NotSupported(0, "NotSupported"),
+
+    /**
+     * Entry should be shown as "supported", but are too "boring" to show on the dashboard,
+     * e.g. annotation classes.
+     */
+    SupportedButBoring(1, "Boring"),
+
+    /** Entry should be shown as "supported" */
+    Supported(2, "Supported"),
+}
+
+/**
  * Captures a [FilterPolicy] with a human-readable reason.
  */
 data class FilterPolicyWithReason (
-        val policy: FilterPolicy,
-        val reason: String = "",
+    val policy: FilterPolicy,
+    val reason: String = "",
+    private val statsLabelOverride: StatsLabel? = null
 ) {
     /**
      * Return a new [FilterPolicy] with an updated reason, while keeping the original reason
      * as an "inner-reason".
      */
-    fun wrapReason(reason: String): FilterPolicyWithReason {
-        return FilterPolicyWithReason(policy, "$reason [inner-reason: ${this.reason}]")
+    fun wrapReason(reason: String, statsLabelOverride: StatsLabel? = null): FilterPolicyWithReason {
+        return FilterPolicyWithReason(
+            policy,
+            "$reason [inner-reason: ${this.reason}]",
+            statsLabelOverride = statsLabelOverride,
+        )
     }
 
     override fun toString(): String {
-        return "[$policy - reason: $reason]"
+        return "[$policy/$statsLabel - reason: $reason]"
     }
 
-    /** Returns whether this policy should be ignored for stats. */
-    val isIgnoredForStats: Boolean
-        get() {
-            return reason.contains("anonymous-inner-class")
-                    || reason.contains("is-annotation")
-                    || reason.contains("is-enum")
-                    || reason.contains("is-synthetic-method")
-                    || reason.contains("special-class")
-                    || reason.contains("substitute-to")
+    val statsLabel: StatsLabel get() {
+        statsLabelOverride?.let { return it }
+        if (policy.isSupported) {
+            return StatsLabel.Supported
         }
+        return StatsLabel.NotSupported
+    }
 }
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
index d44d016..1145da6 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/ImplicitOutputFilter.kt
@@ -48,7 +48,11 @@
             // If the outer class needs to be in impl, it should be in impl too.
             val outerPolicy = outermostFilter.getPolicyForClass(cn.outerClass)
             if (outerPolicy.policy.needsInOutput) {
-                return FilterPolicy.KeepClass.withReason("anonymous-inner-class")
+                // We keep this class, but don't need to show it in the dashboard.
+                return FilterPolicy.KeepClass.withReason(
+                    "anonymous-inner-class",
+                    StatsLabel.Ignored,
+                )
             }
         }
         return null
@@ -62,6 +66,15 @@
         // Use the implicit policy, if any.
         getClassImplicitPolicy(cn)?.let { return it }
 
+        // If it's an annotation class and we need to keep it, then
+        // change the reason to hide it from the stats.
+        if (cn.isAnnotation() && fallback.policy.needsInOutput) {
+            return FilterPolicy.KeepClass.withReason(
+                "is-annotation",
+                StatsLabel.Ignored,
+            )
+        }
+
         return fallback
     }
 
@@ -102,14 +115,20 @@
             if (cn.isEnum()) {
                 mn?.let { mn ->
                     if (isAutoGeneratedEnumMember(mn)) {
-                        return memberPolicy.withReason(classPolicy.reason).wrapReason("is-enum")
+                        return memberPolicy.withReason(classPolicy.reason).wrapReason(
+                            "is-enum",
+                            StatsLabel.Ignored,
+                        )
                     }
                 }
             }
 
             // Keep (or stub) all members of annotations.
             if (cn.isAnnotation()) {
-                return memberPolicy.withReason(classPolicy.reason).wrapReason("is-annotation")
+                return memberPolicy.withReason(classPolicy.reason).wrapReason(
+                    "is-annotation",
+                    StatsLabel.Ignored,
+                )
             }
 
             mn?.let {
@@ -117,7 +136,8 @@
                     // For synthetic methods (such as lambdas), let's just inherit the class's
                     // policy.
                     return memberPolicy.withReason(classPolicy.reason).wrapReason(
-                        "is-synthetic-method"
+                        "is-synthetic-method",
+                        StatsLabel.Ignored,
                     )
                 }
             }
diff --git a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt
index 00e7d77..57309b4 100644
--- a/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt
+++ b/ravenwood/tools/hoststubgen/lib/com/android/hoststubgen/filters/KeepNativeFilter.kt
@@ -22,6 +22,9 @@
  *  For native methods that weren't handled by outer filters, we keep it so that
  *  native method registration will not crash at runtime. Ideally we shouldn't need
  *  this, but in practice unsupported native method registrations do occur.
+ *
+ *  Native methods kept by this filter will all have a "Keep" policy, but they won't show
+ *  up as "supported" in the stats dashboard beucase we set reallySupported to false.
  */
 class KeepNativeFilter(
     private val classes: ClassNodes,
@@ -34,7 +37,7 @@
     ): FilterPolicyWithReason {
         return classes.findMethod(className, methodName, descriptor)?.let { mn ->
             if (mn.isNative()) {
-                FilterPolicy.Keep.withReason("native-preserve")
+                FilterPolicy.Keep.withReason("native-preserve", StatsLabel.NotSupported)
             } else {
                 null
             }
diff --git a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
index 3335405..3291ff6 100644
--- a/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
+++ b/ravenwood/tools/hoststubgen/src/com/android/hoststubgen/HostStubGen.kt
@@ -19,13 +19,11 @@
 import com.android.hoststubgen.dumper.ApiDumper
 import com.android.hoststubgen.filters.FilterPolicy
 import com.android.hoststubgen.filters.printAsTextPolicy
-import java.io.BufferedInputStream
-import java.io.BufferedOutputStream
 import java.io.FileOutputStream
 import java.io.PrintWriter
-import java.util.zip.ZipEntry
-import java.util.zip.ZipFile
-import java.util.zip.ZipOutputStream
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
+import org.apache.commons.compress.archivers.zip.ZipFile
 
 /**
  * Actual main class.
@@ -33,10 +31,12 @@
 class HostStubGen(val options: HostStubGenOptions) {
     fun run() {
         val errors = HostStubGenErrors()
-        val stats = HostStubGenStats()
+        val inJar = ZipFile(options.inJar.get)
 
         // Load all classes.
-        val allClasses = ClassNodes.loadClassStructures(options.inJar.get)
+        val allClasses = ClassNodes.loadClassStructures(inJar, options.inJar.get)
+
+        val stats = HostStubGenStats(allClasses)
 
         // Dump the classes, if specified.
         options.inputJarDumpFile.ifSet {
@@ -59,7 +59,7 @@
         val processor = HostStubGenClassProcessor(options, allClasses, errors, stats)
 
         // Transform the jar.
-        convert(
+        inJar.convert(
             options.inJar.get,
             options.outJar.get,
             processor,
@@ -88,7 +88,7 @@
     /**
      * Convert a JAR file into "stub" and "impl" JAR files.
      */
-    private fun convert(
+    private fun ZipFile.convert(
         inJar: String,
         outJar: String?,
         processor: HostStubGenClassProcessor,
@@ -100,45 +100,39 @@
         log.i("ASM CheckClassAdapter is %s", if (enableChecker) "enabled" else "disabled")
 
         log.iTime("Transforming jar") {
-            var itemIndex = 0
             var numItemsProcessed = 0
             var numItems = -1 // == Unknown
 
             log.withIndent {
-                // Open the input jar file and process each entry.
-                ZipFile(inJar).use { inZip ->
+                val entries = entries.toList()
 
-                    numItems = inZip.size()
-                    val shardStart = numItems * shard / numShards
-                    val shardNextStart = numItems * (shard + 1) / numShards
+                numItems = entries.size
+                val shardStart = numItems * shard / numShards
+                val shardNextStart = numItems * (shard + 1) / numShards
 
-                    maybeWithZipOutputStream(outJar) { outStream ->
-                        val inEntries = inZip.entries()
-                        while (inEntries.hasMoreElements()) {
-                            val entry = inEntries.nextElement()
-                            val inShard = (shardStart <= itemIndex)
-                                    && (itemIndex < shardNextStart)
-                            itemIndex++
-                            if (!inShard) {
-                                continue
-                            }
-                            convertSingleEntry(inZip, entry, outStream, processor)
-                            numItemsProcessed++
+                maybeWithZipOutputStream(outJar) { outStream ->
+                    entries.forEachIndexed { itemIndex, entry ->
+                        val inShard = (shardStart <= itemIndex)
+                                && (itemIndex < shardNextStart)
+                        if (!inShard) {
+                            return@forEachIndexed
                         }
-                        log.i("Converted all entries.")
+                        convertSingleEntry(this, entry, outStream, processor)
+                        numItemsProcessed++
                     }
-                    outJar?.let { log.i("Created: $it") }
+                    log.i("Converted all entries.")
                 }
+                outJar?.let { log.i("Created: $it") }
             }
             log.i("%d / %d item(s) processed.", numItemsProcessed, numItems)
         }
     }
 
-    private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipOutputStream?) -> T): T {
+    private fun <T> maybeWithZipOutputStream(filename: String?, block: (ZipArchiveOutputStream?) -> T): T {
         if (filename == null) {
             return block(null)
         }
-        return ZipOutputStream(BufferedOutputStream(FileOutputStream(filename))).use(block)
+        return ZipArchiveOutputStream(FileOutputStream(filename).buffered()).use(block)
     }
 
     /**
@@ -146,8 +140,8 @@
      */
     private fun convertSingleEntry(
         inZip: ZipFile,
-        entry: ZipEntry,
-        outStream: ZipOutputStream?,
+        entry: ZipArchiveEntry,
+        outStream: ZipArchiveOutputStream?,
         processor: HostStubGenClassProcessor
     ) {
         log.d("Entry: %s", entry.name)
@@ -181,32 +175,12 @@
     }
 
     /**
-     * Copy a single ZIP entry to the output.
-     */
-    private fun copyZipEntry(
-        inZip: ZipFile,
-        entry: ZipEntry,
-        out: ZipOutputStream,
-    ) {
-        // TODO: It seems like copying entries this way is _very_ slow,
-        // even with out.setLevel(0). Look for other ways to do it.
-
-        inZip.getInputStream(entry).use { ins ->
-            // Copy unknown entries as is to the impl out. (but not to the stub out.)
-            val outEntry = ZipEntry(entry.name)
-            out.putNextEntry(outEntry)
-            ins.transferTo(out)
-            out.closeEntry()
-        }
-    }
-
-    /**
      * Convert a single class.
      */
     private fun processSingleClass(
         inZip: ZipFile,
-        entry: ZipEntry,
-        outStream: ZipOutputStream?,
+        entry: ZipArchiveEntry,
+        outStream: ZipArchiveOutputStream?,
         processor: HostStubGenClassProcessor
     ) {
         val classInternalName = entry.name.replaceFirst("\\.class$".toRegex(), "")
@@ -227,12 +201,10 @@
         if (outStream != null) {
             log.v("Creating class: %s Policy: %s", classInternalName, classPolicy)
             log.withIndent {
-                BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
-                    val newEntry = ZipEntry(newName)
-                    outStream.putNextEntry(newEntry)
-                    val classBytecode = bis.readAllBytes()
-                    outStream.write(processor.processClassBytecode(classBytecode))
-                    outStream.closeEntry()
+                inZip.getInputStream(entry).use { zis ->
+                    var classBytecode = zis.readAllBytes()
+                    classBytecode = processor.processClassBytecode(classBytecode)
+                    outStream.addBytesEntry(newName, classBytecode)
                 }
             }
         }
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
index 7617482..0c2269a 100755
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/tiny-framework-dump-test.py
@@ -33,7 +33,7 @@
                '--ignore-space-change',
 
                # Ignore the class file version.
-               '--ignore-matching-lines=^ *\(major\|minor\) version:$',
+               '--ignore-matching-lines=^ *\\(major\\|minor\\) version:$',
 
                # We shouldn't need `--ignore-matching-lines`, but somehow
                # the golden files were generated without these lines for b/388562869,
diff --git a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt
index 04e3bda2..8e36323 100644
--- a/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt
+++ b/ravenwood/tools/ravenizer/src/com/android/platform/test/ravenwood/ravenizer/Ravenizer.kt
@@ -17,17 +17,17 @@
 
 import com.android.hoststubgen.GeneralUserErrorException
 import com.android.hoststubgen.HostStubGenClassProcessor
+import com.android.hoststubgen.addBytesEntry
 import com.android.hoststubgen.asm.ClassNodes
 import com.android.hoststubgen.asm.zipEntryNameToClassName
+import com.android.hoststubgen.copyZipEntry
 import com.android.hoststubgen.executableName
 import com.android.hoststubgen.log
 import com.android.platform.test.ravenwood.ravenizer.adapter.RunnerRewritingAdapter
-import java.io.BufferedInputStream
-import java.io.BufferedOutputStream
 import java.io.FileOutputStream
-import java.util.zip.ZipEntry
-import java.util.zip.ZipFile
-import java.util.zip.ZipOutputStream
+import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
+import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream
+import org.apache.commons.compress.archivers.zip.ZipFile
 import org.objectweb.asm.ClassReader
 import org.objectweb.asm.ClassVisitor
 import org.objectweb.asm.ClassWriter
@@ -93,13 +93,14 @@
         val stats = RavenizerStats()
 
         stats.totalTime = log.nTime {
-            val allClasses = ClassNodes.loadClassStructures(options.inJar.get) {
+            val inJar = ZipFile(options.inJar.get)
+            val allClasses = ClassNodes.loadClassStructures(inJar, options.inJar.get) {
                 stats.loadStructureTime = it
             }
             val processor = HostStubGenClassProcessor(options, allClasses)
 
-            process(
-                options.inJar.get,
+            inJar.process(
+                options.outJar.get,
                 options.outJar.get,
                 options.enableValidation.get,
                 options.fatalValidation.get,
@@ -111,7 +112,7 @@
         log.i(stats.toString())
     }
 
-    private fun process(
+    private fun ZipFile.process(
         inJar: String,
         outJar: String,
         enableValidation: Boolean,
@@ -138,40 +139,34 @@
         }
 
         stats.totalProcessTime = log.vTime("$executableName processing $inJar") {
-            ZipFile(inJar).use { inZip ->
-                val inEntries = inZip.entries()
+            ZipArchiveOutputStream(FileOutputStream(outJar).buffered()).use { outZip ->
+                entries.asSequence().forEach { entry ->
+                    stats.totalEntries++
+                    if (entry.name.endsWith(".dex")) {
+                        // Seems like it's an ART jar file. We can't process it.
+                        // It's a fatal error.
+                        throw GeneralUserErrorException(
+                            "$inJar is not a desktop jar file. It contains a *.dex file."
+                        )
+                    }
 
-                stats.totalEntries = inZip.size()
+                    if (stripMockito && entry.name.isMockitoFile()) {
+                        // Skip this entry
+                        return@forEach
+                    }
 
-                ZipOutputStream(BufferedOutputStream(FileOutputStream(outJar))).use { outZip ->
-                    while (inEntries.hasMoreElements()) {
-                        val entry = inEntries.nextElement()
+                    val className = zipEntryNameToClassName(entry.name)
 
-                        if (entry.name.endsWith(".dex")) {
-                            // Seems like it's an ART jar file. We can't process it.
-                            // It's a fatal error.
-                            throw GeneralUserErrorException(
-                                "$inJar is not a desktop jar file. It contains a *.dex file."
-                            )
-                        }
+                    if (className != null) {
+                        stats.totalClasses += 1
+                    }
 
-                        if (stripMockito && entry.name.isMockitoFile()) {
-                            // Skip this entry
-                            continue
-                        }
-
-                        val className = zipEntryNameToClassName(entry.name)
-
-                        if (className != null) {
-                            stats.totalClasses += 1
-                        }
-
-                        if (className != null &&
-                            shouldProcessClass(processor.allClasses, className)) {
-                            processSingleClass(inZip, entry, outZip, processor, stats)
-                        } else {
-                            // Too slow, let's use merge_zips to bring back the original classes.
-                            copyZipEntry(inZip, entry, outZip, stats)
+                    if (className != null &&
+                        shouldProcessClass(processor.allClasses, className)) {
+                        processSingleClass(this, entry, outZip, processor, stats)
+                    } else {
+                        stats.totalCopyTime += log.nTime {
+                            copyZipEntry(this, entry, outZip)
                         }
                     }
                 }
@@ -179,53 +174,25 @@
         }
     }
 
-    /**
-     * Copy a single ZIP entry to the output.
-     */
-    private fun copyZipEntry(
-        inZip: ZipFile,
-        entry: ZipEntry,
-        out: ZipOutputStream,
-        stats: RavenizerStats,
-    ) {
-        stats.totalCopyTime += log.nTime {
-            inZip.getInputStream(entry).use { ins ->
-                // Copy unknown entries as is to the impl out. (but not to the stub out.)
-                val outEntry = ZipEntry(entry.name)
-                outEntry.method = 0
-                outEntry.size = entry.size
-                outEntry.crc = entry.crc
-                out.putNextEntry(outEntry)
-
-                ins.transferTo(out)
-
-                out.closeEntry()
-            }
-        }
-    }
-
     private fun processSingleClass(
         inZip: ZipFile,
-        entry: ZipEntry,
-        outZip: ZipOutputStream,
+        entry: ZipArchiveEntry,
+        outZip: ZipArchiveOutputStream,
         processor: HostStubGenClassProcessor,
         stats: RavenizerStats,
     ) {
         stats.processedClasses += 1
-        val newEntry = ZipEntry(entry.name)
-        outZip.putNextEntry(newEntry)
-
-        BufferedInputStream(inZip.getInputStream(entry)).use { bis ->
-            var classBytes = bis.readBytes()
+        inZip.getInputStream(entry).use { zis ->
+            var classBytes = zis.readAllBytes()
             stats.totalRavenizeTime += log.vTime("Ravenize ${entry.name}") {
                 classBytes = ravenizeSingleClass(entry, classBytes, processor.allClasses)
             }
             stats.totalHostStubGenTime += log.vTime("HostStubGen ${entry.name}") {
                 classBytes = processor.processClassBytecode(classBytes)
             }
-            outZip.write(classBytes)
+            // TODO: if the class does not change, use copyZipEntry
+            outZip.addBytesEntry(entry.name, classBytes)
         }
-        outZip.closeEntry()
     }
 
     /**
@@ -237,7 +204,7 @@
     }
 
     private fun ravenizeSingleClass(
-        entry: ZipEntry,
+        entry: ZipArchiveEntry,
         input: ByteArray,
         allClasses: ClassNodes,
     ): ByteArray {
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index 6c26c1f..703e37f 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -531,7 +531,7 @@
             AccessibilitySecurityPolicy securityPolicy,
             SystemActionPerformer systemActionPerformer,
             AccessibilityWindowManager a11yWindowManager,
-            AccessibilityDisplayListener a11yDisplayListener,
+            AccessibilityDisplayListener.DisplayManagerWrapper displayManagerWrapper,
             MagnificationController magnificationController,
             @Nullable AccessibilityInputFilter inputFilter,
             ProxyManager proxyManager,
@@ -550,7 +550,8 @@
         mSecurityPolicy = securityPolicy;
         mSystemActionPerformer = systemActionPerformer;
         mA11yWindowManager = a11yWindowManager;
-        mA11yDisplayListener = a11yDisplayListener;
+        mA11yDisplayListener = new AccessibilityDisplayListener(displayManagerWrapper,
+                new MainHandler(Looper.getMainLooper()));
         mMagnificationController = magnificationController;
         mMagnificationProcessor = new MagnificationProcessor(mMagnificationController);
         mCaptioningManagerImpl = new CaptioningManagerImpl(mContext);
@@ -596,7 +597,8 @@
                 this, LocalServices.getService(PackageManagerInternal.class));
         mA11yWindowManager = new AccessibilityWindowManager(mLock, mMainHandler,
                 mWindowManagerService, this, mSecurityPolicy, this, mTraceManager);
-        mA11yDisplayListener = new AccessibilityDisplayListener(mContext, mMainHandler);
+        mA11yDisplayListener = new AccessibilityDisplayListener(
+                new AccessibilityDisplayListener.DisplayManagerWrapper(mContext), mMainHandler);
         mMagnificationController = new MagnificationController(
                 this,
                 mLock,
@@ -5457,11 +5459,11 @@
      * A Utility class to handle display state.
      */
     public class AccessibilityDisplayListener implements DisplayManager.DisplayListener {
-        private final DisplayManager mDisplayManager;
+        private final DisplayManagerWrapper mDisplayManager;
         private final ArrayList<Display> mDisplaysList = new ArrayList<>();
         private int mSystemUiUid = 0;
 
-        AccessibilityDisplayListener(Context context, Handler handler) {
+        AccessibilityDisplayListener(DisplayManagerWrapper displayManager, Handler handler) {
             // Avoid concerns about one thread adding displays while another thread removes
             // them by ensuring the looper is the main looper and the DisplayListener
             // callbacks are always executed on the one main thread.
@@ -5474,7 +5476,7 @@
                 Slog.e(LOG_TAG, errorMessage);
             }
 
-            mDisplayManager = (DisplayManager) context.getSystemService(Context.DISPLAY_SERVICE);
+            mDisplayManager = displayManager;
             mDisplayManager.registerDisplayListener(this, handler);
             initializeDisplayList();
 
@@ -5626,6 +5628,34 @@
             }
             return true;
         }
+
+        /** Wrapper of DisplayManager for testing. */
+        @VisibleForTesting
+        static class DisplayManagerWrapper {
+            private final DisplayManager mDm;
+
+            DisplayManagerWrapper(Context context) {
+                mDm = context.getSystemService(DisplayManager.class);
+            }
+
+            /**
+             * @see DisplayManager#registerDisplayListener(DisplayManager.DisplayListener, Handler)
+             */
+            public void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
+                    @Nullable Handler handler) {
+                mDm.registerDisplayListener(listener, handler);
+            }
+
+            /** @see DisplayManager#getDisplays() */
+            public Display[] getDisplays() {
+                return mDm.getDisplays();
+            }
+
+            /** @see DisplayManager#getDisplay(int) */
+            public Display getDisplay(int displayId) {
+                return mDm.getDisplay(displayId);
+            }
+        }
     }
 
     /** Represents an {@link AccessibilityManager} */
diff --git a/services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java b/services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java
index 805d7f8..edcf574 100644
--- a/services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java
+++ b/services/accessibility/java/com/android/server/accessibility/HearingDevicePhoneCallNotificationController.java
@@ -17,6 +17,7 @@
 package com.android.server.accessibility;
 
 import android.Manifest;
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.SuppressLint;
 import android.app.Notification;
@@ -149,11 +150,7 @@
             }
 
             if (state == TelephonyManager.CALL_STATE_IDLE) {
-                if (mIsCommDeviceChangedRegistered) {
-                    mIsCommDeviceChangedRegistered = false;
-                    mAudioManager.removeOnCommunicationDeviceChangedListener(
-                            mCommDeviceChangedListener);
-                }
+                removeOnCommunicationDeviceChangedListenerIfNeeded(mCommDeviceChangedListener);
                 dismissNotificationIfNeeded();
 
                 if (mHearingDevice != null) {
@@ -165,14 +162,15 @@
             if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
                 if (com.android.server.accessibility.Flags.hearingInputChangeWhenCommDevice()) {
                     AudioDeviceInfo commDevice = mAudioManager.getCommunicationDevice();
+                    if (commDevice == null) {
+                        return;
+                    }
                     mHearingDevice = getSupportedInputHearingDeviceInfo(List.of(commDevice));
                     if (mHearingDevice != null) {
                         showNotificationIfNeeded();
                     } else {
-                        mAudioManager.addOnCommunicationDeviceChangedListener(
-                                mCommDeviceChangedExecutor,
+                        addOnCommunicationDeviceChangedListenerIfNeeded(mCommDeviceChangedExecutor,
                                 mCommDeviceChangedListener);
-                        mIsCommDeviceChangedRegistered = true;
                     }
                 } else {
                     mHearingDevice = getSupportedInputHearingDeviceInfo(
@@ -184,6 +182,27 @@
             }
         }
 
+        private void addOnCommunicationDeviceChangedListenerIfNeeded(
+                @NonNull @CallbackExecutor Executor executor,
+                @NonNull AudioManager.OnCommunicationDeviceChangedListener listener) {
+            if (mIsCommDeviceChangedRegistered) {
+                return;
+            }
+
+            mIsCommDeviceChangedRegistered = true;
+            mAudioManager.addOnCommunicationDeviceChangedListener(executor, listener);
+        }
+
+        private void removeOnCommunicationDeviceChangedListenerIfNeeded(
+                @NonNull AudioManager.OnCommunicationDeviceChangedListener listener) {
+            if (!mIsCommDeviceChangedRegistered) {
+                return;
+            }
+
+            mAudioManager.removeOnCommunicationDeviceChangedListener(listener);
+            mIsCommDeviceChangedRegistered = false;
+        }
+
         private void showNotificationIfNeeded() {
             if (mIsNotificationShown) {
                 return;
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
index 23166a8..0b9c45d 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickController.java
@@ -24,6 +24,8 @@
 import static android.view.accessibility.AccessibilityManager.AUTOCLICK_REVERT_TO_LEFT_CLICK_DEFAULT;
 
 import static com.android.server.accessibility.autoclick.AutoclickIndicatorView.SHOW_INDICATOR_DELAY_TIME;
+import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_DOUBLE_CLICK;
+import static com.android.server.accessibility.autoclick.AutoclickScrollPanel.DIRECTION_NONE;
 import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_LEFT_CLICK;
 import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_RIGHT_CLICK;
 import static com.android.server.accessibility.autoclick.AutoclickTypePanel.AUTOCLICK_TYPE_SCROLL;
@@ -45,6 +47,7 @@
 import android.view.MotionEvent;
 import android.view.MotionEvent.PointerCoords;
 import android.view.MotionEvent.PointerProperties;
+import android.view.ViewConfiguration;
 import android.view.WindowManager;
 
 import androidx.annotation.VisibleForTesting;
@@ -95,6 +98,9 @@
     // Default click type is left-click.
     private @AutoclickType int mActiveClickType = AUTOCLICK_TYPE_LEFT_CLICK;
 
+    // Default scroll direction is DIRECTION_NONE.
+    private @AutoclickScrollPanel.ScrollDirection int mHoveredDirection = DIRECTION_NONE;
+
     @VisibleForTesting
     final ClickPanelControllerInterface clickPanelController =
             new ClickPanelControllerInterface() {
@@ -129,14 +135,26 @@
     final AutoclickScrollPanel.ScrollPanelControllerInterface mScrollPanelController =
             new AutoclickScrollPanel.ScrollPanelControllerInterface() {
                 @Override
-                public void handleScroll(@AutoclickScrollPanel.ScrollDirection int direction) {
-                    // TODO(b/388845721): Perform actual scroll.
-                }
+                public void onHoverButtonChange(
+                        @AutoclickScrollPanel.ScrollDirection int direction,
+                        boolean hovered) {
+                    // Update the hover direction.
+                    if (hovered) {
+                        mHoveredDirection = direction;
+                    } else if (mHoveredDirection == direction) {
+                        // Safety check: Only clear hover tracking if this is the same button
+                        // we're currently tracking.
+                        mHoveredDirection = AutoclickScrollPanel.DIRECTION_NONE;
+                    }
 
-                @Override
-                public void exitScrollMode() {
-                    if (mAutoclickScrollPanel != null) {
-                        mAutoclickScrollPanel.hide();
+                    // For exit button, we only trigger hover state changes, the autoclick system
+                    // will handle the countdown.
+                    if (direction == AutoclickScrollPanel.DIRECTION_EXIT) {
+                        return;
+                    }
+                    // For direction buttons, perform scroll action immediately.
+                    if (hovered && direction != AutoclickScrollPanel.DIRECTION_NONE) {
+                        handleScroll(direction);
                     }
                 }
             };
@@ -283,6 +301,22 @@
         }
     }
 
+    /**
+     * Handles scroll operations in the specified direction.
+     */
+    public void handleScroll(@AutoclickScrollPanel.ScrollDirection int direction) {
+        // TODO(b/388845721): Perform actual scroll.
+    }
+
+    /**
+     * Exits scroll mode and hides the scroll panel UI.
+     */
+    public void exitScrollMode() {
+        if (mAutoclickScrollPanel != null) {
+            mAutoclickScrollPanel.hide();
+        }
+    }
+
     @VisibleForTesting
     void onChangeForTesting(boolean selfChange, Uri uri) {
         mAutoclickSettingsObserver.onChange(selfChange, uri);
@@ -774,6 +808,14 @@
                 return;
             }
 
+            if (mAutoclickScrollPanel != null && mAutoclickScrollPanel.isVisible()) {
+                // If exit button is hovered, exit scroll mode after countdown and return early.
+                if (mHoveredDirection == AutoclickScrollPanel.DIRECTION_EXIT) {
+                    exitScrollMode();
+                }
+                return;
+            }
+
             // Handle scroll type specially, show scroll panel instead of sending click events.
             if (mActiveClickType == AutoclickTypePanel.AUTOCLICK_TYPE_SCROLL) {
                 if (mAutoclickScrollPanel != null) {
@@ -799,7 +841,7 @@
 
             final long now = SystemClock.uptimeMillis();
 
-            int actionButton;
+            int actionButton = BUTTON_PRIMARY;
             if (mHoveredState) {
                 // Always triggers left-click when the cursor hovers over the autoclick type
                 // panel, to always allow users to change a different click type. Otherwise, if
@@ -807,15 +849,32 @@
                 // select other click types.
                 actionButton = BUTTON_PRIMARY;
             } else {
-                actionButton = mActiveClickType == AUTOCLICK_TYPE_RIGHT_CLICK
-                        ? BUTTON_SECONDARY
-                        : BUTTON_PRIMARY;
+                switch (mActiveClickType) {
+                    case AUTOCLICK_TYPE_LEFT_CLICK:
+                        actionButton = BUTTON_PRIMARY;
+                        break;
+                    case AUTOCLICK_TYPE_RIGHT_CLICK:
+                        actionButton = BUTTON_SECONDARY;
+                        break;
+                    case AUTOCLICK_TYPE_DOUBLE_CLICK:
+                        actionButton = BUTTON_PRIMARY;
+                        long doubleTapMinimumTimeout = ViewConfiguration.getDoubleTapMinTime();
+                        sendMotionEvent(actionButton, now);
+                        sendMotionEvent(actionButton, now + doubleTapMinimumTimeout);
+                        return;
+                    default:
+                        break;
+                }
             }
 
+            sendMotionEvent(actionButton, now);
+        }
+
+        private void sendMotionEvent(int actionButton, long eventTime) {
             MotionEvent downEvent =
                     MotionEvent.obtain(
-                            /* downTime= */ now,
-                            /* eventTime= */ now,
+                            /* downTime= */ eventTime,
+                            /* eventTime= */ eventTime,
                             MotionEvent.ACTION_DOWN,
                             /* pointerCount= */ 1,
                             mTempPointerProperties,
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java
index e79be50..c714431 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickScrollPanel.java
@@ -23,6 +23,7 @@
 import android.graphics.PixelFormat;
 import android.view.Gravity;
 import android.view.LayoutInflater;
+import android.view.MotionEvent;
 import android.view.View;
 import android.view.WindowInsets;
 import android.view.WindowManager;
@@ -41,12 +42,16 @@
     public static final int DIRECTION_DOWN = 1;
     public static final int DIRECTION_LEFT = 2;
     public static final int DIRECTION_RIGHT = 3;
+    public static final int DIRECTION_EXIT = 4;
+    public static final int DIRECTION_NONE = 5;
 
     @IntDef({
             DIRECTION_UP,
             DIRECTION_DOWN,
             DIRECTION_LEFT,
-            DIRECTION_RIGHT
+            DIRECTION_RIGHT,
+            DIRECTION_EXIT,
+            DIRECTION_NONE,
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface ScrollDirection {}
@@ -70,16 +75,12 @@
      */
     public interface ScrollPanelControllerInterface {
         /**
-         * Called when a scroll direction is hovered.
+         * Called when a button hover state changes.
          *
-         * @param direction The direction to scroll: one of {@link ScrollDirection} values.
+         * @param direction The direction associated with the button.
+         * @param hovered Whether the button is being hovered or not.
          */
-        void handleScroll(@ScrollDirection int direction);
-
-        /**
-         * Called when the exit button is hovered.
-         */
-        void exitScrollMode();
+        void onHoverButtonChange(@ScrollDirection int direction, boolean hovered);
     }
 
     public AutoclickScrollPanel(Context context, WindowManager windowManager,
@@ -104,19 +105,12 @@
      * Sets up hover listeners for scroll panel buttons.
      */
     private void initializeButtonState() {
-        // Set up hover listeners for direction buttons.
-        setupHoverListenerForDirectionButton(mUpButton, DIRECTION_UP);
-        setupHoverListenerForDirectionButton(mLeftButton, DIRECTION_LEFT);
-        setupHoverListenerForDirectionButton(mRightButton, DIRECTION_RIGHT);
-        setupHoverListenerForDirectionButton(mDownButton, DIRECTION_DOWN);
-
-        // Set up hover listener for exit button.
-        mExitButton.setOnHoverListener((v, event) -> {
-            if (mScrollPanelController != null) {
-                mScrollPanelController.exitScrollMode();
-            }
-            return true;
-        });
+        // Set up hover listeners for all buttons.
+        setupHoverListenerForButton(mUpButton, DIRECTION_UP);
+        setupHoverListenerForButton(mLeftButton, DIRECTION_LEFT);
+        setupHoverListenerForButton(mRightButton, DIRECTION_RIGHT);
+        setupHoverListenerForButton(mDownButton, DIRECTION_DOWN);
+        setupHoverListenerForButton(mExitButton, DIRECTION_EXIT);
     }
 
     /**
@@ -142,14 +136,37 @@
     }
 
     /**
-     * Sets up a hover listener for a direction button.
+     * Sets up a hover listener for a button.
      */
-    private void setupHoverListenerForDirectionButton(ImageButton button,
-            @ScrollDirection int direction) {
+    private void setupHoverListenerForButton(ImageButton button, @ScrollDirection int direction) {
         button.setOnHoverListener((v, event) -> {
-            if (mScrollPanelController != null) {
-                mScrollPanelController.handleScroll(direction);
+            if (mScrollPanelController == null) {
+                return true;
             }
+
+            boolean hovered;
+            switch (event.getAction()) {
+                case MotionEvent.ACTION_HOVER_ENTER:
+                    hovered = true;
+                    break;
+                case MotionEvent.ACTION_HOVER_MOVE:
+                    // For direction buttons, continuously trigger scroll on hover move.
+                    if (direction != DIRECTION_EXIT) {
+                        hovered = true;
+                    } else {
+                        // Ignore hover move events for exit button.
+                        return true;
+                    }
+                    break;
+                case MotionEvent.ACTION_HOVER_EXIT:
+                    hovered = false;
+                    break;
+                default:
+                    return true;
+            }
+
+            // Notify the controller about the hover change.
+            mScrollPanelController.onHoverButtonChange(direction, hovered);
             return true;
         });
     }
diff --git a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
index 5a484d4..c29829f 100644
--- a/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
+++ b/services/accessibility/java/com/android/server/accessibility/autoclick/AutoclickTypePanel.java
@@ -576,7 +576,7 @@
     private WindowManager.LayoutParams getDefaultLayoutParams() {
         final WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams();
         layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
-        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
+        layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
         layoutParams.privateFlags |= WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
         layoutParams.setFitInsetsTypes(WindowInsets.Type.statusBars());
         layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
diff --git a/services/companion/java/com/android/server/companion/virtual/SensorController.java b/services/companion/java/com/android/server/companion/virtual/SensorController.java
index 88b7910..6e098d01 100644
--- a/services/companion/java/com/android/server/companion/virtual/SensorController.java
+++ b/services/companion/java/com/android/server/companion/virtual/SensorController.java
@@ -21,15 +21,18 @@
 import android.companion.virtual.IVirtualDevice;
 import android.companion.virtual.sensor.IVirtualSensorCallback;
 import android.companion.virtual.sensor.VirtualSensor;
+import android.companion.virtual.sensor.VirtualSensorAdditionalInfo;
 import android.companion.virtual.sensor.VirtualSensorConfig;
 import android.companion.virtual.sensor.VirtualSensorEvent;
 import android.content.AttributionSource;
+import android.hardware.SensorAdditionalInfo;
 import android.hardware.SensorDirectChannel;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.SharedMemory;
+import android.os.SystemClock;
 import android.util.ArrayMap;
 import android.util.Slog;
 import android.util.SparseArray;
@@ -140,7 +143,7 @@
         final IBinder sensorToken =
                 new Binder("android.hardware.sensor.VirtualSensor:" + config.getName());
         VirtualSensor sensor = new VirtualSensor(handle, config.getType(), config.getName(),
-                virtualDevice, sensorToken);
+                config.getFlags(), virtualDevice, sensorToken);
         synchronized (mLock) {
             mSensorDescriptors.put(sensorToken, sensorDescriptor);
             mVirtualSensors.put(handle, sensor);
@@ -164,6 +167,37 @@
         }
     }
 
+    boolean sendSensorAdditionalInfo(@NonNull IBinder token,
+            @NonNull VirtualSensorAdditionalInfo info) {
+        Objects.requireNonNull(token);
+        Objects.requireNonNull(info);
+        synchronized (mLock) {
+            final SensorDescriptor sensorDescriptor = mSensorDescriptors.get(token);
+            long timestamp = SystemClock.elapsedRealtimeNanos();
+            if (sensorDescriptor == null) {
+                throw new IllegalArgumentException("Could not send sensor event for given token");
+            }
+            if (!mSensorManagerInternal.sendSensorAdditionalInfo(
+                    sensorDescriptor.getHandle(), SensorAdditionalInfo.TYPE_FRAME_BEGIN,
+                    /* serial= */ 0, timestamp++, /* values= */ null)) {
+                return false;
+            }
+            for (int i = 0; i < info.getValues().size(); ++i) {
+                if (!mSensorManagerInternal.sendSensorAdditionalInfo(
+                        sensorDescriptor.getHandle(), info.getType(), /* serial= */ i,
+                        timestamp++, info.getValues().get(i))) {
+                    return false;
+                }
+            }
+            if (!mSensorManagerInternal.sendSensorAdditionalInfo(
+                    sensorDescriptor.getHandle(), SensorAdditionalInfo.TYPE_FRAME_END,
+                    /* serial= */ 0, timestamp, /* values= */ null)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
     @Nullable
     VirtualSensor getSensorByHandle(int handle) {
         synchronized (mLock) {
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
index 28efdfc..0023b6d 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceImpl.java
@@ -55,6 +55,7 @@
 import android.companion.virtual.audio.IAudioRoutingCallback;
 import android.companion.virtual.camera.VirtualCameraConfig;
 import android.companion.virtual.sensor.VirtualSensor;
+import android.companion.virtual.sensor.VirtualSensorAdditionalInfo;
 import android.companion.virtual.sensor.VirtualSensorEvent;
 import android.companion.virtualdevice.flags.Flags;
 import android.compat.annotation.ChangeId;
@@ -1294,6 +1295,18 @@
     }
 
     @Override // Binder call
+    public boolean sendSensorAdditionalInfo(@NonNull IBinder token,
+            @NonNull VirtualSensorAdditionalInfo info) {
+        checkCallerIsDeviceOwner();
+        final long ident = Binder.clearCallingIdentity();
+        try {
+            return mSensorController.sendSensorAdditionalInfo(token, info);
+        } finally {
+            Binder.restoreCallingIdentity(ident);
+        }
+    }
+
+    @Override // Binder call
     public void registerIntentInterceptor(IVirtualDeviceIntentInterceptor intentInterceptor,
             IntentFilter filter) {
         checkCallerIsDeviceOwner();
diff --git a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
index 7eb7072..a1d39fa 100644
--- a/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
+++ b/services/contextualsearch/java/com/android/server/contextualsearch/ContextualSearchManagerService.java
@@ -313,7 +313,8 @@
             android.Manifest.permission.CREATE_USERS,
             android.Manifest.permission.QUERY_USERS
     })
-    private Intent getContextualSearchIntent(int entrypoint, int userId, CallbackToken mToken) {
+    private Intent getContextualSearchIntent(int entrypoint, int userId, String callingPackage,
+            CallbackToken mToken) {
         final Intent launchIntent = getResolvedLaunchIntent(userId);
         if (launchIntent == null) {
             if (DEBUG) Log.w(TAG, "Failed getContextualSearchIntent: launchIntent is null");
@@ -332,6 +333,9 @@
             launchIntent.putExtra(ContextualSearchManager.EXTRA_IS_AUDIO_PLAYING,
                     mAudioManager.isMusicActive());
         }
+        if (Flags.selfInvocation()) {
+            launchIntent.putExtra(Intent.EXTRA_CALLING_PACKAGE, callingPackage);
+        }
         boolean isAssistDataAllowed = mAtmInternal.isAssistDataAllowed();
         final List<ActivityAssistInfo> records = mAtmInternal.getTopVisibleActivities();
         final List<IBinder> activityTokens = new ArrayList<>(records.size());
@@ -500,6 +504,7 @@
         }
 
         private void startContextualSearchInternal(int entrypoint) {
+            final String callingPackage = mPackageManager.getNameForUid(Binder.getCallingUid());
             final int callingUserId = Binder.getCallingUserHandle().getIdentifier();
             mAssistDataRequester.cancel();
             // Creates a new CallbackToken at mToken and an expiration handler.
@@ -508,7 +513,8 @@
             // server has READ_FRAME_BUFFER permission to get the screenshot and because only
             // the system server can invoke non-exported activities.
             Binder.withCleanCallingIdentity(() -> {
-                Intent launchIntent = getContextualSearchIntent(entrypoint, callingUserId, mToken);
+                Intent launchIntent = getContextualSearchIntent(entrypoint, callingUserId,
+                            callingPackage, mToken);
                 if (launchIntent != null) {
                     int result = invokeContextualSearchIntent(launchIntent, callingUserId);
                     if (DEBUG) {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index b75b7ddf..76dd6a5 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -2816,10 +2816,11 @@
         if (!checkNotifyPermission("notifyEmergencyNumberList()")) {
             return;
         }
-        if (!mContext.getPackageManager().hasSystemFeature(
-                PackageManager.FEATURE_TELEPHONY_CALLING)) {
+        if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+                && !mContext.getPackageManager()
+                        .hasSystemFeature(PackageManager.FEATURE_TELEPHONY_MESSAGING)) {
             // TelephonyManager.getEmergencyNumberList() throws an exception if
-            // FEATURE_TELEPHONY_CALLING is not defined.
+            // FEATURE_TELEPHONY_CALLING or FEATURE_TELEPHONY_MESSAGING is not defined.
             return;
         }
 
diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
index 658ea4c..193d827 100644
--- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java
+++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java
@@ -168,7 +168,6 @@
     private AdbConnectionInfo mAdbConnectionInfo = new AdbConnectionInfo();
     // Polls for a tls port property when adb wifi is enabled
     private AdbConnectionPortPoller mConnectionPortPoller;
-    private final PortListenerImpl mPortListener = new PortListenerImpl();
     private final Ticker mTicker;
 
     public AdbDebuggingManager(Context context) {
@@ -323,10 +322,6 @@
         }
     }
 
-    interface AdbConnectionPortListener {
-        void onPortReceived(int port);
-    }
-
     /**
      * This class will poll for a period of time for adbd to write the port
      * it connected to.
@@ -336,16 +331,11 @@
      * port through different means. A better fix would be to always start AdbDebuggingManager, but
      * it needs to adjust accordingly on whether ro.adb.secure is set.
      */
-    static class AdbConnectionPortPoller extends Thread {
+    private class AdbConnectionPortPoller extends Thread {
         private final String mAdbPortProp = "service.adb.tls.port";
-        private AdbConnectionPortListener mListener;
         private final int mDurationSecs = 10;
         private AtomicBoolean mCanceled = new AtomicBoolean(false);
 
-        AdbConnectionPortPoller(AdbConnectionPortListener listener) {
-            mListener = listener;
-        }
-
         @Override
         public void run() {
             Slog.d(TAG, "Starting adb port property poller");
@@ -362,13 +352,22 @@
                 // to start the server. Otherwise we should have a valid port.
                 int port = SystemProperties.getInt(mAdbPortProp, Integer.MAX_VALUE);
                 if (port == -1 || (port > 0 && port <= 65535)) {
-                    mListener.onPortReceived(port);
+                    onPortReceived(port);
                     return;
                 }
                 SystemClock.sleep(1000);
             }
             Slog.w(TAG, "Failed to receive adb connection port");
-            mListener.onPortReceived(-1);
+            onPortReceived(-1);
+        }
+
+        private void onPortReceived(int port) {
+            Slog.d(TAG, "Received tls port=" + port);
+            Message msg = mHandler.obtainMessage(port > 0
+                    ? AdbDebuggingHandler.MSG_SERVER_CONNECTED
+                    : AdbDebuggingHandler.MSG_SERVER_DISCONNECTED);
+            msg.obj = port;
+            mHandler.sendMessage(msg);
         }
 
         public void cancelAndWait() {
@@ -382,17 +381,6 @@
         }
     }
 
-    class PortListenerImpl implements AdbConnectionPortListener {
-        public void onPortReceived(int port) {
-            Slog.d(TAG, "Received tls port=" + port);
-            Message msg = mHandler.obtainMessage(port > 0
-                     ? AdbDebuggingHandler.MSG_SERVER_CONNECTED
-                     : AdbDebuggingHandler.MSG_SERVER_DISCONNECTED);
-            msg.obj = port;
-            mHandler.sendMessage(msg);
-        }
-    }
-
     @VisibleForTesting
     static class AdbDebuggingThread extends Thread {
         private boolean mStopped;
@@ -800,7 +788,6 @@
 
         // === Messages we can send to adbd ===========
         static final String MSG_DISCONNECT_DEVICE = "DD";
-        static final String MSG_DISABLE_ADBDWIFI = "DA";
 
         @Nullable @VisibleForTesting AdbKeyStore mAdbKeyStore;
 
@@ -1088,8 +1075,7 @@
                     mContext.registerReceiver(mBroadcastReceiver, intentFilter);
 
                     SystemProperties.set(AdbService.WIFI_PERSISTENT_CONFIG_PROPERTY, "1");
-                    mConnectionPortPoller =
-                            new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener);
+                    mConnectionPortPoller = new AdbDebuggingManager.AdbConnectionPortPoller();
                     mConnectionPortPoller.start();
 
                     startAdbDebuggingThread();
@@ -1106,9 +1092,6 @@
                     setAdbConnectionInfo(null);
                     mContext.unregisterReceiver(mBroadcastReceiver);
 
-                    if (mThread != null) {
-                        mThread.sendResponse(MSG_DISABLE_ADBDWIFI);
-                    }
                     onAdbdWifiServerDisconnected(-1);
                     stopAdbDebuggingThread();
                     break;
@@ -1138,8 +1121,7 @@
                     mContext.registerReceiver(mBroadcastReceiver, intentFilter);
 
                     SystemProperties.set(AdbService.WIFI_PERSISTENT_CONFIG_PROPERTY, "1");
-                    mConnectionPortPoller =
-                            new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener);
+                    mConnectionPortPoller = new AdbDebuggingManager.AdbConnectionPortPoller();
                     mConnectionPortPoller.start();
 
                     startAdbDebuggingThread();
@@ -1257,7 +1239,7 @@
                     if (mAdbWifiEnabled) {
                         // In scenarios where adbd is restarted, the tls port may change.
                         mConnectionPortPoller =
-                                new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener);
+                                new AdbDebuggingManager.AdbConnectionPortPoller();
                         mConnectionPortPoller.start();
                     }
                     break;
diff --git a/services/core/java/com/android/server/adb/AdbService.java b/services/core/java/com/android/server/adb/AdbService.java
index 40f7c87..d12a0a2 100644
--- a/services/core/java/com/android/server/adb/AdbService.java
+++ b/services/core/java/com/android/server/adb/AdbService.java
@@ -21,10 +21,8 @@
 import android.annotation.UserIdInt;
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.Intent;
 import android.content.pm.PackageManager;
 import android.database.ContentObserver;
-import android.debug.AdbManager;
 import android.debug.AdbManagerInternal;
 import android.debug.AdbTransportType;
 import android.debug.FingerprintAndPairDevice;
@@ -40,10 +38,8 @@
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
 import android.os.SystemProperties;
-import android.os.UserHandle;
 import android.provider.Settings;
 import android.service.adb.AdbServiceDumpProto;
-import android.sysprop.AdbProperties;
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Slog;
@@ -63,7 +59,6 @@
 import java.io.PrintWriter;
 import java.util.Collections;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * The Android Debug Bridge (ADB) service. This controls the availability of ADB and authorization
@@ -85,12 +80,6 @@
      */
     static final String CTL_STOP = "ctl.stop";
 
-    // The tcp port adb is currently using
-    AtomicInteger mConnectionPort = new AtomicInteger(-1);
-
-    private final AdbConnectionPortListener mPortListener = new AdbConnectionPortListener();
-    private AdbDebuggingManager.AdbConnectionPortPoller mConnectionPortPoller;
-
     private final RemoteCallbackList<IAdbCallback> mCallbacks = new RemoteCallbackList<>();
     /**
      * Manages the service lifecycle for {@code AdbService} in {@code SystemServer}.
@@ -404,39 +393,6 @@
         Slog.d(TAG, "Unregistering callback " + callback);
         mCallbacks.unregister(callback);
     }
-    /**
-     * This listener is only used when ro.adb.secure=0. Otherwise, AdbDebuggingManager will
-     * do this.
-     */
-    class AdbConnectionPortListener implements AdbDebuggingManager.AdbConnectionPortListener {
-        public void onPortReceived(int port) {
-            if (port > 0 && port <= 65535) {
-                mConnectionPort.set(port);
-            } else {
-                mConnectionPort.set(-1);
-                // Turn off wifi debugging, since the server did not start.
-                try {
-                    Settings.Global.putInt(mContentResolver,
-                            Settings.Global.ADB_WIFI_ENABLED, 0);
-                } catch (SecurityException e) {
-                    // If UserManager.DISALLOW_DEBUGGING_FEATURES is on, that this setting can't
-                    // be changed.
-                    Slog.d(TAG, "ADB_ENABLED is restricted.");
-                }
-            }
-            broadcastPortInfo(mConnectionPort.get());
-        }
-    }
-
-    private void broadcastPortInfo(int port) {
-        Intent intent = new Intent(AdbManager.WIRELESS_DEBUG_STATE_CHANGED_ACTION);
-        intent.putExtra(AdbManager.WIRELESS_STATUS_EXTRA, (port >= 0)
-                ? AdbManager.WIRELESS_STATUS_CONNECTED
-                : AdbManager.WIRELESS_STATUS_DISCONNECTED);
-        intent.putExtra(AdbManager.WIRELESS_DEBUG_PORT_EXTRA, port);
-        AdbDebuggingManager.sendBroadcastWithDebugPermission(mContext, intent, UserHandle.ALL);
-        Slog.i(TAG, "sent port broadcast port=" + port);
-    }
 
     private void startAdbd() {
         SystemProperties.set(CTL_START, ADBD);
@@ -470,20 +426,11 @@
         } else if (transportType == AdbTransportType.WIFI && enable != mIsAdbWifiEnabled) {
             mIsAdbWifiEnabled = enable;
             if (mIsAdbWifiEnabled) {
-                if (!AdbProperties.secure().orElse(false)) {
-                    // Start adbd. If this is secure adb, then we defer enabling adb over WiFi.
-                    SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1");
-                    mConnectionPortPoller =
-                            new AdbDebuggingManager.AdbConnectionPortPoller(mPortListener);
-                    mConnectionPortPoller.start();
-                }
+                // Start adb over WiFi.
+                SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "1");
             } else {
                 // Stop adb over WiFi.
                 SystemProperties.set(WIFI_PERSISTENT_CONFIG_PROPERTY, "0");
-                if (mConnectionPortPoller != null) {
-                    mConnectionPortPoller.cancelAndWait();
-                    mConnectionPortPoller = null;
-                }
             }
         } else {
             // No change
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 76ba005..59c5e0e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -137,6 +137,7 @@
 import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
 import static android.view.Display.INVALID_DISPLAY;
 
+import static com.android.internal.util.FrameworkStatsLog.EXTRA_INTENT_KEYS_COLLECTED_ON_SERVER;
 import static com.android.internal.util.FrameworkStatsLog.INTENT_CREATOR_TOKEN_ADDED;
 import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NEW_MUTABLE_IMPLICIT_PENDING_INTENT_RETRIEVED;
 import static com.android.sdksandbox.flags.Flags.sdkSandboxInstrumentationInfo;
@@ -2004,7 +2005,7 @@
                 new IAppOpsCallback.Stub() {
                     @Override public void opChanged(int op, int uid, String packageName,
                             String persistentDeviceId) {
-                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
+                        if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && uid >= 0) {
                             if (getAppOpsManager().checkOpNoThrow(op, uid, packageName)
                                     != AppOpsManager.MODE_ALLOWED) {
                                 runInBackgroundDisabled(uid);
@@ -19415,12 +19416,14 @@
         if (!preventIntentRedirect()) return;
         if (intent == null) return;
 
+        int callingUid = Binder.getCallingUid();
         if (((intent.getExtendedFlags() & Intent.EXTENDED_FLAG_NESTED_INTENT_KEYS_COLLECTED) == 0)
                 && intent.getExtras() != null && intent.getExtras().hasIntent()) {
             Slog.wtf(TAG,
                     "[IntentRedirect Hardening] The intent does not have its nested keys collected as a "
                             + "preparation for creating intent creator tokens. Intent: "
                             + intent + "; creatorPackage: " + creatorPackage);
+            FrameworkStatsLog.write(EXTRA_INTENT_KEYS_COLLECTED_ON_SERVER, callingUid);
             if (preventIntentRedirectShowToastIfNestedKeysNotCollectedRW()) {
                 UiThread.getHandler().post(
                         () -> Toast.makeText(mContext,
@@ -19447,7 +19450,7 @@
                 targetPackage);
         final boolean noExtraIntentKeys =
                 intent.getExtraIntentKeys() == null || intent.getExtraIntentKeys().isEmpty();
-        final int creatorUid = noExtraIntentKeys ? DEFAULT_INTENT_CREATOR_UID : Binder.getCallingUid();
+        final int creatorUid = noExtraIntentKeys ? DEFAULT_INTENT_CREATOR_UID : callingUid;
 
         intent.forEachNestedCreatorToken(extraIntent -> {
             if (isCreatorSameAsTarget) {
diff --git a/services/core/java/com/android/server/am/AppPermissionTracker.java b/services/core/java/com/android/server/am/AppPermissionTracker.java
index a47beae..800e2b2 100644
--- a/services/core/java/com/android/server/am/AppPermissionTracker.java
+++ b/services/core/java/com/android/server/am/AppPermissionTracker.java
@@ -394,6 +394,7 @@
     private class MyAppOpsCallback extends IAppOpsCallback.Stub {
         @Override
         public void opChanged(int op, int uid, String packageName, String persistentDeviceId) {
+            if (uid < 0) return;
             mHandler.obtainMessage(MyHandler.MSG_APPOPS_CHANGED, op, uid, packageName)
                     .sendToTarget();
         }
diff --git a/services/core/java/com/android/server/am/AppStartInfoTracker.java b/services/core/java/com/android/server/am/AppStartInfoTracker.java
index 517279b..8b3eb48 100644
--- a/services/core/java/com/android/server/am/AppStartInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppStartInfoTracker.java
@@ -98,6 +98,9 @@
 
     @VisibleForTesting static final int APP_START_INFO_HISTORY_LIST_SIZE = 16;
 
+    @VisibleForTesting
+    static final long APP_START_INFO_HISTORY_LENGTH_MS = TimeUnit.DAYS.toMillis(14);
+
     /**
      * The max number of records that can be present in {@link mInProgressRecords}.
      *
@@ -120,9 +123,13 @@
      * Monotonic clock which does not reset on reboot.
      *
      * Time for offset is persisted along with records, see {@link #persistProcessStartInfo}.
-     * This does not follow the recommendation of {@link MonotonicClock} to persist on shutdown as
-     * it's ok in this case to lose any time change past the last persist as records added since
-     * then will be lost as well and the purpose of this clock is to keep records in order.
+     * This does not currently follow the recommendation of {@link MonotonicClock} to persist on
+     * shutdown as it's ok in this case to lose any time change past the last persist as records
+     * added since then will be lost as well. Since this time is used for cleanup as well, the
+     * potential old offset may result in the cleanup window being extended slightly beyond the
+     * targeted 14 days.
+     *
+     * TODO: b/402794215 - Persist on shutdown once persist performance is sufficiently improved.
      */
     @VisibleForTesting MonotonicClock mMonotonicClock = null;
 
@@ -296,7 +303,7 @@
             if (!mEnabled) {
                 return;
             }
-            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
             start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
             start.setIntent(intent);
             start.setStartType(ApplicationStartInfo.START_TYPE_UNSET);
@@ -454,7 +461,7 @@
             if (!mEnabled) {
                 return;
             }
-            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
             addBaseFieldsFromProcessRecord(start, app);
             start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
             start.addStartupTimestamp(
@@ -484,7 +491,7 @@
             if (!mEnabled) {
                 return;
             }
-            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
             addBaseFieldsFromProcessRecord(start, app);
             start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
             start.addStartupTimestamp(
@@ -511,7 +518,7 @@
             if (!mEnabled) {
                 return;
             }
-            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
             addBaseFieldsFromProcessRecord(start, app);
             start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
             start.addStartupTimestamp(
@@ -533,7 +540,7 @@
             if (!mEnabled) {
                 return;
             }
-            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTime());
+            ApplicationStartInfo start = new ApplicationStartInfo(getMonotonicTimeMs());
             addBaseFieldsFromProcessRecord(start, app);
             start.setStartupState(ApplicationStartInfo.STARTUP_STATE_STARTED);
             start.addStartupTimestamp(
@@ -721,8 +728,8 @@
 
                     Collections.sort(
                             list, (a, b) ->
-                            Long.compare(b.getMonoticCreationTimeMs(),
-                                    a.getMonoticCreationTimeMs()));
+                            Long.compare(b.getMonotonicCreationTimeMs(),
+                                    a.getMonotonicCreationTimeMs()));
                     int size = list.size();
                     if (maxNum > 0) {
                         size = Math.min(size, maxNum);
@@ -1098,7 +1105,7 @@
                     mLastAppStartInfoPersistTimestamp = now;
                 }
             }
-            proto.write(AppsStartInfoProto.MONOTONIC_TIME, getMonotonicTime());
+            proto.write(AppsStartInfoProto.MONOTONIC_TIME, getMonotonicTimeMs());
             if (succeeded) {
                 proto.flush();
                 af.finishWrite(out);
@@ -1219,7 +1226,11 @@
         }
     }
 
-    private long getMonotonicTime() {
+    /**
+     * Monotonic time that doesn't change with reboot or device time change for ordering records.
+     */
+    @VisibleForTesting
+    public long getMonotonicTimeMs() {
         if (mMonotonicClock == null) {
             // This should never happen. Return 0 to not interfere with past or future records.
             return 0;
@@ -1229,7 +1240,7 @@
 
     /** A container class of (@link android.app.ApplicationStartInfo) */
     final class AppStartInfoContainer {
-        private ArrayList<ApplicationStartInfo> mInfos; // Always kept sorted by first timestamp.
+        private ArrayList<ApplicationStartInfo> mInfos; // Always kept sorted by monotonic time.
         private int mMaxCapacity;
         private int mUid;
         private boolean mMonitoringModeEnabled = false;
@@ -1260,9 +1271,12 @@
                 return;
             }
 
-            // Sort records so we can remove the least recent ones.
-            Collections.sort(mInfos, (a, b) ->
-                    Long.compare(b.getMonoticCreationTimeMs(), a.getMonoticCreationTimeMs()));
+            if (!android.app.Flags.appStartInfoKeepRecordsSorted()) {
+                // Sort records so we can remove the least recent ones.
+                Collections.sort(mInfos, (a, b) ->
+                        Long.compare(b.getMonotonicCreationTimeMs(),
+                                a.getMonotonicCreationTimeMs()));
+            }
 
             // Remove records and trim list object back to size.
             mInfos.subList(0, mInfos.size() - getMaxCapacity()).clear();
@@ -1277,25 +1291,34 @@
 
         @GuardedBy("mLock")
         void addStartInfoLocked(ApplicationStartInfo info) {
-            int size = mInfos.size();
-            if (size >= getMaxCapacity()) {
-                // Remove oldest record if size is over max capacity.
-                int oldestIndex = -1;
-                long oldestTimeStamp = Long.MAX_VALUE;
-                for (int i = 0; i < size; i++) {
-                    ApplicationStartInfo startInfo = mInfos.get(i);
-                    if (startInfo.getMonoticCreationTimeMs() < oldestTimeStamp) {
-                        oldestTimeStamp = startInfo.getMonoticCreationTimeMs();
-                        oldestIndex = i;
+            if (android.app.Flags.appStartInfoKeepRecordsSorted()) {
+                while (mInfos.size() >= getMaxCapacity()) {
+                    // Expected to execute at most once.
+                    mInfos.removeLast();
+                }
+                mInfos.addFirst(info);
+            } else {
+                int size = mInfos.size();
+                if (size >= getMaxCapacity()) {
+                    // Remove oldest record if size is over max capacity.
+                    int oldestIndex = -1;
+                    long oldestTimeStamp = Long.MAX_VALUE;
+                    for (int i = 0; i < size; i++) {
+                        ApplicationStartInfo startInfo = mInfos.get(i);
+                        if (startInfo.getMonotonicCreationTimeMs() < oldestTimeStamp) {
+                            oldestTimeStamp = startInfo.getMonotonicCreationTimeMs();
+                            oldestIndex = i;
+                        }
+                    }
+                    if (oldestIndex >= 0) {
+                        mInfos.remove(oldestIndex);
                     }
                 }
-                if (oldestIndex >= 0) {
-                    mInfos.remove(oldestIndex);
-                }
+                mInfos.add(info);
+                Collections.sort(mInfos, (a, b) ->
+                        Long.compare(b.getMonotonicCreationTimeMs(),
+                                a.getMonotonicCreationTimeMs()));
             }
-            mInfos.add(info);
-            Collections.sort(mInfos, (a, b) ->
-                    Long.compare(b.getMonoticCreationTimeMs(), a.getMonoticCreationTimeMs()));
         }
 
         /**
@@ -1439,9 +1462,25 @@
             long token = proto.start(fieldId);
             proto.write(AppsStartInfoProto.Package.User.UID, mUid);
             int size = mInfos.size();
-            for (int i = 0; i < size; i++) {
-                mInfos.get(i).writeToProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO,
-                        byteArrayOutputStream, objectOutputStream, typedXmlSerializer);
+            if (android.app.Flags.appStartInfoCleanupOldRecords()) {
+                long removeOlderThan = getMonotonicTimeMs() - APP_START_INFO_HISTORY_LENGTH_MS;
+                // Iterate backwards so we can remove old records as we go.
+                for (int i = size - 1; i >= 0; i--) {
+                    if (mInfos.get(i).getMonotonicCreationTimeMs() < removeOlderThan) {
+                        // Remove the record.
+                        mInfos.remove(i);
+                    } else {
+                        mInfos.get(i).writeToProto(
+                                proto, AppsStartInfoProto.Package.User.APP_START_INFO,
+                                byteArrayOutputStream, objectOutputStream, typedXmlSerializer);
+                    }
+                }
+            } else {
+                for (int i = 0; i < size; i++) {
+                    mInfos.get(i).writeToProto(
+                            proto, AppsStartInfoProto.Package.User.APP_START_INFO,
+                            byteArrayOutputStream, objectOutputStream, typedXmlSerializer);
+                }
             }
             proto.write(AppsStartInfoProto.Package.User.MONITORING_ENABLED, mMonitoringModeEnabled);
             proto.end(token);
@@ -1466,7 +1505,13 @@
                         info.readFromProto(proto, AppsStartInfoProto.Package.User.APP_START_INFO,
                                 byteArrayInputStream, objectInputStream, typedXmlPullParser);
                         info.setPackageName(packageName);
-                        mInfos.add(info);
+                        if (android.app.Flags.appStartInfoKeepRecordsSorted()) {
+                            // Since the writes are done from oldest to newest, each additional
+                            // record will be newer than the previous so use addFirst.
+                            mInfos.addFirst(info);
+                        } else {
+                            mInfos.add(info);
+                        }
                         break;
                     case (int) AppsStartInfoProto.Package.User.MONITORING_ENABLED:
                         mMonitoringModeEnabled = proto.readBoolean(
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index fa35da3..115ae41 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -2643,7 +2643,7 @@
         }
 
         capability |= getDefaultCapability(app, procState);
-        capability |= getCpuCapability(app, now);
+        capability |= getCpuCapability(app, now, foregroundActivities);
 
         // Procstates below BFGS should never have this capability.
         if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
@@ -3422,15 +3422,18 @@
         return baseCapabilities | networkCapabilities;
     }
 
-    private static int getCpuCapability(ProcessRecord app, long nowUptime) {
+    private static int getCpuCapability(ProcessRecord app, long nowUptime,
+            boolean hasForegroundActivities) {
         // Note: persistent processes get all capabilities, including CPU_TIME.
         final UidRecord uidRec = app.getUidRecord();
         if (uidRec != null && uidRec.isCurAllowListed()) {
             // Process is in the power allowlist.
             return PROCESS_CAPABILITY_CPU_TIME;
         }
-        if (app.mState.getCachedHasVisibleActivities()) {
-            // Process has user visible activities.
+        if (hasForegroundActivities) {
+            // TODO: b/402987519 - This grants the Top Sleeping process CPU_TIME but eventually
+            //  should not.
+            // Process has user perceptible activities.
             return PROCESS_CAPABILITY_CPU_TIME;
         }
         if (Flags.prototypeAggressiveFreezing()) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index fb33cb1..5ecac22 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -182,6 +182,7 @@
 import com.android.server.companion.virtual.VirtualDeviceManagerInternal;
 import com.android.server.pm.PackageList;
 import com.android.server.pm.PackageManagerLocal;
+import com.android.server.pm.ProtectedPackages;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.pm.pkg.AndroidPackage;
 import com.android.server.pm.pkg.PackageState;
@@ -311,6 +312,8 @@
     private final IPlatformCompat mPlatformCompat = IPlatformCompat.Stub.asInterface(
             ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
 
+    private ProtectedPackages mProtectedPackages;
+
     /**
      * Registered callbacks, called from {@link #collectAsyncNotedOp}.
      *
@@ -822,7 +825,8 @@
         @Override
         public void onOpModeChanged(int op, int uid, String packageName, String persistentDeviceId)
                 throws RemoteException {
-            mCallback.opChanged(op, uid, packageName, persistentDeviceId);
+            mCallback.opChanged(op, uid, packageName != null ? packageName : "",
+                    Objects.requireNonNull(persistentDeviceId));
         }
     }
 
@@ -1059,7 +1063,7 @@
         if (Flags.enableAllSqliteAppopsAccesses()) {
             mHistoricalRegistry = new HistoricalRegistrySql(context);
         } else {
-            mHistoricalRegistry = new HistoricalRegistry(this, context);
+            mHistoricalRegistry = new LegacyHistoricalRegistry(this, context);
         }
     }
 
@@ -2127,6 +2131,12 @@
 
         enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
         verifyIncomingOp(code);
+
+        if (isDeviceProvisioningPackage(uid, null)) {
+            Slog.w(TAG, "Cannot set uid mode for device provisioning app by Shell");
+            return;
+        }
+
         code = AppOpsManager.opToSwitch(code);
 
         if (permissionPolicyCallback == null) {
@@ -2437,6 +2447,11 @@
             return;
         }
 
+        if (isDeviceProvisioningPackage(uid, packageName)) {
+            Slog.w(TAG, "Cannot set op mode for device provisioning app by Shell");
+            return;
+        }
+
         code = AppOpsManager.opToSwitch(code);
 
         PackageVerificationResult pvr;
@@ -2467,6 +2482,36 @@
         notifyStorageManagerOpModeChangedSync(code, uid, packageName, mode, previousMode);
     }
 
+    // Device provisioning package is restricted from setting app op mode through shell command
+    private boolean isDeviceProvisioningPackage(int uid,
+            @Nullable String packageName) {
+        if (UserHandle.getAppId(Binder.getCallingUid()) == Process.SHELL_UID) {
+            ProtectedPackages protectedPackages = getProtectedPackages();
+
+            if (packageName != null && protectedPackages.isDeviceProvisioningPackage(packageName)) {
+                return true;
+            }
+
+            String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
+            if (packageNames != null) {
+                for (String pkg : packageNames) {
+                    if (protectedPackages.isDeviceProvisioningPackage(pkg)) {
+                        return true;
+                    }
+                }
+            }
+        }
+        return false;
+    }
+
+    // Race condition is allowed here for better performance
+    private ProtectedPackages getProtectedPackages() {
+        if (mProtectedPackages == null) {
+            mProtectedPackages = new ProtectedPackages(mContext);
+        }
+        return mProtectedPackages;
+    }
+
     private void notifyOpChanged(ArraySet<OnOpModeChangedListener> callbacks, int code,
             int uid, String packageName, String persistentDeviceId) {
         for (int i = 0; i < callbacks.size(); i++) {
@@ -7011,7 +7056,8 @@
             mHistoricalRegistry = new HistoricalRegistrySql(
                     (HistoricalRegistrySql) mHistoricalRegistry);
         } else {
-            mHistoricalRegistry = new HistoricalRegistry((HistoricalRegistry) mHistoricalRegistry);
+            mHistoricalRegistry = new LegacyHistoricalRegistry(
+                    (LegacyHistoricalRegistry) mHistoricalRegistry);
         }
 
         mHistoricalRegistry.systemReady(mContext.getContentResolver());
diff --git a/services/core/java/com/android/server/appop/DiscreteOpsDbHelper.java b/services/core/java/com/android/server/appop/DiscreteOpsDbHelper.java
index c53e4bd..3a8d583 100644
--- a/services/core/java/com/android/server/appop/DiscreteOpsDbHelper.java
+++ b/services/core/java/com/android/server/appop/DiscreteOpsDbHelper.java
@@ -24,6 +24,7 @@
 import android.database.DefaultDatabaseErrorHandler;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteFullException;
 import android.database.sqlite.SQLiteOpenHelper;
 import android.database.sqlite.SQLiteRawStatement;
 import android.os.Environment;
@@ -174,11 +175,16 @@
         if (DEBUG) {
             Slog.i(LOG_TAG, "DB execSQL, sql: " + sql);
         }
-        SQLiteDatabase db = getWritableDatabase();
-        if (bindArgs == null) {
-            db.execSQL(sql);
-        } else {
-            db.execSQL(sql, bindArgs);
+        try {
+            SQLiteDatabase db = getWritableDatabase();
+            if (bindArgs == null) {
+                db.execSQL(sql);
+            } else {
+                db.execSQL(sql, bindArgs);
+            }
+        } catch (SQLiteFullException exception) {
+            Slog.e(LOG_TAG, "Couldn't exec sql command, disk is full. Discrete ops "
+                    + "db file size (bytes) : " + getDatabaseFile().length(), exception);
         }
     }
 
diff --git a/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java b/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java
index 70b7016..3867cbe 100644
--- a/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteOpsRegistry.java
@@ -82,9 +82,8 @@
  * INITIALIZATION: We can initialize persistence only after the system is ready
  * as we need to check the optional configuration override from the settings
  * database which is not initialized at the time the app ops service is created. This class
- * relies on {@link HistoricalRegistry} for controlling that no calls are allowed until then. All
- * outside calls are going through {@link HistoricalRegistry}.
- *
+ * relies on {@link LegacyHistoricalRegistry} for controlling that no calls are allowed until then.
+ * All outside calls are going through {@link LegacyHistoricalRegistry}.
  */
 abstract class DiscreteOpsRegistry {
     private static final String TAG = DiscreteOpsRegistry.class.getSimpleName();
diff --git a/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java b/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java
index 20706b6..771df19 100644
--- a/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteOpsXmlRegistry.java
@@ -81,7 +81,7 @@
  * THREADING AND LOCKING:
  * For in-memory transactions this class relies on {@link DiscreteOpsXmlRegistry#mInMemoryLock}.
  * It is assumed that the same lock is used for in-memory transactions in {@link AppOpsService},
- * {@link HistoricalRegistry}, and {@link DiscreteOpsXmlRegistry }.
+ * {@link LegacyHistoricalRegistry}, and {@link DiscreteOpsXmlRegistry }.
  * {@link DiscreteOpsRegistry#recordDiscreteAccess} must only be called while holding this lock.
  * {@link DiscreteOpsXmlRegistry#mOnDiskLock} is used when disk transactions are performed.
  * It is very important to release {@link DiscreteOpsXmlRegistry#mInMemoryLock} as soon as
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/LegacyHistoricalRegistry.java
similarity index 99%
rename from services/core/java/com/android/server/appop/HistoricalRegistry.java
rename to services/core/java/com/android/server/appop/LegacyHistoricalRegistry.java
index a8128dd..f4f5775 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/LegacyHistoricalRegistry.java
@@ -128,11 +128,11 @@
  */
 // TODO (bug:122218838): Make sure we handle start of epoch time
 // TODO (bug:122218838): Validate changed time is handled correctly
-final class HistoricalRegistry implements HistoricalRegistryInterface {
+final class LegacyHistoricalRegistry implements HistoricalRegistryInterface {
     private static final boolean DEBUG = false;
     private static final boolean KEEP_WTF_LOG = Build.IS_DEBUGGABLE;
 
-    private static final String LOG_TAG = HistoricalRegistry.class.getSimpleName();
+    private static final String LOG_TAG = LegacyHistoricalRegistry.class.getSimpleName();
 
     private static final String PARAMETER_DELIMITER = ",";
     private static final String PARAMETER_ASSIGNMENT = "=";
@@ -200,7 +200,7 @@
 
     private final Context mContext;
 
-    HistoricalRegistry(@NonNull Object lock, Context context) {
+    LegacyHistoricalRegistry(@NonNull Object lock, Context context) {
         mInMemoryLock = lock;
         mContext = context;
         if (Flags.enableSqliteAppopsAccesses()) {
@@ -210,7 +210,7 @@
         }
     }
 
-    HistoricalRegistry(@NonNull HistoricalRegistry other) {
+    LegacyHistoricalRegistry(@NonNull LegacyHistoricalRegistry other) {
         this(other.mInMemoryLock, other.mContext);
         mMode = other.mMode;
         mBaseSnapshotInterval = other.mBaseSnapshotInterval;
@@ -313,9 +313,9 @@
                 final int mode = AppOpsManager.parseHistoricalMode(modeValue);
                 final long baseSnapshotInterval = Long.parseLong(baseSnapshotIntervalValue);
                 final int intervalCompressionMultiplier = Integer.parseInt(intervalMultiplierValue);
-                setHistoryParameters(mode, baseSnapshotInterval,intervalCompressionMultiplier);
+                setHistoryParameters(mode, baseSnapshotInterval, intervalCompressionMultiplier);
                 return;
-            } catch (NumberFormatException ignored) {}
+            } catch (NumberFormatException ignored) { }
         }
         Slog.w(LOG_TAG, "Bad value for" + Settings.Global.APPOP_HISTORY_PARAMETERS
                 + "=" + setting + " resetting!");
@@ -805,7 +805,7 @@
 
     private void schedulePersistHistoricalOpsMLocked(@NonNull HistoricalOps ops) {
         final Message message = PooledLambda.obtainMessage(
-                HistoricalRegistry::persistPendingHistory, HistoricalRegistry.this);
+                LegacyHistoricalRegistry::persistPendingHistory, LegacyHistoricalRegistry.this);
         message.what = MSG_WRITE_PENDING_HISTORY;
         IoThread.getHandler().sendMessage(message);
         mPendingWrites.offerFirst(ops);
@@ -813,7 +813,7 @@
 
     private static void makeRelativeToEpochStart(@NonNull HistoricalOps ops, long nowMillis) {
         ops.setBeginAndEndTime(nowMillis - ops.getEndTimeMillis(),
-                nowMillis- ops.getBeginTimeMillis());
+                nowMillis - ops.getBeginTimeMillis());
     }
 
     private void pruneFutureOps(@NonNull List<HistoricalOps> ops) {
@@ -979,7 +979,7 @@
                     final HistoricalOps readOp = readOps.get(i);
                     currentOps.merge(readOp);
                 }
-             }
+            }
         }
 
         private @Nullable LinkedList<HistoricalOps> collectHistoricalOpsBaseDLocked(int filterUid,
@@ -1125,7 +1125,7 @@
                 if (existingOpCount > 0) {
                     // Compute elapsed time
                     final long elapsedTimeMillis = passedOps.get(passedOps.size() - 1)
-                        .getEndTimeMillis();
+                            .getEndTimeMillis();
                     for (int i = 0; i < existingOpCount; i++) {
                         final HistoricalOps existingOp = existingOps.get(i);
                         existingOp.offsetBeginAndEndTime(elapsedTimeMillis);
diff --git a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
index 7502664..180ef85 100644
--- a/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
+++ b/services/core/java/com/android/server/audio/AudioServerPermissionProvider.java
@@ -39,6 +39,7 @@
 import android.os.UserHandle;
 import android.util.ArraySet;
 import android.util.IntArray;
+import android.util.Log;
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.media.permission.INativePermissionController;
@@ -62,6 +63,8 @@
 /** Responsible for synchronizing system server permission state to the native audioserver. */
 public class AudioServerPermissionProvider {
 
+    static final String TAG = "AudioServerPermissionProvider";
+
     static final String[] MONITORED_PERMS = new String[PermissionEnum.ENUM_SIZE];
 
     static final byte[] HDS_PERMS = new byte[] {PermissionEnum.CAPTURE_AUDIO_HOTWORD,
@@ -219,10 +222,13 @@
     public void setIsolatedServiceUid(int uid, int owningUid) {
         synchronized (mLock) {
             if (mHdsUid == uid) return;
-            var packageNameSet = mPackageMap.get(owningUid);
-            if (packageNameSet == null) return;
-            var packageName = packageNameSet.iterator().next();
-            onModifyPackageState(uid, packageName, /* isRemove= */ false);
+            var packageNameSet = mPackageMap.get(UserHandle.getAppId(owningUid));
+            if (packageNameSet != null) {
+                var packageName = packageNameSet.iterator().next();
+                onModifyPackageState(uid, packageName, /* isRemove= */ false);
+            } else {
+                Log.wtf(TAG, "setIsolatedService owning uid not found");
+            }
             // permissions
             mHdsUid = uid;
             if (mDest == null) {
@@ -249,11 +255,19 @@
 
     public void clearIsolatedServiceUid(int uid) {
         synchronized (mLock) {
-            if (mHdsUid != uid) return;
-            var packageNameSet = mPackageMap.get(uid);
-            if (packageNameSet == null) return;
-            var packageName = packageNameSet.iterator().next();
-            onModifyPackageState(uid, packageName, /* isRemove= */ true);
+            var packageNameSet = mPackageMap.get(UserHandle.getAppId(uid));
+            if (mHdsUid != uid) {
+                Log.wtf(TAG,
+                        "Unexpected isolated service uid cleared: " + uid + packageNameSet
+                                + ", expected " + mHdsUid);
+                return;
+            }
+            if (packageNameSet != null) {
+                var packageName = packageNameSet.iterator().next();
+                onModifyPackageState(uid, packageName, /* isRemove= */ true);
+            } else {
+                Log.wtf(TAG, "clearIsolatedService uid not found");
+            }
             // permissions
             if (mDest == null) {
                 mIsUpdateDeferred = true;
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index d917bff..6b3661a 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -32,7 +32,6 @@
 import static android.Manifest.permission.WRITE_SETTINGS;
 import static android.app.BroadcastOptions.DELIVERY_GROUP_POLICY_MOST_RECENT;
 import static android.content.Intent.ACTION_PACKAGE_ADDED;
-import static android.content.Intent.ACTION_PACKAGE_REMOVED;
 import static android.content.Intent.EXTRA_ARCHIVAL;
 import static android.content.Intent.EXTRA_REPLACING;
 import static android.media.AudioDeviceInfo.TYPE_BLUETOOTH_A2DP;
@@ -930,7 +929,8 @@
     private final Object mAbsoluteVolumeDeviceInfoMapLock = new Object();
     // Devices where the framework sends a full scale audio signal, and controls the volume of
     // the external audio system separately.
-    // For possible volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
+    // For possible volume behaviors, see
+    // {@link AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior}.
     @GuardedBy("mAbsoluteVolumeDeviceInfoMapLock")
     Map<Integer, AbsoluteVolumeDeviceInfo> mAbsoluteVolumeDeviceInfoMap = new ArrayMap<>();
 
@@ -943,7 +943,7 @@
         private final List<VolumeInfo> mVolumeInfos;
         private final IAudioDeviceVolumeDispatcher mCallback;
         private final boolean mHandlesVolumeAdjustment;
-        private @AudioManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
+        private @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int mDeviceVolumeBehavior;
 
         private AbsoluteVolumeDeviceInfo(
                 AudioService parent,
@@ -951,7 +951,7 @@
                 List<VolumeInfo> volumeInfos,
                 IAudioDeviceVolumeDispatcher callback,
                 boolean handlesVolumeAdjustment,
-                @AudioManager.AbsoluteDeviceVolumeBehavior int behavior) {
+                @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int behavior) {
             this.mParent = parent;
             this.mDevice = device;
             this.mVolumeInfos = volumeInfos;
@@ -3336,11 +3336,25 @@
     }
 
     private int rescaleIndex(int index, int srcStream, int dstStream) {
-        return rescaleIndex(index,
-                getVssForStreamOrDefault(srcStream).getMinIndex(),
-                getVssForStreamOrDefault(srcStream).getMaxIndex(),
-                getVssForStreamOrDefault(dstStream).getMinIndex(),
-                getVssForStreamOrDefault(dstStream).getMaxIndex());
+        final VolumeStreamState srcVss = getVssForStreamOrDefault(srcStream);
+        final VolumeStreamState dstVss = getVssForStreamOrDefault(dstStream);
+        int newIndex = rescaleIndex(index, srcVss.getMinIndex(), srcVss.getMaxIndex(),
+                dstVss.getMinIndex(), dstVss.getMaxIndex());
+        // only apply solution for DTMF stream to make sure that it is not muted when
+        // re-aliasing to voice call stream. With ringMyCar flag enabled this will be
+        // automatically solved since we are sending the mute state to APM
+        // TODO(b/402542630): revisit stream aliasing logic with different min index
+        //  values / mute states
+        if (!ringMyCar() && dstStream == AudioSystem.STREAM_DTMF
+                && srcStream == AudioSystem.STREAM_VOICE_CALL
+                && srcVss.getMinIndex() > dstVss.getMinIndex()) {
+            newIndex += srcVss.getMinIndex() - dstVss.getMinIndex();
+            if (newIndex > dstVss.getMaxIndex()) {
+                newIndex = dstVss.getMaxIndex();
+            }
+        }
+
+        return newIndex;
     }
 
     private int rescaleIndex(int index, int srcMin, int srcMax, int dstMin, int dstMax) {
@@ -8160,7 +8174,7 @@
             IAudioDeviceVolumeDispatcher cb, String packageName,
             AudioDeviceAttributes device, List<VolumeInfo> volumes,
             boolean handlesVolumeAdjustment,
-            @AudioManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
+            @AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior int deviceVolumeBehavior) {
         // verify permissions
         if (mContext.checkCallingOrSelfPermission(MODIFY_AUDIO_ROUTING)
                 != PackageManager.PERMISSION_GRANTED
@@ -8227,12 +8241,13 @@
     @android.annotation.EnforcePermission(anyOf = {
             MODIFY_AUDIO_ROUTING, MODIFY_AUDIO_SETTINGS_PRIVILEGED })
     public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
-            @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @Nullable String pkgName) {
+            @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior,
+            @Nullable String pkgName) {
         // verify permissions
         super.setDeviceVolumeBehavior_enforcePermission();
         // verify arguments
         Objects.requireNonNull(device);
-        AudioManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
+        AudioDeviceVolumeManager.enforceValidVolumeBehavior(deviceVolumeBehavior);
 
         device = retrieveBluetoothAddress(device);
 
@@ -8255,7 +8270,8 @@
     }
 
     private void setDeviceVolumeBehaviorInternal(@NonNull AudioDeviceAttributes device,
-            @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior, @NonNull String caller) {
+            @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior,
+            @NonNull String caller) {
         int audioSystemDeviceOut = device.getInternalType();
         boolean volumeBehaviorChanged = false;
         // update device masks based on volume behavior
@@ -8310,7 +8326,7 @@
     @android.annotation.EnforcePermission(anyOf = {
             MODIFY_AUDIO_ROUTING, QUERY_AUDIO_STATE,  MODIFY_AUDIO_SETTINGS_PRIVILEGED
     })
-    public @AudioManager.DeviceVolumeBehavior
+    public @AudioDeviceVolumeManager.DeviceVolumeBehavior
     int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
         // verify permissions
         super.getDeviceVolumeBehavior_enforcePermission();
@@ -8322,7 +8338,7 @@
         return getDeviceVolumeBehaviorInt(device);
     }
 
-    private @AudioManager.DeviceVolumeBehavior
+    private @AudioDeviceVolumeManager.DeviceVolumeBehavior
             int getDeviceVolumeBehaviorInt(@NonNull AudioDeviceAttributes device) {
         // Get the internal type set by the AudioDeviceAttributes constructor which is always more
         // exact (avoids double conversions) than a conversion from SDK type via
@@ -12929,11 +12945,12 @@
                 );
         audioPolicy.registerOnStartTask(() -> {
             provider.onServiceStart(audioPolicy.getPermissionController());
+            sLifecycleLogger.enqueue(new EventLogger.StringEvent(
+                    "Controller start task complete").printLog(ALOGI, TAG));
         });
 
         IntentFilter packageUpdateFilter = new IntentFilter();
         packageUpdateFilter.addAction(ACTION_PACKAGE_ADDED);
-        packageUpdateFilter.addAction(ACTION_PACKAGE_REMOVED);
         packageUpdateFilter.addDataScheme("package");
 
         context.registerReceiverForAllUsers(new BroadcastReceiver() {
@@ -12947,9 +12964,6 @@
                 if (ACTION_PACKAGE_ADDED.equals(action)) {
                     audioserverExecutor.execute(() ->
                             provider.onModifyPackageState(uid, pkgName, false /* isRemoved */));
-                } else if (ACTION_PACKAGE_REMOVED.equals(action)) {
-                    audioserverExecutor.execute(() ->
-                            provider.onModifyPackageState(uid, pkgName, true /* isRemoved */));
                 }
             }
         }, packageUpdateFilter, null, null); // main thread is fine, since dispatch on executor
@@ -15343,7 +15357,8 @@
 
     /**
      * Returns whether the input device uses absolute volume behavior, including its variants.
-     * For included volume behaviors, see {@link AudioManager.AbsoluteDeviceVolumeBehavior}.
+     * For included volume behaviors, see
+     * {@link AudioDeviceVolumeManager.AbsoluteDeviceVolumeBehavior}.
      * <p>This is distinct from Bluetooth A2DP absolute volume behavior
      * ({@link #isA2dpAbsoluteVolumeDevice}).
      */
@@ -15370,7 +15385,7 @@
     }
 
     private void persistDeviceVolumeBehavior(int deviceType,
-            @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
+            @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
         if (DEBUG_VOL) {
             Log.d(TAG, "Persisting Volume Behavior for DeviceType: " + deviceType);
         }
@@ -15385,7 +15400,7 @@
         }
     }
 
-    @AudioManager.DeviceVolumeBehaviorState
+    @AudioDeviceVolumeManager.DeviceVolumeBehaviorState
     private int retrieveStoredDeviceVolumeBehavior(int deviceType) {
         return mSettings.getSystemIntForUser(mContentResolver,
                 getSettingsNameForDeviceVolumeBehavior(deviceType),
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index ac0892b..aa98590 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -1113,7 +1113,11 @@
             }
             // Remove always-on VPN if it's not supported.
             if (!isAlwaysOnPackageSupported(alwaysOnPackage)) {
-                setAlwaysOnPackage(null, false, null);
+                // Do not remove the always-on setting due to the restricted ability in safe mode.
+                // The always-on VPN can then start after the device reboots to normal mode.
+                if (!mContext.getPackageManager().isSafeMode()) {
+                    setAlwaysOnPackage(null, false, null);
+                }
                 return false;
             }
             // Skip if the service is already established. This isn't bulletproof: it's not bound
diff --git a/services/core/java/com/android/server/display/DisplayDeviceInfo.java b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
index 3aaf4f6..7450dff 100644
--- a/services/core/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/core/java/com/android/server/display/DisplayDeviceInfo.java
@@ -122,8 +122,8 @@
     public static final int FLAG_MASK_DISPLAY_CUTOUT = 1 << 11;
 
     /**
-     * Flag: This flag identifies secondary displays that should show system decorations, such as
-     * navigation bar, home activity or wallpaper.
+     * Flag: This flag identifies secondary displays that should always show system decorations,
+     * such as navigation bar, home activity or wallpaper.
      * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p>
      * @hide
      */
@@ -191,6 +191,19 @@
     public static final int FLAG_STEAL_TOP_FOCUS_DISABLED = 1 << 19;
 
     /**
+     * Flag: Indicates that the display is allowed to switch the content mode between
+     * projected/extended and mirroring. This allows the display to dynamically add or remove the
+     * home and system decorations.
+     *
+     * Note that this flag should not be enabled with any of {@link #FLAG_PRIVATE},
+     * {@link #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS}, or {@link #FLAG_OWN_CONTENT_ONLY} at the
+     * same time; otherwise it will be ignored.
+     *
+     * @hide
+     */
+    public static final int FLAG_ALLOWS_CONTENT_MODE_SWITCH = 1 << 20;
+
+    /**
      * Touch attachment: Display does not receive touch.
      */
     public static final int TOUCH_NONE = 0;
diff --git a/services/core/java/com/android/server/display/DisplayGroup.java b/services/core/java/com/android/server/display/DisplayGroup.java
index f73b66c..ce8d8a6 100644
--- a/services/core/java/com/android/server/display/DisplayGroup.java
+++ b/services/core/java/com/android/server/display/DisplayGroup.java
@@ -16,6 +16,8 @@
 
 package com.android.server.display;
 
+import android.util.IndentingPrintWriter;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -97,4 +99,14 @@
         }
         return displayIds;
     }
+
+    /** Dumps information about the DisplayGroup. */
+    void dumpLocked(IndentingPrintWriter ipw) {
+        final int numDisplays = mDisplays.size();
+        for (int i = 0; i < numDisplays; i++) {
+            LogicalDisplay logicalDisplay = mDisplays.get(i);
+            ipw.println("Display " + logicalDisplay.getDisplayIdLocked() + " "
+                    + logicalDisplay.getPrimaryDisplayDeviceLocked());
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 7b714ad..2cad7ed 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -766,7 +766,7 @@
                         mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
                     }
                 } else {
-                    if (!res.getBoolean(R.bool.config_localDisplaysMirrorContent)) {
+                    if (shouldOwnContentOnly()) {
                         mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
                     }
 
@@ -780,6 +780,15 @@
                     }
                 }
 
+                if (getFeatureFlags().isDisplayContentModeManagementEnabled()) {
+                    // Public display with FLAG_OWN_CONTENT_ONLY disabled is allowed to switch the
+                    // content mode.
+                    if (mIsFirstDisplay
+                            || (!isDisplayPrivate(physicalAddress) && !shouldOwnContentOnly())) {
+                        mInfo.flags |= DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH;
+                    }
+                }
+
                 if (DisplayCutout.getMaskBuiltInDisplayCutout(res, mInfo.uniqueId)) {
                     mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT;
                 }
@@ -822,6 +831,7 @@
                                 R.string.display_manager_hdmi_display_name);
                     }
                 }
+
                 mInfo.frameRateOverrides = mFrameRateOverrides;
 
                 // The display is trusted since it is created by system.
@@ -1467,6 +1477,11 @@
             return false;
         }
 
+        private boolean shouldOwnContentOnly() {
+            final Resources res = getOverlayContext().getResources();
+            return !res.getBoolean(R.bool.config_localDisplaysMirrorContent);
+        }
+
         private boolean isDisplayStealTopFocusDisabled(DisplayAddress.Physical physicalAddress) {
             if (physicalAddress == null) {
                 return false;
diff --git a/services/core/java/com/android/server/display/LogicalDisplay.java b/services/core/java/com/android/server/display/LogicalDisplay.java
index b2b9ef1..0e6870f 100644
--- a/services/core/java/com/android/server/display/LogicalDisplay.java
+++ b/services/core/java/com/android/server/display/LogicalDisplay.java
@@ -489,6 +489,11 @@
             if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_STEAL_TOP_FOCUS_DISABLED) != 0) {
                 mBaseDisplayInfo.flags |= Display.FLAG_STEAL_TOP_FOCUS_DISABLED;
             }
+            // Rear display should not be allowed to use the content mode switch.
+            if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH) != 0
+                    && mDevicePosition != Layout.Display.POSITION_REAR) {
+                mBaseDisplayInfo.flags |= Display.FLAG_ALLOWS_CONTENT_MODE_SWITCH;
+            }
             Rect maskingInsets = getMaskingInsets(deviceInfo);
             int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
             int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
@@ -1155,6 +1160,7 @@
         pw.println("mRequestedMinimalPostProcessing=" + mRequestedMinimalPostProcessing);
         pw.println("mFrameRateOverrides=" + Arrays.toString(mFrameRateOverrides));
         pw.println("mPendingFrameRateOverrideUids=" + mPendingFrameRateOverrideUids);
+        pw.println("mDisplayGroupId=" + mDisplayGroupId);
         pw.println("mDisplayGroupName=" + mDisplayGroupName);
         pw.println("mThermalBrightnessThrottlingDataId=" + mThermalBrightnessThrottlingDataId);
         pw.println("mLeadDisplayId=" + mLeadDisplayId);
diff --git a/services/core/java/com/android/server/display/LogicalDisplayMapper.java b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
index f4daf87..4a4c616 100644
--- a/services/core/java/com/android/server/display/LogicalDisplayMapper.java
+++ b/services/core/java/com/android/server/display/LogicalDisplayMapper.java
@@ -478,6 +478,21 @@
             ipw.decreaseIndent();
             ipw.println();
         }
+
+        final int displayGroupCount = mDisplayGroups.size();
+        ipw.println();
+        ipw.println("Display Groups: size=" + displayGroupCount);
+        for (int i = 0; i < displayGroupCount; i++) {
+            int groupId = mDisplayGroups.keyAt(i);
+            DisplayGroup displayGroup = mDisplayGroups.valueAt(i);
+            ipw.println("Group " + groupId + ":");
+            ipw.increaseIndent();
+            displayGroup.dumpLocked(ipw);
+            ipw.decreaseIndent();
+            ipw.println();
+        }
+
+
         mDeviceStateToLayoutMap.dumpLocked(ipw);
     }
 
diff --git a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
index b5a9b19..60b7fca 100644
--- a/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -76,6 +76,7 @@
  * <li><code>secure</code>: creates a secure display</li>
  * <li><code>own_content_only</code>: only shows this display's own content</li>
  * <li><code>should_show_system_decorations</code>: supports system decorations</li>
+ * <li><code>fixed_content_mode</code>: not allowed to switch content mode</li>
  * <li><code>gravity_top_left</code>: display the overlay at the top left of the screen</li>
  * <li><code>gravity_top_right</code>: display the overlay at the top right of the screen</li>
  * <li><code>gravity_bottom_right</code>: display the overlay at the bottom right of the screen</li>
@@ -117,6 +118,18 @@
     private static final String OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS =
             "should_show_system_decorations";
 
+    /**
+     * When this flag is set, the overlay display is not allowed to switch content mode.
+     * Note that it is the opposite of {@link  DisplayDeviceInfo#FLAG_ALLOWS_CONTENT_MODE_SWITCH},
+     * because we want overlay displays (such as those used for connected display simulation in
+     * development) to have {@link  DisplayDeviceInfo#FLAG_ALLOWS_CONTENT_MODE_SWITCH} enabled by
+     * default without explicitly specifying it.
+     *
+     * @see DisplayDeviceInfo#FLAG_ALLOWS_CONTENT_MODE_SWITCH
+     */
+    private static final String OVERLAY_DISPLAY_FLAG_FIXED_CONTENT_MODE =
+            "fixed_content_mode";
+
     // Gravity flags to decide where the overlay should be shown.
     private static final String GRAVITY_TOP_LEFT = "gravity_top_left";
     private static final String GRAVITY_BOTTOM_RIGHT = "gravity_bottom_right";
@@ -384,6 +397,17 @@
                 if (mFlags.mShouldShowSystemDecorations) {
                     mInfo.flags |= DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
                 }
+                if (getFeatureFlags().isDisplayContentModeManagementEnabled()) {
+                    if (!mFlags.mFixedContentMode
+                            && !mFlags.mOwnContentOnly
+                            && !mFlags.mShouldShowSystemDecorations) {
+                        // For overlay displays, if FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS and
+                        // FLAG_OWN_CONTENT_ONLY are both disabled,
+                        // then FLAG_ALLOWS_CONTENT_MODE_SWITCH should be enabled by default,
+                        // unless OVERLAY_DISPLAY_FLAG_FIXED_CONTENT_MODE is set.
+                        mInfo.flags |= DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH;
+                    }
+                }
                 mInfo.type = Display.TYPE_OVERLAY;
                 mInfo.touch = DisplayDeviceInfo.TOUCH_VIRTUAL;
                 mInfo.state = mState;
@@ -628,16 +652,21 @@
         /** See {@link #OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS}. */
         final boolean mShouldShowSystemDecorations;
 
+        /** See {@link #OVERLAY_DISPLAY_FLAG_FIXED_CONTENT_MODE}. */
+        final boolean mFixedContentMode;
+
         final int mGravity;
 
         OverlayFlags(
                 boolean secure,
                 boolean ownContentOnly,
                 boolean shouldShowSystemDecorations,
+                boolean fixedContentMode,
                 int gravity) {
             mSecure = secure;
             mOwnContentOnly = ownContentOnly;
             mShouldShowSystemDecorations = shouldShowSystemDecorations;
+            mFixedContentMode = fixedContentMode;
             mGravity = gravity;
         }
 
@@ -647,12 +676,14 @@
                         false /* secure */,
                         false /* ownContentOnly */,
                         false /* shouldShowSystemDecorations */,
+                        false /* fixedContentMode */,
                         Gravity.NO_GRAVITY);
             }
 
             boolean secure = false;
             boolean ownContentOnly = false;
             boolean shouldShowSystemDecorations = false;
+            boolean fixedContentMode = false;
             int gravity = Gravity.NO_GRAVITY;
             for (String flag: flagString.split(FLAG_SPLITTER)) {
                 if (OVERLAY_DISPLAY_FLAG_SECURE.equals(flag)) {
@@ -661,11 +692,14 @@
                     ownContentOnly = true;
                 } else if (OVERLAY_DISPLAY_FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS.equals(flag)) {
                     shouldShowSystemDecorations = true;
+                } else if (OVERLAY_DISPLAY_FLAG_FIXED_CONTENT_MODE.equals(flag)) {
+                    fixedContentMode = true;
                 } else {
                     gravity = parseOverlayGravity(flag);
                 }
             }
-            return new OverlayFlags(secure, ownContentOnly, shouldShowSystemDecorations, gravity);
+            return new OverlayFlags(secure, ownContentOnly, shouldShowSystemDecorations,
+                    fixedContentMode, gravity);
         }
 
         @Override
@@ -674,6 +708,7 @@
                     .append("secure=").append(mSecure)
                     .append(", ownContentOnly=").append(mOwnContentOnly)
                     .append(", shouldShowSystemDecorations=").append(mShouldShowSystemDecorations)
+                    .append(", fixedContentMode=").append(mFixedContentMode)
                     .append(", gravity").append(Gravity.toString(mGravity))
                     .append("}")
                     .toString();
diff --git a/services/core/java/com/android/server/display/WifiDisplayAdapter.java b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
index 902eefa..89679c7 100644
--- a/services/core/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/WifiDisplayAdapter.java
@@ -666,6 +666,12 @@
                 mInfo.setAssumedDensityForExternalDisplay(mWidth, mHeight);
                 // The display is trusted since it is created by system.
                 mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED;
+                if (getFeatureFlags().isDisplayContentModeManagementEnabled()) {
+                    // The wifi display is allowed to switch content mode since FLAG_PRIVATE,
+                    // FLAG_OWN_CONTENT_ONLY, and FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS are not
+                    // enabled in WifiDisplayDevice#getDisplayDeviceInfoLocked().
+                    mInfo.flags |= DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH;
+                }
                 mInfo.displayShape =
                         DisplayShape.createDefaultDisplayShape(mInfo.width, mInfo.height, false);
             }
diff --git a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
index 7cc178d..f5228df 100644
--- a/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
+++ b/services/core/java/com/android/server/display/feature/DisplayManagerFlags.java
@@ -280,6 +280,11 @@
             Flags::committedStateSeparateEvent
     );
 
+    private final FlagState mSeparateTimeouts = new FlagState(
+            Flags.FLAG_SEPARATE_TIMEOUTS,
+            Flags::separateTimeouts
+    );
+
     private final FlagState mDelayImplicitRrRegistrationUntilRrAccessed = new FlagState(
             Flags.FLAG_DELAY_IMPLICIT_RR_REGISTRATION_UNTIL_RR_ACCESSED,
             Flags::delayImplicitRrRegistrationUntilRrAccessed
@@ -608,6 +613,14 @@
     }
 
     /**
+     * @return {@code true} if the flag for having a separate timeouts for power groups
+     * is enabled
+     */
+    public boolean isSeparateTimeoutsEnabled() {
+        return mSeparateTimeouts.isEnabled();
+    }
+
+    /**
      * @return {@code true} if the flag for only explicit subscription for RR changes is enabled
      */
     public boolean isDelayImplicitRrRegistrationUntilRrAccessedEnabled() {
@@ -671,6 +684,7 @@
         pw.println(" " + mFramerateOverrideTriggersRrCallbacks);
         pw.println(" " + mRefreshRateEventForForegroundApps);
         pw.println(" " + mCommittedStateSeparateEvent);
+        pw.println(" " + mSeparateTimeouts);
         pw.println(" " + mDelayImplicitRrRegistrationUntilRrAccessed);
     }
 
diff --git a/services/core/java/com/android/server/display/feature/display_flags.aconfig b/services/core/java/com/android/server/display/feature/display_flags.aconfig
index a0064a9..007646f 100644
--- a/services/core/java/com/android/server/display/feature/display_flags.aconfig
+++ b/services/core/java/com/android/server/display/feature/display_flags.aconfig
@@ -509,6 +509,14 @@
     }
 }
 
+
+flag {
+    name: "separate_timeouts"
+    namespace: "lse_desktop_experience"
+    description: "Allow separate timeouts for different power groups"
+    bug: "402356291"
+}
+
 flag {
     name: "delay_implicit_rr_registration_until_rr_accessed"
     namespace: "display_manager"
diff --git a/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
index ab86433..62c3dbd 100644
--- a/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/AudioDeviceVolumeManagerWrapper.java
@@ -23,6 +23,7 @@
 import android.annotation.NonNull;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceVolumeManager;
+import android.media.AudioManager;
 import android.media.VolumeInfo;
 
 import java.util.concurrent.Executor;
@@ -53,7 +54,7 @@
 
     /**
      * Wrapper for {@link AudioDeviceVolumeManager#setDeviceAbsoluteVolumeBehavior(
-     * AudioDeviceAttributes, VolumeInfo, Executor, OnAudioDeviceVolumeChangedListener, boolean)}
+     * AudioDeviceAttributes, VolumeInfo, boolean, Executor, OnAudioDeviceVolumeChangedListener)}
      */
     void setDeviceAbsoluteVolumeBehavior(
             @NonNull AudioDeviceAttributes device,
@@ -64,7 +65,7 @@
 
     /**
      * Wrapper for {@link AudioDeviceVolumeManager#setDeviceAbsoluteVolumeAdjustOnlyBehavior(
-     * AudioDeviceAttributes, VolumeInfo, Executor, OnAudioDeviceVolumeChangedListener, boolean)}
+     * AudioDeviceAttributes, VolumeInfo, boolean, Executor, OnAudioDeviceVolumeChangedListener)}
      */
     void setDeviceAbsoluteVolumeAdjustOnlyBehavior(
             @NonNull AudioDeviceAttributes device,
@@ -72,4 +73,16 @@
             boolean handlesVolumeAdjustment,
             @NonNull @CallbackExecutor Executor executor,
             @NonNull AudioDeviceVolumeManager.OnAudioDeviceVolumeChangedListener vclistener);
+
+    /**
+     * Wraps {@link AudioDeviceVolumeManager#getDeviceVolumeBehavior(AudioDeviceAttributes)}
+     */
+    @AudioManager.DeviceVolumeBehavior
+    int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device);
+
+    /**
+     * Wraps {@link AudioDeviceVolumeManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)}
+     */
+    void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+            @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior);
 }
diff --git a/services/core/java/com/android/server/hdmi/AudioManagerWrapper.java b/services/core/java/com/android/server/hdmi/AudioManagerWrapper.java
index fd4dd51..6d01e2d 100644
--- a/services/core/java/com/android/server/hdmi/AudioManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/AudioManagerWrapper.java
@@ -85,18 +85,6 @@
     void setWiredDeviceConnectionState(int device, int state, String address, String name);
 
     /**
-     * Wraps {@link AudioManager#getDeviceVolumeBehavior(AudioDeviceAttributes)}
-     */
-    @AudioManager.DeviceVolumeBehavior
-    int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device);
-
-    /**
-     * Wraps {@link AudioManager#setDeviceVolumeBehavior(AudioDeviceAttributes, int)}
-     */
-    void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
-            @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior);
-
-    /**
      * Wraps {@link AudioManager#getDevicesForAttributes(AudioAttributes)}
      */
     @NonNull
diff --git a/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java b/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
index 10cbb00..02d8579 100644
--- a/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/DefaultAudioDeviceVolumeManagerWrapper.java
@@ -16,11 +16,14 @@
 
 package com.android.server.hdmi;
 
+import static android.media.audio.Flags.unifyAbsoluteVolumeManagement;
+
 import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.content.Context;
 import android.media.AudioDeviceAttributes;
 import android.media.AudioDeviceVolumeManager;
+import android.media.AudioManager;
 import android.media.VolumeInfo;
 
 import java.util.concurrent.Executor;
@@ -38,9 +41,11 @@
     private static final String TAG = "AudioDeviceVolumeManagerWrapper";
 
     private final AudioDeviceVolumeManager mAudioDeviceVolumeManager;
+    private final AudioManager mAudioManager;
 
     public DefaultAudioDeviceVolumeManagerWrapper(Context context) {
         mAudioDeviceVolumeManager = new AudioDeviceVolumeManager(context);
+        mAudioManager = context.getSystemService(AudioManager.class);
     }
 
     @Override
@@ -78,4 +83,24 @@
         mAudioDeviceVolumeManager.setDeviceAbsoluteVolumeAdjustOnlyBehavior(device, volume,
                 handlesVolumeAdjustment, executor, vclistener);
     }
+
+    @Override
+    @AudioDeviceVolumeManager.DeviceVolumeBehavior
+    public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
+        if (!unifyAbsoluteVolumeManagement()) {
+            int deviceBehavior = mAudioManager.getDeviceVolumeBehavior(device);
+            return deviceBehavior;
+        }
+        return mAudioDeviceVolumeManager.getDeviceVolumeBehavior(device);
+    }
+
+    @Override
+    public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+            @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
+        if (!unifyAbsoluteVolumeManagement()) {
+            int deviceBehavior = deviceVolumeBehavior;
+            mAudioManager.setDeviceVolumeBehavior(device, deviceBehavior);
+        }
+        mAudioDeviceVolumeManager.setDeviceVolumeBehavior(device, deviceVolumeBehavior);
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java b/services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java
index 061e145..6627154 100644
--- a/services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java
+++ b/services/core/java/com/android/server/hdmi/DefaultAudioManagerWrapper.java
@@ -94,18 +94,6 @@
     }
 
     @Override
-    @AudioManager.DeviceVolumeBehavior
-    public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
-        return mAudioManager.getDeviceVolumeBehavior(device);
-    }
-
-    @Override
-    public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
-            @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
-        mAudioManager.setDeviceVolumeBehavior(device, deviceVolumeBehavior);
-    }
-
-    @Override
     @NonNull
     public List<AudioDeviceAttributes> getDevicesForAttributes(
             @NonNull AudioAttributes attributes) {
diff --git a/services/core/java/com/android/server/hdmi/DeviceSelectActionFromTv.java b/services/core/java/com/android/server/hdmi/DeviceSelectActionFromTv.java
index 9118c46..574e484 100644
--- a/services/core/java/com/android/server/hdmi/DeviceSelectActionFromTv.java
+++ b/services/core/java/com/android/server/hdmi/DeviceSelectActionFromTv.java
@@ -167,7 +167,11 @@
     private boolean handleReportPowerStatus(int powerStatus) {
         switch (powerStatus) {
             case HdmiControlManager.POWER_STATUS_ON:
-                selectDevice();
+                if (tv().getActiveSource().physicalAddress == mTarget.getPhysicalAddress()) {
+                    finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
+                } else {
+                    selectDevice();
+                }
                 return true;
             case HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY:
                 if (mPowerStatusCounter < 4) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 8f5b831..32a61fa 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -79,6 +79,9 @@
     // True by default for all the ARC-enabled ports.
     private final SparseBooleanArray mArcFeatureEnabled = new SparseBooleanArray();
 
+    @GuardedBy("mLock")
+    private List<byte[]> mSupportedSads = new ArrayList<>();
+
     // Whether the System Audio Control feature is enabled or not. True by default.
     @GuardedBy("mLock")
     private boolean mSystemAudioControlFeatureEnabled;
@@ -858,6 +861,13 @@
                 new SystemAudioActionFromTv(this, avr.getLogicalAddress(), enabled, callback));
     }
 
+    void clearSads() {
+        synchronized (mLock) {
+            mSupportedSads.clear();
+        }
+    }
+
+
     // # Seq 25
     void setSystemAudioMode(boolean on) {
         if (!isSystemAudioControlFeatureEnabled() && on) {
@@ -911,13 +921,41 @@
     }
 
     @ServiceThreadOnly
-    void enableArc(List<byte[]> supportedSads) {
+    void enableArc() {
         assertRunOnServiceThread();
         HdmiLogger.debug("Set Arc Status[old:%b new:true]", mArcEstablished);
 
         enableAudioReturnChannel(true);
-        notifyArcStatusToAudioService(true, supportedSads);
+        //Ensure mSupportedSads is empty before fetching SADs
+        synchronized (mLock) {
+            mSupportedSads.clear();
+            notifyArcStatusToAudioService(true, mSupportedSads);
+        }
         mArcEstablished = true;
+
+        // Avoid triggering duplicate RequestSadAction events.
+        // This could lead to unexpected responses from the AVR and cause the TV to receive data
+        // out of order. The SAD report does not provide information about the order of events.
+        if (hasAction(RequestSadAction.class)) {
+            return;
+        }
+
+        // Send Request SAD to get real SAD instead of default empty
+        RequestSadAction action = new RequestSadAction(
+                this, Constants.ADDR_AUDIO_SYSTEM,
+                new RequestSadAction.RequestSadCallback() {
+                    @Override
+                    public void onRequestSadDone(List<byte[]> supportedSadsDone) {
+                        synchronized (mLock) {
+                            mSupportedSads = supportedSadsDone;
+                        }
+                        notifyArcStatusToAudioService(false, new ArrayList<>());
+                        synchronized (mLock) {
+                            notifyArcStatusToAudioService(true, mSupportedSads);
+                        }
+                    }
+                });
+        addAndStartAction(action);
     }
 
     @ServiceThreadOnly
@@ -928,6 +966,7 @@
         enableAudioReturnChannel(false);
         notifyArcStatusToAudioService(false, new ArrayList<>());
         mArcEstablished = false;
+        clearSads();
     }
 
     /**
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index fdd0ef2..41b0b4d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -4595,7 +4595,7 @@
      * Wrapper for {@link AudioManager#getDeviceVolumeBehavior} that takes advantage of cached
      * results for the volume behaviors of HDMI audio devices.
      */
-    @AudioManager.DeviceVolumeBehavior
+    @AudioDeviceVolumeManager.DeviceVolumeBehavior
     private int getDeviceVolumeBehavior(AudioDeviceAttributes device) {
         if (AVB_AUDIO_OUTPUT_DEVICES.contains(device)) {
             synchronized (mLock) {
@@ -4604,7 +4604,7 @@
                 }
             }
         }
-        return getAudioManager().getDeviceVolumeBehavior(device);
+        return getAudioDeviceVolumeManager().getDeviceVolumeBehavior(device);
     }
 
     /**
@@ -4695,7 +4695,7 @@
         // Condition 3: All AVB-capable audio outputs already use full/absolute volume behavior
         // We only need to check the first AVB-capable audio output because only TV panels
         // have more than one of them, and they always have the same volume behavior.
-        @AudioManager.DeviceVolumeBehavior int currentVolumeBehavior =
+        @AudioDeviceVolumeManager.DeviceVolumeBehavior int currentVolumeBehavior =
                 getDeviceVolumeBehavior(getAvbCapableAudioOutputDevices().get(0));
         boolean alreadyUsingFullOrAbsoluteVolume =
                 FULL_AND_ABSOLUTE_VOLUME_BEHAVIORS.contains(currentVolumeBehavior);
@@ -4719,7 +4719,8 @@
         // Condition 5: The System Audio device supports <Set Audio Volume Level>
         switch (systemAudioDeviceInfo.getDeviceFeatures().getSetAudioVolumeLevelSupport()) {
             case DeviceFeatures.FEATURE_SUPPORTED:
-                if (currentVolumeBehavior != AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+                if (currentVolumeBehavior
+                        != AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
                     // Start an action that will call enableAbsoluteVolumeBehavior
                     // once the System Audio device sends <Report Audio Status>
                     localCecDevice.startNewAvbAudioStatusAction(
@@ -4731,13 +4732,15 @@
                 // This allows the device to display numeric volume UI for the System Audio device.
                 if (tv() != null && mNumericSoundbarVolumeUiOnTvFeatureFlagEnabled) {
                     if (currentVolumeBehavior
-                            != AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY) {
+                            != AudioDeviceVolumeManager
+                            .DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY) {
                         // If we're currently using absolute volume behavior, switch to full volume
                         // behavior until we successfully adopt adjust-only absolute volume behavior
-                        if (currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+                        if (currentVolumeBehavior
+                                == AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
                             for (AudioDeviceAttributes device : getAvbCapableAudioOutputDevices()) {
-                                getAudioManager().setDeviceVolumeBehavior(device,
-                                        AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+                                getAudioDeviceVolumeManager().setDeviceVolumeBehavior(device,
+                                        AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
                             }
                         }
                         // Start an action that will call enableAbsoluteVolumeBehavior
@@ -4750,7 +4753,8 @@
                 }
                 return;
             case DeviceFeatures.FEATURE_SUPPORT_UNKNOWN:
-                if (currentVolumeBehavior == AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
+                if (currentVolumeBehavior
+                        == AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE) {
                     switchToFullVolumeBehavior();
                 }
                 localCecDevice.querySetAudioVolumeLevelSupport(
@@ -4773,8 +4777,8 @@
 
         for (AudioDeviceAttributes device : getAvbCapableAudioOutputDevices()) {
             if (ABSOLUTE_VOLUME_BEHAVIORS.contains(getDeviceVolumeBehavior(device))) {
-                getAudioManager().setDeviceVolumeBehavior(device,
-                        AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+                getAudioDeviceVolumeManager().setDeviceVolumeBehavior(device,
+                        AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
             }
         }
     }
diff --git a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
index e6abcb9..d8dfe44 100644
--- a/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
+++ b/services/core/java/com/android/server/hdmi/SetArcTransmissionStateAction.java
@@ -60,35 +60,20 @@
     boolean start() {
         // Seq #37.
         if (mEnabled) {
-            // Avoid triggering duplicate RequestSadAction events.
-            // This could lead to unexpected responses from the AVR and cause the TV to receive data
-            // out of order. The SAD report does not provide information about the order of events.
-            if ((tv().hasAction(RequestSadAction.class))) {
-                return true;
-            }
-            // Request SADs before enabling ARC
-            RequestSadAction action = new RequestSadAction(
-                    localDevice(), Constants.ADDR_AUDIO_SYSTEM,
-                    new RequestSadAction.RequestSadCallback() {
-                        @Override
-                        public void onRequestSadDone(List<byte[]> supportedSads) {
-                            // Enable ARC status immediately before sending <Report Arc Initiated>.
-                            // If AVR responds with <Feature Abort>, disable ARC status again.
-                            // This is different from spec that says that turns ARC status to
-                            // "Enabled" if <Report ARC Initiated> is acknowledged and no
-                            // <Feature Abort> is received.
-                            // But implemented this way to save the time having to wait for
-                            // <Feature Abort>.
-                            Slog.i(TAG, "Enabling ARC");
-                            tv().enableArc(supportedSads);
-                            // If succeeds to send <Report ARC Initiated>, wait general timeout to
-                            // check whether there is no <Feature Abort> for <Report ARC Initiated>.
-                            mState = STATE_WAITING_TIMEOUT;
-                            addTimer(mState, HdmiConfig.TIMEOUT_MS);
-                            sendReportArcInitiated();
-                        }
-                    });
-            addAndStartAction(action);
+            // Enable ARC status immediately before sending <Report Arc Initiated>.
+            // If AVR responds with <Feature Abort>, disable ARC status again.
+            // This is different from spec that says that turns ARC status to
+            // "Enabled" if <Report ARC Initiated> is acknowledged and no
+            // <Feature Abort> is received.
+            // But implemented this way to save the time having to wait for
+            // <Feature Abort>.
+            Slog.i(TAG, "Enabling ARC");
+            tv().enableArc();
+            // If succeeds to send <Report ARC Initiated>, wait general timeout to
+            // check whether there is no <Feature Abort> for <Report ARC Initiated>.
+            mState = STATE_WAITING_TIMEOUT;
+            addTimer(mState, HdmiConfig.TIMEOUT_MS);
+            sendReportArcInitiated();
         } else {
             disableArc();
             finish();
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index d9db178..6e6d00d 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -1230,7 +1230,7 @@
                 "registerTabletModeChangedListener()")) {
             throw new SecurityException("Requires TABLET_MODE_LISTENER permission");
         }
-        Objects.requireNonNull(listener, "event must not be null");
+        Objects.requireNonNull(listener, "listener must not be null");
 
         synchronized (mTabletModeLock) {
             final int callingPid = Binder.getCallingPid();
@@ -1342,7 +1342,7 @@
 
     @Override
     public void requestPointerCapture(IBinder inputChannelToken, boolean enabled) {
-        Objects.requireNonNull(inputChannelToken, "event must not be null");
+        Objects.requireNonNull(inputChannelToken, "inputChannelToken must not be null");
 
         mNative.requestPointerCapture(inputChannelToken, enabled);
     }
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index 2375775..fde9165 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -5669,11 +5669,6 @@
         LocalServices.addService(InputMethodManagerInternal.class, mInputMethodManagerInternal);
     }
 
-    // TODO(b/352228316): Remove it once IMMIProxy is removed.
-    InputMethodManagerInternal getLocalService(){
-        return mInputMethodManagerInternal;
-    }
-
     private final class LocalServiceImpl extends InputMethodManagerInternal {
 
         @ImfLockFree
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
index 6db62c8..ccb9e3e 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointBroker.java
@@ -301,7 +301,8 @@
             throw new IllegalArgumentException(
                     "Unknown session ID in closeSession: id=" + sessionId);
         }
-        halCloseEndpointSession(sessionId, ContextHubServiceUtil.toHalReason(reason));
+        mEndpointManager.halCloseEndpointSession(
+                sessionId, ContextHubServiceUtil.toHalReason(reason));
     }
 
     @Override
@@ -312,7 +313,7 @@
             // Iterate in reverse since cleanupSessionResources will remove the entry
             for (int i = mSessionMap.size() - 1; i >= 0; i--) {
                 int id = mSessionMap.keyAt(i);
-                halCloseEndpointSessionNoThrow(id, Reason.ENDPOINT_GONE);
+                mEndpointManager.halCloseEndpointSessionNoThrow(id, Reason.ENDPOINT_GONE);
                 cleanupSessionResources(id);
             }
         }
@@ -444,7 +445,8 @@
                     int id = mSessionMap.keyAt(i);
                     HubEndpointInfo target = mSessionMap.get(id).getRemoteEndpointInfo();
                     if (!hasEndpointPermissions(target)) {
-                        halCloseEndpointSessionNoThrow(id, Reason.PERMISSION_DENIED);
+                        mEndpointManager.halCloseEndpointSessionNoThrow(
+                                id, Reason.PERMISSION_DENIED);
                         onCloseEndpointSession(id, Reason.PERMISSION_DENIED);
                         // Resource cleanup is done in onCloseEndpointSession
                     }
@@ -503,17 +505,7 @@
         mContextHubEndpointCallback.asBinder().linkToDeath(this, 0 /* flags */);
     }
 
-    /* package */ void onEndpointSessionOpenRequest(
-            int sessionId, HubEndpointInfo initiator, String serviceDescriptor) {
-        Optional<Byte> error =
-                onEndpointSessionOpenRequestInternal(sessionId, initiator, serviceDescriptor);
-        if (error.isPresent()) {
-            halCloseEndpointSessionNoThrow(sessionId, error.get());
-            onCloseEndpointSession(sessionId, error.get());
-            // Resource cleanup is done in onCloseEndpointSession
-        }
-    }
-
+    /** Handle close endpoint callback to the client side */
     /* package */ void onCloseEndpointSession(int sessionId, byte reason) {
         if (!cleanupSessionResources(sessionId)) {
             Log.w(TAG, "Unknown session ID in onCloseEndpointSession: id=" + sessionId);
@@ -585,7 +577,7 @@
         }
     }
 
-    private Optional<Byte> onEndpointSessionOpenRequestInternal(
+    /* package */ Optional<Byte> onEndpointSessionOpenRequest(
             int sessionId, HubEndpointInfo initiator, String serviceDescriptor) {
         if (!hasEndpointPermissions(initiator)) {
             Log.e(
@@ -594,15 +586,41 @@
                             + initiator
                             + " doesn't have permission for "
                             + mEndpointInfo);
-            return Optional.of(Reason.PERMISSION_DENIED);
+            byte reason = Reason.PERMISSION_DENIED;
+            onCloseEndpointSession(sessionId, reason);
+            return Optional.of(reason);
         }
 
+        // Check & handle error cases for duplicated session id.
+        final boolean existingSession;
+        final boolean existingSessionActive;
         synchronized (mOpenSessionLock) {
             if (hasSessionId(sessionId)) {
-                Log.e(TAG, "Existing session in onEndpointSessionOpenRequest: id=" + sessionId);
-                return Optional.of(Reason.UNSPECIFIED);
+                existingSession = true;
+                existingSessionActive = mSessionMap.get(sessionId).isActive();
+                Log.w(
+                        TAG,
+                        "onEndpointSessionOpenRequest: "
+                                + "Existing session ID: "
+                                + sessionId
+                                + ", isActive: "
+                                + existingSessionActive);
+            } else {
+                existingSession = false;
+                existingSessionActive = false;
+                mSessionMap.put(sessionId, new Session(initiator, true));
             }
-            mSessionMap.put(sessionId, new Session(initiator, true));
+        }
+
+        if (existingSession) {
+            if (existingSessionActive) {
+                // Existing session is already active, call onSessionOpenComplete.
+                openSessionRequestComplete(sessionId);
+                return Optional.empty();
+            }
+            // Reject the session open request for now. Consider invalidating previous pending
+            // session open request based on timeout.
+            return Optional.of(Reason.OPEN_ENDPOINT_SESSION_REQUEST_REJECTED);
         }
 
         boolean success =
@@ -610,7 +628,11 @@
                         (consumer) ->
                                 consumer.onSessionOpenRequest(
                                         sessionId, initiator, serviceDescriptor));
-        return success ? Optional.empty() : Optional.of(Reason.UNSPECIFIED);
+        byte reason = Reason.UNSPECIFIED;
+        if (!success) {
+            onCloseEndpointSession(sessionId, reason);
+        }
+        return success ? Optional.empty() : Optional.of(reason);
     }
 
     private byte onMessageReceivedInternal(int sessionId, HubMessage message) {
@@ -657,29 +679,6 @@
     }
 
     /**
-     * Calls the HAL closeEndpointSession API.
-     *
-     * @param sessionId The session ID to close
-     * @param halReason The HAL reason
-     */
-    private void halCloseEndpointSession(int sessionId, byte halReason) throws RemoteException {
-        try {
-            mHubInterface.closeEndpointSession(sessionId, halReason);
-        } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
-            throw e;
-        }
-    }
-
-    /** Same as halCloseEndpointSession but does not throw the exception */
-    private void halCloseEndpointSessionNoThrow(int sessionId, byte halReason) {
-        try {
-            halCloseEndpointSession(sessionId, halReason);
-        } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
-            Log.e(TAG, "Exception while calling HAL closeEndpointSession", e);
-        }
-    }
-
-    /**
      * Cleans up resources related to a session with the provided ID.
      *
      * @param sessionId The session ID to clean up resources for
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
index 8ab581e..e156159 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubEndpointManager.java
@@ -29,6 +29,7 @@
 import android.hardware.contexthub.IContextHubEndpointCallback;
 import android.hardware.contexthub.IEndpointCommunication;
 import android.hardware.contexthub.MessageDeliveryStatus;
+import android.hardware.contexthub.Reason;
 import android.os.RemoteException;
 import android.os.ServiceSpecificException;
 import android.util.Log;
@@ -42,6 +43,7 @@
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
+import java.util.Optional;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Consumer;
@@ -316,6 +318,11 @@
         }
     }
 
+    /** Returns if a sessionId can be allocated for the service hub. */
+    private boolean isSessionIdAllocatedForService(int sessionId) {
+        return sessionId > mMaxSessionId || sessionId < mMinSessionId;
+    }
+
     /**
      * Unregisters an endpoint given its ID.
      *
@@ -337,8 +344,7 @@
         }
     }
 
-    @Override
-    public void onEndpointSessionOpenRequest(
+    private Optional<Byte> onEndpointSessionOpenRequestInternal(
             int sessionId,
             HubEndpointInfo.HubEndpointIdentifier destination,
             HubEndpointInfo.HubEndpointIdentifier initiator,
@@ -348,7 +354,7 @@
                     TAG,
                     "onEndpointSessionOpenRequest: invalid destination hub ID: "
                             + destination.getHub());
-            return;
+            return Optional.of(Reason.ENDPOINT_INVALID);
         }
         ContextHubEndpointBroker broker = mEndpointMap.get(destination.getEndpoint());
         if (broker == null) {
@@ -356,7 +362,7 @@
                     TAG,
                     "onEndpointSessionOpenRequest: unknown destination endpoint ID: "
                             + destination.getEndpoint());
-            return;
+            return Optional.of(Reason.ENDPOINT_INVALID);
         }
         HubEndpointInfo initiatorInfo = mHubInfoRegistry.getEndpointInfo(initiator);
         if (initiatorInfo == null) {
@@ -364,9 +370,29 @@
                     TAG,
                     "onEndpointSessionOpenRequest: unknown initiator endpoint ID: "
                             + initiator.getEndpoint());
-            return;
+            return Optional.of(Reason.ENDPOINT_INVALID);
         }
-        broker.onEndpointSessionOpenRequest(sessionId, initiatorInfo, serviceDescriptor);
+        if (!isSessionIdAllocatedForService(sessionId)) {
+            Log.e(
+                    TAG,
+                    "onEndpointSessionOpenRequest: invalid session ID, rejected:"
+                            + " sessionId="
+                            + sessionId);
+            return Optional.of(Reason.OPEN_ENDPOINT_SESSION_REQUEST_REJECTED);
+        }
+        return broker.onEndpointSessionOpenRequest(sessionId, initiatorInfo, serviceDescriptor);
+    }
+
+    @Override
+    public void onEndpointSessionOpenRequest(
+            int sessionId,
+            HubEndpointInfo.HubEndpointIdentifier destination,
+            HubEndpointInfo.HubEndpointIdentifier initiator,
+            String serviceDescriptor) {
+        Optional<Byte> errorOptional =
+                onEndpointSessionOpenRequestInternal(
+                        sessionId, destination, initiator, serviceDescriptor);
+        errorOptional.ifPresent((error) -> halCloseEndpointSessionNoThrow(sessionId, error));
     }
 
     @Override
@@ -418,6 +444,30 @@
         }
     }
 
+    /**
+     * Calls the HAL closeEndpointSession API.
+     *
+     * @param sessionId The session ID to close
+     * @param halReason The HAL reason
+     */
+    /* package */ void halCloseEndpointSession(int sessionId, byte halReason)
+            throws RemoteException {
+        try {
+            mHubInterface.closeEndpointSession(sessionId, halReason);
+        } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
+            throw e;
+        }
+    }
+
+    /** Same as halCloseEndpointSession but does not throw the exception */
+    /* package */ void halCloseEndpointSessionNoThrow(int sessionId, byte halReason) {
+        try {
+            halCloseEndpointSession(sessionId, halReason);
+        } catch (RemoteException | IllegalArgumentException | UnsupportedOperationException e) {
+            Log.e(TAG, "Exception while calling HAL closeEndpointSession", e);
+        }
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
diff --git a/services/core/java/com/android/server/location/gnss/GnssManagerService.java b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
index 6a72cc7..7d9f2c2 100644
--- a/services/core/java/com/android/server/location/gnss/GnssManagerService.java
+++ b/services/core/java/com/android/server/location/gnss/GnssManagerService.java
@@ -24,6 +24,7 @@
 import android.hardware.location.GeofenceHardwareImpl;
 import android.location.FusedBatchOptions;
 import android.location.GnssAntennaInfo;
+import android.location.GnssAssistance;
 import android.location.GnssCapabilities;
 import android.location.GnssMeasurementCorrections;
 import android.location.GnssMeasurementRequest;
@@ -35,6 +36,8 @@
 import android.location.IGpsGeofenceHardware;
 import android.location.Location;
 import android.location.LocationManager;
+import android.location.flags.Flags;
+import android.location.provider.IGnssAssistanceCallback;
 import android.location.util.identity.CallerIdentity;
 import android.os.BatteryStats;
 import android.os.Binder;
@@ -47,12 +50,13 @@
 import com.android.server.FgThread;
 import com.android.server.location.gnss.hal.GnssNative;
 import com.android.server.location.injector.Injector;
+import com.android.server.location.provider.proxy.ProxyGnssAssistanceProvider;
 
 import java.io.FileDescriptor;
 import java.util.List;
 
 /** Manages Gnss providers and related Gnss functions for LocationManagerService. */
-public class GnssManagerService {
+public class GnssManagerService implements GnssNative.GnssAssistanceCallbacks {
 
     public static final String TAG = "GnssManager";
     public static final boolean D = Log.isLoggable(TAG, Log.DEBUG);
@@ -75,6 +79,8 @@
 
     private final GnssMetrics mGnssMetrics;
 
+    private @Nullable ProxyGnssAssistanceProvider mProxyGnssAssistanceProvider = null;
+
     public GnssManagerService(Context context, Injector injector, GnssNative gnssNative) {
         mContext = context.createAttributionContext(ATTRIBUTION_ID);
         mGnssNative = gnssNative;
@@ -100,6 +106,16 @@
     /** Called when system is ready. */
     public void onSystemReady() {
         mGnssLocationProvider.onSystemReady();
+
+        if (Flags.gnssAssistanceInterfaceJni()) {
+            mProxyGnssAssistanceProvider =
+                    ProxyGnssAssistanceProvider.createAndRegister(mContext);
+            if (mProxyGnssAssistanceProvider == null) {
+                Log.e(TAG, "no gnss assistance provider found");
+            } else {
+                mGnssNative.setGnssAssistanceCallbacks(this);
+            }
+        }
     }
 
     /** Retrieve the GnssLocationProvider. */
@@ -323,6 +339,29 @@
         }
     }
 
+    @Override
+    public void onRequestGnssAssistanceInject() {
+        if (!Flags.gnssAssistanceInterfaceJni()) {
+            return;
+        }
+        if (mProxyGnssAssistanceProvider == null) {
+            Log.e(TAG, "ProxyGnssAssistanceProvider is null");
+            return;
+        }
+        mProxyGnssAssistanceProvider.request(new IGnssAssistanceCallback.Stub() {
+            @Override
+            public void onError() {
+                Log.e(TAG, "GnssAssistanceCallback.onError");
+            }
+
+            @Override
+            public void onResult(GnssAssistance gnssAssistance) {
+                Log.d(TAG, "GnssAssistanceCallback.onResult");
+                mGnssNative.injectGnssAssistance(gnssAssistance);
+            }
+        });
+    }
+
     private class GnssCapabilitiesHalModule implements GnssNative.BaseCallbacks {
 
         GnssCapabilitiesHalModule(GnssNative gnssNative) {
diff --git a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java
index c79a21a..7fd400e 100644
--- a/services/core/java/com/android/server/location/gnss/hal/GnssNative.java
+++ b/services/core/java/com/android/server/location/gnss/hal/GnssNative.java
@@ -23,6 +23,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.location.GnssAntennaInfo;
+import android.location.GnssAssistance;
 import android.location.GnssCapabilities;
 import android.location.GnssMeasurementCorrections;
 import android.location.GnssMeasurementsEvent;
@@ -30,6 +31,7 @@
 import android.location.GnssSignalType;
 import android.location.GnssStatus;
 import android.location.Location;
+import android.location.flags.Flags;
 import android.os.Binder;
 import android.os.Handler;
 import android.os.SystemClock;
@@ -275,6 +277,12 @@
         void onRequestPsdsDownload(int psdsType);
     }
 
+    /** Callbacks for HAL requesting GNSS assistance. */
+    public interface GnssAssistanceCallbacks {
+        /** On request GnssAssistance injection. */
+        void onRequestGnssAssistanceInject();
+    }
+
     /** Callbacks for AGPS functionality. */
     public interface AGpsCallbacks {
 
@@ -400,6 +408,7 @@
     private TimeCallbacks mTimeCallbacks;
     private LocationRequestCallbacks mLocationRequestCallbacks;
     private PsdsCallbacks mPsdsCallbacks;
+    private @Nullable GnssAssistanceCallbacks mGnssAssistanceCallbacks;
     private AGpsCallbacks mAGpsCallbacks;
     private NotificationCallbacks mNotificationCallbacks;
 
@@ -504,6 +513,15 @@
         mNotificationCallbacks = Objects.requireNonNull(callbacks);
     }
 
+    /** Sets GnssAssistanceCallbacks. */
+    public void setGnssAssistanceCallbacks(GnssAssistanceCallbacks callbacks) {
+        if (!Flags.gnssAssistanceInterfaceJni()) {
+            return;
+        }
+        Preconditions.checkState(mGnssAssistanceCallbacks == null);
+        mGnssAssistanceCallbacks = Objects.requireNonNull(callbacks);
+    }
+
     /**
      * Registers with the HAL and allows callbacks to begin. Once registered with the native HAL,
      * no more callbacks can be added or set. Must only be called once.
@@ -1053,6 +1071,17 @@
         mGnssHal.injectNiSuplMessageData(data, length, slotIndex);
     }
 
+    /**
+     * Injects GNSS assistance data into the GNSS HAL.
+     */
+    public void injectGnssAssistance(GnssAssistance assistance) {
+        if (!Flags.gnssAssistanceInterfaceJni()) {
+            return;
+        }
+        Preconditions.checkState(mRegistered);
+        mGnssHal.injectGnssAssistance(assistance);
+    }
+
     @NativeEntryPoint
     void reportGnssServiceDied() {
         // Not necessary to clear (and restore) binder identity since it runs on another thread.
@@ -1269,6 +1298,15 @@
     }
 
     @NativeEntryPoint
+    void gnssAssistanceInjectRequest() {
+        if (!Flags.gnssAssistanceInterfaceJni() || mGnssAssistanceCallbacks == null) {
+            return;
+        }
+        Binder.withCleanCallingIdentity(
+                () -> mGnssAssistanceCallbacks.onRequestGnssAssistanceInject());
+    }
+
+    @NativeEntryPoint
     void reportGeofenceTransition(int geofenceId, Location location, int transition,
             long transitionTimestamp) {
         Binder.withCleanCallingIdentity(
@@ -1569,6 +1607,10 @@
         protected void injectNiSuplMessageData(byte[] data, int length, int slotIndex) {
             native_inject_ni_supl_message_data(data, length, slotIndex);
         }
+
+        protected void injectGnssAssistance(GnssAssistance gnssAssistance) {
+            native_inject_gnss_assistance(gnssAssistance);
+        }
     }
 
     // basic APIs
@@ -1718,4 +1760,7 @@
     private static native boolean native_supports_psds();
 
     private static native void native_inject_psds_data(byte[] data, int length, int psdsType);
+
+    // GNSS Assistance APIs
+    private static native void native_inject_gnss_assistance(GnssAssistance gnssAssistance);
 }
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 42d0a5c..07d1a65 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -31,7 +31,6 @@
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.UserHandle.USER_ALL;
 import static android.os.UserHandle.USER_SYSTEM;
-import static android.security.Flags.reportPrimaryAuthAttempts;
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN;
@@ -1918,7 +1917,7 @@
      * Set a new LSKF for the given user/profile. Only succeeds if the synthetic password for the
      * user is protected by the given {@param savedCredential}.
      * <p>
-     * When {@link android.security.Flags#clearStrongAuthOnAddPrimaryCredential()} is enabled and
+     * When {@link android.security.Flags#clearStrongAuthOnAddingPrimaryCredential()} is enabled and
      * setting a new credential where there was none, updates the strong auth state for
      * {@param userId} to <tt>STRONG_AUTH_NOT_REQUIRED</tt>.
      *
@@ -1970,7 +1969,7 @@
 
             onSyntheticPasswordUnlocked(userId, sp);
             setLockCredentialWithSpLocked(credential, sp, userId);
-            if (android.security.Flags.clearStrongAuthOnAddPrimaryCredential()
+            if (android.security.Flags.clearStrongAuthOnAddingPrimaryCredential()
                     && savedCredential.isNone() && !credential.isNone()) {
                 // Clear the strong auth value, since the LSKF has just been entered and set,
                 // but only when the previous credential was None.
@@ -2483,11 +2482,8 @@
                 requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT, userId);
             }
         }
-        if (reportPrimaryAuthAttempts()) {
-            final boolean success =
-                    response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK;
-            notifyLockSettingsStateListeners(success, userId);
-        }
+        final boolean success = response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK;
+        notifyLockSettingsStateListeners(success, userId);
         return response;
     }
 
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityService.java b/services/core/java/com/android/server/media/quality/MediaQualityService.java
index ad108f6..9a09807 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityService.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityService.java
@@ -371,12 +371,8 @@
                     PictureParameter[] pictureParameters = MediaQualityUtils
                             .convertPersistableBundleToPictureParameterList(params);
 
-                    PersistableBundle vendorPictureParameters = params
-                            .getPersistableBundle(BaseParameters.VENDOR_PARAMETERS);
                     Parcel parcel = Parcel.obtain();
-                    if (vendorPictureParameters != null) {
-                        setVendorPictureParameters(pp, parcel, vendorPictureParameters);
-                    }
+                    setVendorPictureParameters(pp, parcel, params);
 
                     pp.pictureParameters = pictureParameters;
 
@@ -1429,11 +1425,9 @@
                     MediaQualityUtils.convertPersistableBundleToPictureParameterList(
                             params);
 
-            PersistableBundle vendorPictureParameters = params
-                    .getPersistableBundle(BaseParameters.VENDOR_PARAMETERS);
             Parcel parcel = Parcel.obtain();
-            if (vendorPictureParameters != null) {
-                setVendorPictureParameters(pictureParameters, parcel, vendorPictureParameters);
+            if (params != null) {
+                setVendorPictureParameters(pictureParameters, parcel, params);
             }
 
             android.hardware.tv.mediaquality.PictureProfile toReturn =
diff --git a/services/core/java/com/android/server/media/quality/MediaQualityUtils.java b/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
index 303c967..cf8b703 100644
--- a/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
+++ b/services/core/java/com/android/server/media/quality/MediaQualityUtils.java
@@ -373,323 +373,403 @@
         if (params.containsKey(PictureQuality.PARAMETER_BRIGHTNESS)) {
             pictureParams.add(PictureParameter.brightness(params.getLong(
                     PictureQuality.PARAMETER_BRIGHTNESS)));
+            params.remove(PictureQuality.PARAMETER_BRIGHTNESS);
         }
         if (params.containsKey(PictureQuality.PARAMETER_CONTRAST)) {
             pictureParams.add(PictureParameter.contrast(params.getInt(
                     PictureQuality.PARAMETER_CONTRAST)));
+            params.remove(PictureQuality.PARAMETER_CONTRAST);
         }
         if (params.containsKey(PictureQuality.PARAMETER_SHARPNESS)) {
             pictureParams.add(PictureParameter.sharpness(params.getInt(
                     PictureQuality.PARAMETER_SHARPNESS)));
+            params.remove(PictureQuality.PARAMETER_SHARPNESS);
         }
         if (params.containsKey(PictureQuality.PARAMETER_SATURATION)) {
             pictureParams.add(PictureParameter.saturation(params.getInt(
                     PictureQuality.PARAMETER_SATURATION)));
+            params.remove(PictureQuality.PARAMETER_SATURATION);
         }
         if (params.containsKey(PictureQuality.PARAMETER_HUE)) {
             pictureParams.add(PictureParameter.hue(params.getInt(
                     PictureQuality.PARAMETER_HUE)));
+            params.remove(PictureQuality.PARAMETER_HUE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BRIGHTNESS)) {
             pictureParams.add(PictureParameter.colorTunerBrightness(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_BRIGHTNESS)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_BRIGHTNESS);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION)) {
             pictureParams.add(PictureParameter.colorTunerSaturation(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_SATURATION)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE)) {
             pictureParams.add(PictureParameter.colorTunerHue(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_HUE)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_OFFSET)) {
             pictureParams.add(PictureParameter.colorTunerRedOffset(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_RED_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_RED_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_OFFSET)) {
             pictureParams.add(PictureParameter.colorTunerGreenOffset(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_GREEN_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_OFFSET)) {
             pictureParams.add(PictureParameter.colorTunerBlueOffset(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_BLUE_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN)) {
             pictureParams.add(PictureParameter.colorTunerRedGain(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN)) {
             pictureParams.add(PictureParameter.colorTunerGreenGain(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN)) {
             pictureParams.add(PictureParameter.colorTunerBlueGain(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_NOISE_REDUCTION)) {
             pictureParams.add(PictureParameter.noiseReduction(
                     (byte) params.getInt(PictureQuality.PARAMETER_NOISE_REDUCTION)));
+            params.remove(PictureQuality.PARAMETER_NOISE_REDUCTION);
         }
         if (params.containsKey(PictureQuality.PARAMETER_MPEG_NOISE_REDUCTION)) {
             pictureParams.add(PictureParameter.mpegNoiseReduction(
                     (byte) params.getInt(PictureQuality.PARAMETER_MPEG_NOISE_REDUCTION)));
+            params.remove(PictureQuality.PARAMETER_MPEG_NOISE_REDUCTION);
         }
         if (params.containsKey(PictureQuality.PARAMETER_FLESH_TONE)) {
             pictureParams.add(PictureParameter.fleshTone(
                     (byte) params.getInt(PictureQuality.PARAMETER_FLESH_TONE)));
+            params.remove(PictureQuality.PARAMETER_FLESH_TONE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_DECONTOUR)) {
             pictureParams.add(PictureParameter.deContour(
                     (byte) params.getInt(PictureQuality.PARAMETER_DECONTOUR)));
+            params.remove(PictureQuality.PARAMETER_DECONTOUR);
         }
         if (params.containsKey(PictureQuality.PARAMETER_DYNAMIC_LUMA_CONTROL)) {
             pictureParams.add(PictureParameter.dynamicLumaControl(
                     (byte) params.getInt(PictureQuality.PARAMETER_DYNAMIC_LUMA_CONTROL)));
+            params.remove(PictureQuality.PARAMETER_DYNAMIC_LUMA_CONTROL);
         }
         if (params.containsKey(PictureQuality.PARAMETER_FILM_MODE)) {
             pictureParams.add(PictureParameter.filmMode(params.getBoolean(
                     PictureQuality.PARAMETER_FILM_MODE)));
+            params.remove(PictureQuality.PARAMETER_FILM_MODE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_BLUE_STRETCH)) {
             pictureParams.add(PictureParameter.blueStretch(params.getBoolean(
                     PictureQuality.PARAMETER_BLUE_STRETCH)));
+            params.remove(PictureQuality.PARAMETER_BLUE_STRETCH);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNE)) {
             pictureParams.add(PictureParameter.colorTune(params.getBoolean(
                     PictureQuality.PARAMETER_COLOR_TUNE)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE)) {
             pictureParams.add(PictureParameter.colorTemperature(
                     (byte) params.getInt(
                             PictureQuality.PARAMETER_COLOR_TEMPERATURE)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TEMPERATURE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_GLOBAL_DIMMING)) {
             pictureParams.add(PictureParameter.globeDimming(params.getBoolean(
                     PictureQuality.PARAMETER_GLOBAL_DIMMING)));
+            params.remove(PictureQuality.PARAMETER_GLOBAL_DIMMING);
         }
         if (params.containsKey(PictureQuality.PARAMETER_AUTO_PICTURE_QUALITY_ENABLED)) {
             pictureParams.add(PictureParameter.autoPictureQualityEnabled(params.getBoolean(
                     PictureQuality.PARAMETER_AUTO_PICTURE_QUALITY_ENABLED)));
+            params.remove(PictureQuality.PARAMETER_AUTO_PICTURE_QUALITY_ENABLED);
         }
         if (params.containsKey(PictureQuality.PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED)) {
             pictureParams.add(PictureParameter.autoSuperResolutionEnabled(params.getBoolean(
                     PictureQuality.PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED)));
+            params.remove(PictureQuality.PARAMETER_AUTO_SUPER_RESOLUTION_ENABLED);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN)) {
             pictureParams.add(PictureParameter.colorTemperatureRedGain(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_RED_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN)) {
             pictureParams.add(PictureParameter.colorTemperatureGreenGain(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_GREEN_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN)) {
             pictureParams.add(PictureParameter.colorTemperatureBlueGain(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_BLUE_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_LEVEL_RANGE)) {
             pictureParams.add(PictureParameter.levelRange(
                     (byte) params.getInt(PictureQuality.PARAMETER_LEVEL_RANGE)));
+            params.remove(PictureQuality.PARAMETER_LEVEL_RANGE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_GAMUT_MAPPING)) {
             pictureParams.add(PictureParameter.gamutMapping(params.getBoolean(
                     PictureQuality.PARAMETER_GAMUT_MAPPING)));
+            params.remove(PictureQuality.PARAMETER_GAMUT_MAPPING);
         }
         if (params.containsKey(PictureQuality.PARAMETER_PC_MODE)) {
             pictureParams.add(PictureParameter.pcMode(params.getBoolean(
                     PictureQuality.PARAMETER_PC_MODE)));
+            params.remove(PictureQuality.PARAMETER_PC_MODE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_LOW_LATENCY)) {
             pictureParams.add(PictureParameter.lowLatency(params.getBoolean(
                     PictureQuality.PARAMETER_LOW_LATENCY)));
+            params.remove(PictureQuality.PARAMETER_LOW_LATENCY);
         }
         if (params.containsKey(PictureQuality.PARAMETER_VRR)) {
             pictureParams.add(PictureParameter.vrr(params.getBoolean(
                     PictureQuality.PARAMETER_VRR)));
+            params.remove(PictureQuality.PARAMETER_VRR);
         }
         if (params.containsKey(PictureQuality.PARAMETER_CVRR)) {
             pictureParams.add(PictureParameter.cvrr(params.getBoolean(
                     PictureQuality.PARAMETER_CVRR)));
+            params.remove(PictureQuality.PARAMETER_CVRR);
         }
         if (params.containsKey(PictureQuality.PARAMETER_HDMI_RGB_RANGE)) {
             pictureParams.add(PictureParameter.hdmiRgbRange(
                     (byte) params.getInt(PictureQuality.PARAMETER_HDMI_RGB_RANGE)));
+            params.remove(PictureQuality.PARAMETER_HDMI_RGB_RANGE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_SPACE)) {
             pictureParams.add(PictureParameter.colorSpace(
                     (byte) params.getInt(PictureQuality.PARAMETER_COLOR_SPACE)));
+            params.remove(PictureQuality.PARAMETER_COLOR_SPACE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_NITS)) {
             pictureParams.add(PictureParameter.panelInitMaxLuminceNits(
                     params.getInt(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_NITS)));
+            params.remove(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_NITS);
         }
         if (params.containsKey(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_VALID)) {
             pictureParams.add(PictureParameter.panelInitMaxLuminceValid(
                     params.getBoolean(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_VALID)));
+            params.remove(PictureQuality.PARAMETER_PANEL_INIT_MAX_LUMINCE_VALID);
         }
         if (params.containsKey(PictureQuality.PARAMETER_GAMMA)) {
             pictureParams.add(PictureParameter.gamma(
                     (byte) params.getInt(PictureQuality.PARAMETER_GAMMA)));
+            params.remove(PictureQuality.PARAMETER_GAMMA);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE_RED_OFFSET)) {
             pictureParams.add(PictureParameter.colorTemperatureRedOffset(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TEMPERATURE_RED_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TEMPERATURE_RED_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE_GREEN_OFFSET)) {
             pictureParams.add(PictureParameter.colorTemperatureGreenOffset(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TEMPERATURE_GREEN_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TEMPERATURE_GREEN_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TEMPERATURE_BLUE_OFFSET)) {
             pictureParams.add(PictureParameter.colorTemperatureBlueOffset(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TEMPERATURE_BLUE_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TEMPERATURE_BLUE_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_ELEVEN_POINT_RED)) {
             pictureParams.add(PictureParameter.elevenPointRed(params.getIntArray(
                     PictureQuality.PARAMETER_ELEVEN_POINT_RED)));
+            params.remove(PictureQuality.PARAMETER_ELEVEN_POINT_RED);
         }
         if (params.containsKey(PictureQuality.PARAMETER_ELEVEN_POINT_GREEN)) {
             pictureParams.add(PictureParameter.elevenPointGreen(params.getIntArray(
                     PictureQuality.PARAMETER_ELEVEN_POINT_GREEN)));
+            params.remove(PictureQuality.PARAMETER_ELEVEN_POINT_GREEN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_ELEVEN_POINT_BLUE)) {
             pictureParams.add(PictureParameter.elevenPointBlue(params.getIntArray(
                     PictureQuality.PARAMETER_ELEVEN_POINT_BLUE)));
+            params.remove(PictureQuality.PARAMETER_ELEVEN_POINT_BLUE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_LOW_BLUE_LIGHT)) {
             pictureParams.add(PictureParameter.lowBlueLight(
                     (byte) params.getInt(PictureQuality.PARAMETER_LOW_BLUE_LIGHT)));
+            params.remove(PictureQuality.PARAMETER_LOW_BLUE_LIGHT);
         }
         if (params.containsKey(PictureQuality.PARAMETER_LD_MODE)) {
             pictureParams.add(PictureParameter.LdMode(
                     (byte) params.getInt(PictureQuality.PARAMETER_LD_MODE)));
+            params.remove(PictureQuality.PARAMETER_LD_MODE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_RED_GAIN)) {
             pictureParams.add(PictureParameter.osdRedGain(params.getInt(
                     PictureQuality.PARAMETER_OSD_RED_GAIN)));
+            params.remove(PictureQuality.PARAMETER_OSD_RED_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_GREEN_GAIN)) {
             pictureParams.add(PictureParameter.osdGreenGain(params.getInt(
                     PictureQuality.PARAMETER_OSD_GREEN_GAIN)));
+            params.remove(PictureQuality.PARAMETER_OSD_GREEN_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_BLUE_GAIN)) {
             pictureParams.add(PictureParameter.osdBlueGain(params.getInt(
                     PictureQuality.PARAMETER_OSD_BLUE_GAIN)));
+            params.remove(PictureQuality.PARAMETER_OSD_BLUE_GAIN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_RED_OFFSET)) {
             pictureParams.add(PictureParameter.osdRedOffset(params.getInt(
                     PictureQuality.PARAMETER_OSD_RED_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_OSD_RED_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_GREEN_OFFSET)) {
             pictureParams.add(PictureParameter.osdGreenOffset(params.getInt(
                     PictureQuality.PARAMETER_OSD_GREEN_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_OSD_GREEN_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_BLUE_OFFSET)) {
             pictureParams.add(PictureParameter.osdBlueOffset(params.getInt(
                     PictureQuality.PARAMETER_OSD_BLUE_OFFSET)));
+            params.remove(PictureQuality.PARAMETER_OSD_BLUE_OFFSET);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_HUE)) {
             pictureParams.add(PictureParameter.osdHue(params.getInt(
                     PictureQuality.PARAMETER_OSD_HUE)));
+            params.remove(PictureQuality.PARAMETER_OSD_HUE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_SATURATION)) {
             pictureParams.add(PictureParameter.osdSaturation(params.getInt(
                     PictureQuality.PARAMETER_OSD_SATURATION)));
+            params.remove(PictureQuality.PARAMETER_OSD_SATURATION);
         }
         if (params.containsKey(PictureQuality.PARAMETER_OSD_CONTRAST)) {
             pictureParams.add(PictureParameter.osdContrast(params.getInt(
                     PictureQuality.PARAMETER_OSD_CONTRAST)));
+            params.remove(PictureQuality.PARAMETER_OSD_CONTRAST);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SWITCH)) {
             pictureParams.add(PictureParameter.colorTunerSwitch(params.getBoolean(
                     PictureQuality.PARAMETER_COLOR_TUNER_SWITCH)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SWITCH);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_RED)) {
             pictureParams.add(PictureParameter.colorTunerHueRed(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_HUE_RED)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_RED);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_GREEN)) {
             pictureParams.add(PictureParameter.colorTunerHueGreen(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_HUE_GREEN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_GREEN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_BLUE)) {
             pictureParams.add(PictureParameter.colorTunerHueBlue(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_HUE_BLUE)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_BLUE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_CYAN)) {
             pictureParams.add(PictureParameter.colorTunerHueCyan(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_HUE_CYAN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_CYAN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_MAGENTA)) {
             pictureParams.add(PictureParameter.colorTunerHueMagenta(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_HUE_MAGENTA)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_MAGENTA);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_YELLOW)) {
             pictureParams.add(PictureParameter.colorTunerHueYellow(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_HUE_YELLOW)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_YELLOW);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_HUE_FLESH)) {
             pictureParams.add(PictureParameter.colorTunerHueFlesh(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_HUE_FLESH)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_HUE_FLESH);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_RED)) {
             pictureParams.add(PictureParameter.colorTunerSaturationRed(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_RED)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_RED);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_GREEN)) {
             pictureParams.add(PictureParameter.colorTunerSaturationGreen(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_GREEN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_GREEN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_BLUE)) {
             pictureParams.add(PictureParameter.colorTunerSaturationBlue(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_BLUE)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_BLUE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_CYAN)) {
             pictureParams.add(PictureParameter.colorTunerSaturationCyan(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_CYAN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_CYAN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_MAGENTA)) {
             pictureParams.add(PictureParameter.colorTunerSaturationMagenta(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_MAGENTA)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_MAGENTA);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_YELLOW)) {
             pictureParams.add(PictureParameter.colorTunerSaturationYellow(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_YELLOW)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_YELLOW);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_FLESH)) {
             pictureParams.add(PictureParameter.colorTunerSaturationFlesh(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_FLESH)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_SATURATION_FLESH);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_RED)) {
             pictureParams.add(PictureParameter.colorTunerLuminanceRed(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_RED)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_RED);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_GREEN)) {
             pictureParams.add(PictureParameter.colorTunerLuminanceGreen(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_GREEN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_GREEN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_BLUE)) {
             pictureParams.add(PictureParameter.colorTunerLuminanceBlue(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_BLUE)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_BLUE);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_CYAN)) {
             pictureParams.add(PictureParameter.colorTunerLuminanceCyan(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_CYAN)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_CYAN);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_MAGENTA)) {
             pictureParams.add(PictureParameter.colorTunerLuminanceMagenta(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_MAGENTA)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_MAGENTA);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_YELLOW)) {
             pictureParams.add(PictureParameter.colorTunerLuminanceYellow(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_YELLOW)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_YELLOW);
         }
         if (params.containsKey(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_FLESH)) {
             pictureParams.add(PictureParameter.colorTunerLuminanceFlesh(params.getInt(
                     PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_FLESH)));
+            params.remove(PictureQuality.PARAMETER_COLOR_TUNER_LUMINANCE_FLESH);
         }
         if (params.containsKey(PictureQuality.PARAMETER_PICTURE_QUALITY_EVENT_TYPE)) {
             pictureParams.add(PictureParameter.pictureQualityEventType(
                     (byte) params.getInt(PictureQuality.PARAMETER_PICTURE_QUALITY_EVENT_TYPE)));
+            params.remove(PictureQuality.PARAMETER_PICTURE_QUALITY_EVENT_TYPE);
         }
         return pictureParams.toArray(new PictureParameter[0]);
     }
diff --git a/services/core/java/com/android/server/notification/ConditionProviders.java b/services/core/java/com/android/server/notification/ConditionProviders.java
index dd52cce..3f2c222 100644
--- a/services/core/java/com/android/server/notification/ConditionProviders.java
+++ b/services/core/java/com/android/server/notification/ConditionProviders.java
@@ -46,7 +46,6 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.List;
 
 public class ConditionProviders extends ManagedServices {
 
@@ -203,14 +202,7 @@
 
     @Override
     protected void loadDefaultsFromConfig() {
-        for (String dndPackage : getDefaultDndAccessPackages(mContext)) {
-            addDefaultComponentOrPackage(dndPackage);
-        }
-    }
-
-    static List<String> getDefaultDndAccessPackages(Context context) {
-        ArrayList<String> packages = new ArrayList<>();
-        String defaultDndAccess = context.getResources().getString(
+        String defaultDndAccess = mContext.getResources().getString(
                 R.string.config_defaultDndAccessPackages);
         if (defaultDndAccess != null) {
             String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR);
@@ -218,10 +210,9 @@
                 if (TextUtils.isEmpty(dnds[i])) {
                     continue;
                 }
-                packages.add(dnds[i]);
+                addDefaultComponentOrPackage(dnds[i]);
             }
         }
-        return packages;
     }
 
     @Override
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7a544cf..78554bd 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -764,6 +764,8 @@
     private long mLastOverRateLogTime;
     private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
 
+    private boolean mRedactOtpNotifications = true;
+
     private NotificationHistoryManager mHistoryManager;
     protected SnoozeHelper mSnoozeHelper;
     private TimeToLiveHelper mTtlHelper;
@@ -2410,6 +2412,8 @@
                 = Secure.getUriFor(Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS);
         private final Uri SHOW_NOTIFICATION_SNOOZE
                 = Secure.getUriFor(Secure.SHOW_NOTIFICATION_SNOOZE);
+        private final Uri REDACT_OTP_NOTIFICATIONS = Settings.Global.getUriFor(
+                Settings.Global.REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS);
 
         SettingsObserver(Handler handler) {
             super(handler);
@@ -2435,6 +2439,8 @@
 
             resolver.registerContentObserver(SHOW_NOTIFICATION_SNOOZE,
                     false, this, USER_ALL);
+            resolver.registerContentObserver(REDACT_OTP_NOTIFICATIONS,
+                    false, this, USER_ALL);
 
             update(null);
         }
@@ -2481,6 +2487,10 @@
                     unsnoozeAll();
                 }
             }
+            if (REDACT_OTP_NOTIFICATIONS.equals(uri)) {
+                mRedactOtpNotifications = Settings.Global.getInt(resolver,
+                        Settings.Global.REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS, 1) != 0;
+            }
         }
 
         public void update(Uri uri, int userId) {
@@ -6163,10 +6173,15 @@
         }
 
         @Override
-        public Map<String, AutomaticZenRule> getAutomaticZenRules() {
+        public ParceledListSlice getAutomaticZenRules() {
             int callingUid = Binder.getCallingUid();
             enforcePolicyAccess(callingUid, "getAutomaticZenRules");
-            return mZenModeHelper.getAutomaticZenRules(getCallingZenUser(), callingUid);
+            List<AutomaticZenRule.AzrWithId> ruleList = new ArrayList<>();
+            for (Map.Entry<String, AutomaticZenRule> rule : mZenModeHelper.getAutomaticZenRules(
+                    getCallingZenUser(), callingUid).entrySet()) {
+                ruleList.add(new AutomaticZenRule.AzrWithId(rule.getKey(), rule.getValue()));
+            }
+            return new ParceledListSlice<>(ruleList);
         }
 
         @Override
@@ -13453,13 +13468,13 @@
                 StatusBarNotification oldRedactedSbn = null;
                 boolean isNewSensitive = hasSensitiveContent(r);
                 boolean isOldSensitive = hasSensitiveContent(old);
+                boolean redactionEnabled = redactSensitiveNotificationsFromUntrustedListeners()
+                        && mRedactOtpNotifications;
 
                 for (final ManagedServiceInfo info : getServices()) {
                     boolean isTrusted = isUidTrusted(info.uid);
-                    boolean sendRedacted = redactSensitiveNotificationsFromUntrustedListeners()
-                            && isNewSensitive && !isTrusted;
-                    boolean sendOldRedacted = redactSensitiveNotificationsFromUntrustedListeners()
-                            && isOldSensitive && !isTrusted;
+                    boolean sendRedacted = redactionEnabled && isNewSensitive && !isTrusted;
+                    boolean sendOldRedacted = redactionEnabled && isOldSensitive && !isTrusted;
                     boolean sbnVisible = isVisibleToListener(sbn, r.getNotificationType(), info);
                     boolean oldSbnVisible = (oldSbn != null)
                             && isVisibleToListener(oldSbn, old.getNotificationType(), info);
diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java
index bc987ed..ffc7c7b 100644
--- a/services/core/java/com/android/server/notification/NotificationShellCmd.java
+++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java
@@ -45,6 +45,7 @@
 import android.os.RemoteException;
 import android.os.ShellCommand;
 import android.os.UserHandle;
+import android.provider.Settings;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.StatusBarNotification;
 import android.text.TextUtils;
@@ -81,6 +82,7 @@
             + "  snooze --for <msec> <notification-key>\n"
             + "  unsnooze <notification-key>\n"
             + "  set_exempt_th_force_grouping [true|false]\n"
+            + "  redact_otp_from_untrusted_listeners [true|false]\n"
             ;
 
     private static final String NOTIFY_USAGE =
@@ -431,6 +433,14 @@
                     mDirectService.setTestHarnessExempted(exemptTestHarnessFromForceGrouping);
                     break;
                 }
+                case "redact_otp_from_untrusted_listeners": {
+                    String arg = getNextArgRequired();
+                    final int allow = "true".equals(arg) || "1".equals(arg) ? 1 : 0;
+                    Settings.Global.putInt(mDirectService.getContext().getContentResolver(),
+                            Settings.Global.REDACT_OTP_NOTIFICATIONS_FROM_UNTRUSTED_LISTENERS,
+                            allow);
+                    break;
+                }
                 default:
                     return handleDefaultCommands(cmd);
             }
diff --git a/services/core/java/com/android/server/notification/TEST_MAPPING b/services/core/java/com/android/server/notification/TEST_MAPPING
index dc7129cd..ea7ee4a 100644
--- a/services/core/java/com/android/server/notification/TEST_MAPPING
+++ b/services/core/java/com/android/server/notification/TEST_MAPPING
@@ -4,7 +4,10 @@
       "name": "CtsNotificationTestCases_notification"
     },
     {
-      "name": "FrameworksUiServicesTests_notification"
+      "name": "FrameworksUiServicesNotificationTests"
+    },
+    {
+      "name": "FrameworksUiServicesZenTests"
     }
   ],
   "postsubmit": [
diff --git a/services/core/java/com/android/server/notification/ZenConfigTrimmer.java b/services/core/java/com/android/server/notification/ZenConfigTrimmer.java
deleted file mode 100644
index d65954d..0000000
--- a/services/core/java/com/android/server/notification/ZenConfigTrimmer.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.notification;
-
-import android.content.Context;
-import android.os.Parcel;
-import android.service.notification.SystemZenRules;
-import android.service.notification.ZenModeConfig;
-import android.util.Slog;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-
-class ZenConfigTrimmer {
-
-    private static final String TAG = "ZenConfigTrimmer";
-    private static final int MAXIMUM_PARCELED_SIZE = 150_000; // bytes
-
-    private final HashSet<String> mTrustedPackages;
-
-    ZenConfigTrimmer(Context context) {
-        mTrustedPackages = new HashSet<>();
-        mTrustedPackages.add(SystemZenRules.PACKAGE_ANDROID);
-        mTrustedPackages.addAll(ConditionProviders.getDefaultDndAccessPackages(context));
-    }
-
-    void trimToMaximumSize(ZenModeConfig config) {
-        Map<String, PackageRules> rulesPerPackage = new HashMap<>();
-        for (ZenModeConfig.ZenRule rule : config.automaticRules.values()) {
-            PackageRules pkgRules = rulesPerPackage.computeIfAbsent(rule.pkg, PackageRules::new);
-            pkgRules.mRules.add(rule);
-        }
-
-        int totalSize = 0;
-        for (PackageRules pkgRules : rulesPerPackage.values()) {
-            totalSize += pkgRules.dataSize();
-        }
-
-        if (totalSize > MAXIMUM_PARCELED_SIZE) {
-            List<PackageRules> deletionCandidates = new ArrayList<>();
-            for (PackageRules pkgRules : rulesPerPackage.values()) {
-                if (!mTrustedPackages.contains(pkgRules.mPkg)) {
-                    deletionCandidates.add(pkgRules);
-                }
-            }
-            deletionCandidates.sort(Comparator.comparingInt(PackageRules::dataSize).reversed());
-
-            evictPackagesFromConfig(config, deletionCandidates, totalSize);
-        }
-    }
-
-    private static void evictPackagesFromConfig(ZenModeConfig config,
-            List<PackageRules> deletionCandidates, int currentSize) {
-        while (currentSize > MAXIMUM_PARCELED_SIZE && !deletionCandidates.isEmpty()) {
-            PackageRules rulesToDelete = deletionCandidates.removeFirst();
-            Slog.w(TAG, String.format("Evicting %s zen rules from package '%s' (%s bytes)",
-                    rulesToDelete.mRules.size(), rulesToDelete.mPkg, rulesToDelete.dataSize()));
-
-            for (ZenModeConfig.ZenRule rule : rulesToDelete.mRules) {
-                config.automaticRules.remove(rule.id);
-            }
-
-            currentSize -= rulesToDelete.dataSize();
-        }
-    }
-
-    private static class PackageRules {
-        private final String mPkg;
-        private final List<ZenModeConfig.ZenRule> mRules;
-        private int mParceledSize = -1;
-
-        PackageRules(String pkg) {
-            mPkg = pkg;
-            mRules = new ArrayList<>();
-        }
-
-        private int dataSize() {
-            if (mParceledSize >= 0) {
-                return mParceledSize;
-            }
-            Parcel parcel = Parcel.obtain();
-            try {
-                parcel.writeParcelableList(mRules, 0);
-                mParceledSize = parcel.dataSize();
-                return mParceledSize;
-            } finally {
-                parcel.recycle();
-            }
-        }
-    }
-}
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 8b09c2a..889df51 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -48,7 +48,6 @@
 import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
 import static com.android.internal.util.Preconditions.checkArgument;
 import static com.android.server.notification.Flags.preventZenDeviceEffectsWhileDriving;
-import static com.android.server.notification.Flags.limitZenConfigSize;
 
 import static java.util.Objects.requireNonNull;
 
@@ -193,7 +192,6 @@
     private final ConditionProviders.Config mServiceConfig;
     private final SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver;
     private final ZenModeEventLogger mZenModeEventLogger;
-    private final ZenConfigTrimmer mConfigTrimmer;
 
     @VisibleForTesting protected int mZenMode;
     @VisibleForTesting protected NotificationManager.Policy mConsolidatedPolicy;
@@ -228,7 +226,6 @@
         mClock = clock;
         addCallback(mMetrics);
         mAppOps = context.getSystemService(AppOpsManager.class);
-        mConfigTrimmer = new ZenConfigTrimmer(mContext);
 
         mDefaultConfig = Flags.modesUi()
                 ? ZenModeConfig.getDefaultConfig()
@@ -2064,20 +2061,20 @@
                 Log.w(TAG, "Invalid config in setConfigLocked; " + config);
                 return false;
             }
-            if (limitZenConfigSize() && (origin == ORIGIN_APP || origin == ORIGIN_USER_IN_APP)) {
-                mConfigTrimmer.trimToMaximumSize(config);
-            }
-
             if (config.user != mUser) {
                 // simply store away for background users
-                mConfigs.put(config.user, config);
+                synchronized (mConfigLock) {
+                    mConfigs.put(config.user, config);
+                }
                 if (DEBUG) Log.d(TAG, "setConfigLocked: store config for user " + config.user);
                 return true;
             }
             // handle CPS backed conditions - danger! may modify config
             mConditions.evaluateConfig(config, null, false /*processSubscriptions*/);
 
-            mConfigs.put(config.user, config);
+            synchronized (mConfigLock) {
+                mConfigs.put(config.user, config);
+            }
             if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable());
             ZenLog.traceConfig(origin, reason, triggeringComponent, mConfig, config, callingUid);
 
diff --git a/services/core/java/com/android/server/notification/flags.aconfig b/services/core/java/com/android/server/notification/flags.aconfig
index 346d65a..76cd5c8 100644
--- a/services/core/java/com/android/server/notification/flags.aconfig
+++ b/services/core/java/com/android/server/notification/flags.aconfig
@@ -212,16 +212,6 @@
 }
 
 flag {
-  name: "limit_zen_config_size"
-  namespace: "systemui"
-  description: "Enforce a maximum (serialized) size for the Zen configuration"
-  bug: "387498139"
-  metadata {
-    purpose: PURPOSE_BUGFIX
-  }
-}
-
-flag {
   name: "managed_services_concurrent_multiuser"
   namespace: "systemui"
   description: "Enables ManagedServices to support Concurrent multi user environment"
diff --git a/services/core/java/com/android/server/pm/ProtectedPackages.java b/services/core/java/com/android/server/pm/ProtectedPackages.java
index 524252c..e715881 100644
--- a/services/core/java/com/android/server/pm/ProtectedPackages.java
+++ b/services/core/java/com/android/server/pm/ProtectedPackages.java
@@ -20,6 +20,7 @@
 import android.annotation.UserIdInt;
 import android.content.Context;
 import android.os.UserHandle;
+import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.SparseArray;
 
@@ -27,6 +28,7 @@
 import com.android.internal.annotations.GuardedBy;
 
 import java.util.List;
+import java.util.Objects;
 import java.util.Set;
 
 /**
@@ -164,4 +166,13 @@
         return hasDeviceOwnerOrProfileOwner(userId, packageName)
                 || isProtectedPackage(userId, packageName);
     }
+
+    /**
+     * Returns {@code true} if a given package is the device provisioning package. Otherwise,
+     * returns {@code false}.
+     */
+    public synchronized boolean isDeviceProvisioningPackage(String packageName) {
+        return !TextUtils.isEmpty(mDeviceProvisioningPackage) && Objects.equals(
+                mDeviceProvisioningPackage, packageName);
+    }
 }
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index 1fda478..92e8eb9 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -133,6 +133,38 @@
       ]
     },
     {
+      "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases",
+      "file_patterns": [
+          "core/java/.*Install.*",
+          "services/core/.*Install.*",
+          "services/core/java/com/android/server/pm/.*"
+      ],
+      "options":[
+          {
+              "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+              "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
+    },
+    {
+      "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases",
+      "file_patterns": [
+          "core/java/.*Install.*",
+          "services/core/.*Install.*",
+          "services/core/java/com/android/server/pm/.*"
+      ],
+      "options":[
+          {
+              "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+              "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
+    },
+    {
       "name": "CtsPackageInstallerCUJMultiUsersTestCases",
       "file_patterns": [
         "core/java/.*Install.*",
@@ -288,6 +320,38 @@
       ]
     },
     {
+      "name": "CtsPackageInstallerCUJInstallationViaIntentForResultTestCases",
+      "file_patterns": [
+          "core/java/.*Install.*",
+          "services/core/.*Install.*",
+          "services/core/java/com/android/server/pm/.*"
+      ],
+      "options":[
+          {
+              "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+              "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
+    },
+    {
+      "name": "CtsPackageInstallerCUJInstallationViaSessionTestCases",
+      "file_patterns": [
+          "core/java/.*Install.*",
+          "services/core/.*Install.*",
+          "services/core/java/com/android/server/pm/.*"
+      ],
+      "options":[
+          {
+              "exclude-annotation":"androidx.test.filters.FlakyTest"
+          },
+          {
+              "exclude-annotation":"org.junit.Ignore"
+          }
+      ]
+    },
+    {
       "name": "CtsPackageInstallerCUJMultiUsersTestCases",
       "file_patterns": [
         "core/java/.*Install.*",
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 092ec8e..33a7e74 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1078,7 +1078,7 @@
         mUserVisibilityMediator = new UserVisibilityMediator(mHandler);
         mUserDataPreparer = userDataPreparer;
         mUserTypes = UserTypeFactory.getUserTypes();
-        invalidateOwnerNameIfNecessary(context.getResources(), true /* forceUpdate */);
+        invalidateOwnerNameIfNecessary(getContextResources(), true /* forceUpdate */);
         synchronized (mPackagesLock) {
             mUsersDir = new File(dataDir, USER_INFO_DIR);
             mUsersDir.mkdirs();
@@ -1184,6 +1184,15 @@
                 && android.multiuser.Flags.enablePrivateSpaceFeatures();
     }
 
+    private Resources getSystemResources() {
+        return android.multiuser.Flags.useUnifiedResources()
+                ? getContextResources() : Resources.getSystem();
+    }
+
+    private Resources getContextResources() {
+        return mContext.getResources();
+    }
+
     /**
      * This method retrieves the  {@link UserManagerInternal} only for the purpose of
      * PackageManagerService construction.
@@ -1223,7 +1232,7 @@
             // Avoid marking pre-created users for removal.
             return;
         }
-        if (ui.lastLoggedInTime == 0 && ui.isGuest() && Resources.getSystem().getBoolean(
+        if (ui.lastLoggedInTime == 0 && ui.isGuest() && getSystemResources().getBoolean(
                 com.android.internal.R.bool.config_guestUserAutoCreated)) {
             // Avoid marking auto-created but not-yet-logged-in guest user for removal. Because a
             // new one will be created anyway, and this one doesn't have any personal data in it yet
@@ -1402,7 +1411,7 @@
         }
 
         if (isHeadlessSystemUserMode()) {
-            final int bootStrategy = mContext.getResources()
+            final int bootStrategy = getContextResources()
                     .getInteger(com.android.internal.R.integer.config_hsumBootStrategy);
             switch (bootStrategy) {
                 case BOOT_TO_PREVIOUS_OR_FIRST_SWITCHABLE_USER:
@@ -2983,7 +2992,7 @@
     boolean isUserSwitcherEnabled(@UserIdInt int userId) {
         boolean multiUserSettingOn = Settings.Global.getInt(mContext.getContentResolver(),
                 Settings.Global.USER_SWITCHER_ENABLED,
-                Resources.getSystem().getBoolean(com.android.internal
+                getSystemResources().getBoolean(com.android.internal
                         .R.bool.config_showUserSwitcherByDefault) ? 1 : 0) != 0;
 
         return UserManager.supportsMultipleUsers()
@@ -4672,7 +4681,7 @@
             UserData userData = getUserDataNoChecks(UserHandle.USER_SYSTEM);
             if ("Primary".equals(userData.info.name)) {
                 userData.info.name =
-                        mContext.getResources().getString(com.android.internal.R.string.owner_name);
+                        getContextResources().getString(com.android.internal.R.string.owner_name);
                 userIdsToWrite.add(userData.info.id);
             }
             userVersion = 1;
@@ -5002,7 +5011,7 @@
 
         final Bundle restrictions = new Bundle();
         try {
-            final String[] defaultFirstUserRestrictions = mContext.getResources().getStringArray(
+            final String[] defaultFirstUserRestrictions = getContextResources().getStringArray(
                     com.android.internal.R.array.config_defaultFirstUserRestrictions);
             for (String userRestriction : defaultFirstUserRestrictions) {
                 if (UserRestrictionsUtils.isValidRestriction(userRestriction)) {
@@ -6178,7 +6187,7 @@
             // If the user switch hasn't been explicitly toggled on or off by the user, turn it on.
             if (android.provider.Settings.Global.getString(mContext.getContentResolver(),
                     android.provider.Settings.Global.USER_SWITCHER_ENABLED) == null) {
-                if (Resources.getSystem().getBoolean(
+                if (getSystemResources().getBoolean(
                         com.android.internal.R.bool.config_enableUserSwitcherUponUserCreation)) {
                     android.provider.Settings.Global.putInt(mContext.getContentResolver(),
                             android.provider.Settings.Global.USER_SWITCHER_ENABLED, 1);
@@ -7490,7 +7499,6 @@
         final long now = System.currentTimeMillis();
         final long nowRealtime = SystemClock.elapsedRealtime();
         final StringBuilder sb = new StringBuilder();
-        final Resources resources = Resources.getSystem();
 
         if (args != null && args.length > 0) {
             switch (args[0]) {
@@ -7573,13 +7581,14 @@
         pw.println();
         int effectiveMaxSupportedUsers = UserManager.getMaxSupportedUsers();
         pw.print("  Max users: " + effectiveMaxSupportedUsers);
-        int defaultMaxSupportedUsers = resources.getInteger(R.integer.config_multiuserMaximumUsers);
+        int defaultMaxSupportedUsers = getSystemResources()
+                .getInteger(R.integer.config_multiuserMaximumUsers);
         if (effectiveMaxSupportedUsers != defaultMaxSupportedUsers) {
             pw.print(" (built-in value: " + defaultMaxSupportedUsers + ")");
         }
         pw.println(" (limit reached: " + isUserLimitReached() + ")");
         pw.println("  Supports switchable users: " + UserManager.supportsMultipleUsers());
-        pw.println("  All guests ephemeral: " + resources.getBoolean(
+        pw.println("  All guests ephemeral: " + getSystemResources().getBoolean(
                 com.android.internal.R.bool.config_guestUserEphemeral));
         pw.println("  Force ephemeral users: " + mForceEphemeralUsers);
         final boolean isHeadlessSystemUserMode = isHeadlessSystemUserMode();
@@ -7594,7 +7603,7 @@
             }
         }
         if (isHeadlessSystemUserMode) {
-            pw.println("  Can switch to headless system user: " + resources
+            pw.println("  Can switch to headless system user: " + getSystemResources()
                     .getBoolean(com.android.internal.R.bool.config_canSwitchToHeadlessSystemUser));
         }
         pw.println("  User version: " + mUserVersion);
@@ -7715,6 +7724,7 @@
 
         pw.print("    Has profile owner: ");
         pw.println(mIsUserManaged.get(userId));
+
         pw.println("    Restrictions:");
         synchronized (mRestrictionsLock) {
             UserRestrictionsUtils.dumpRestrictions(
@@ -7747,6 +7757,9 @@
             }
         }
 
+        pw.print("    Can have profile: ");
+        pw.println(userInfo.canHaveProfile());
+
         if (userData.userProperties != null) {
             userData.userProperties.println(pw, "    ");
         }
@@ -8536,8 +8549,7 @@
      * or downgraded to non-admin status.
      */
     public boolean isMainUserPermanentAdmin() {
-        return Resources.getSystem()
-                .getBoolean(R.bool.config_isMainUserPermanentAdmin);
+        return getSystemResources().getBoolean(R.bool.config_isMainUserPermanentAdmin);
     }
 
     /**
@@ -8546,8 +8558,7 @@
      * it is not a full user.
      */
     public boolean canSwitchToHeadlessSystemUser() {
-        return Resources.getSystem()
-                .getBoolean(R.bool.config_canSwitchToHeadlessSystemUser);
+        return getSystemResources().getBoolean(R.bool.config_canSwitchToHeadlessSystemUser);
     }
 
     /**
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index c31c287..4ffdb11 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -235,15 +235,12 @@
                 this::synchronizeUidPermissionsAndAppOpsAsync);
 
         mAppOpsCallback = new IAppOpsCallback.Stub() {
-            public void opChanged(int op, int uid, @Nullable String packageName,
-                    String persistentDeviceId) {
+            public void opChanged(int op, int uid, String packageName, String persistentDeviceId) {
                 if (!Objects.equals(persistentDeviceId,
-                        VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT)) {
+                        VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT) || uid < 0) {
                     return;
                 }
-                if (packageName != null) {
-                    synchronizeUidPermissionsAndAppOpsAsync(uid);
-                }
+                synchronizeUidPermissionsAndAppOpsAsync(uid);
                 resetAppOpPermissionsIfNotRequestedForUidAsync(uid);
             }
         };
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 3230e89..38d4587 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5966,7 +5966,7 @@
             long whenNanos, int policyFlags) {
         if ((policyFlags & FLAG_WAKE) != 0) {
             if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source,
-                    action == MotionEvent.ACTION_DOWN)) {
+                    action == MotionEvent.ACTION_DOWN, mDeviceGoingToSleep)) {
                 // Woke up. Pass motion events to user.
                 return ACTION_PASS_TO_USER;
             }
@@ -5981,7 +5981,7 @@
         // wake up in this case.
         if (isTheaterModeEnabled() && (policyFlags & FLAG_WAKE) != 0) {
             if (mWindowWakeUpPolicy.wakeUpFromMotion(displayId, whenNanos / 1000000, source,
-                    action == MotionEvent.ACTION_DOWN)) {
+                    action == MotionEvent.ACTION_DOWN, mDeviceGoingToSleep)) {
                 // Woke up. Pass motion events to user.
                 return ACTION_PASS_TO_USER;
             }
diff --git a/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java b/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java
index 04dbd1f..0b5ec6e4 100644
--- a/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowWakeUpPolicy.java
@@ -149,16 +149,22 @@
      * @param displayId the id of the display to wake.
      * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}.
      * @param isDown {@code true} if the event's action is {@link MotionEvent#ACTION_DOWN}.
+     * @param deviceGoingToSleep {@code true} if the device is in the middle of going to sleep. This
+     *      will be {@code false} if the device is currently fully awake or is fully asleep
+     *      (i.e. not trying to go to sleep)
      * @return {@code true} if the policy allows the requested wake up and the request has been
      *      executed; {@code false} otherwise.
      */
-    boolean wakeUpFromMotion(int displayId, long eventTime, int source, boolean isDown) {
+    boolean wakeUpFromMotion(
+            int displayId, long eventTime, int source, boolean isDown,
+            boolean deviceGoingToSleep) {
         if (!canWakeUp(mAllowTheaterModeWakeFromMotion)) {
             if (DEBUG) Slog.d(TAG, "Unable to wake up from motion.");
             return false;
         }
         if (mInputWakeUpDelegate != null
-                && mInputWakeUpDelegate.wakeUpFromMotion(eventTime, source, isDown)) {
+                && mInputWakeUpDelegate.wakeUpFromMotion(
+                        eventTime, source, isDown, deviceGoingToSleep)) {
             return true;
         }
         if (perDisplayWakeByTouch()) {
diff --git a/services/core/java/com/android/server/policy/WindowWakeUpPolicyInternal.java b/services/core/java/com/android/server/policy/WindowWakeUpPolicyInternal.java
index 66a0035..962b5a7 100644
--- a/services/core/java/com/android/server/policy/WindowWakeUpPolicyInternal.java
+++ b/services/core/java/com/android/server/policy/WindowWakeUpPolicyInternal.java
@@ -52,10 +52,14 @@
          * @param eventTime the timestamp of the event in {@link SystemClock#uptimeMillis()}.
          * @param source the {@link android.view.InputDevice} source that caused the event.
          * @param isDown {@code true} if the event's action is {@link MotionEvent#ACTION_DOWN}.
+         * @param deviceGoingToSleep {@code true} if the device is in the middle of going to sleep.
+         *      This will be {@code false} if the device is currently fully awake or is fully
+         *      asleep (i.e. not trying to go to sleep)
          * @return {@code true} if the delegate handled the wake up. {@code false} if the delegate
          *      decided not to handle the wake up. The policy will execute the wake up in this case.
          */
-        boolean wakeUpFromMotion(long eventTime, int source, boolean isDown);
+        boolean wakeUpFromMotion(
+                long eventTime, int source, boolean isDown, boolean deviceGoingToSleep);
     }
 
     /**
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 102dc07..417b5c7 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -16,6 +16,7 @@
 
 package com.android.server.power;
 
+import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
 import android.annotation.UserIdInt;
@@ -36,8 +37,8 @@
 import android.os.BatteryStatsInternal;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.IWakeLockCallback;
 import android.os.IScreenTimeoutPolicyListener;
+import android.os.IWakeLockCallback;
 import android.os.Looper;
 import android.os.Message;
 import android.os.PowerManager;
@@ -67,6 +68,7 @@
 import com.android.internal.logging.MetricsLogger;
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
 import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.util.IndentingPrintWriter;
 import com.android.server.EventLogTags;
 import com.android.server.LocalServices;
 import com.android.server.input.InputManagerInternal;
@@ -147,7 +149,8 @@
     @Nullable private final StatusBarManagerInternal mStatusBarManagerInternal;
     private final TrustManager mTrustManager;
     private final Vibrator mVibrator;
-    private final WakeLockLog mWakeLockLog;
+    @NonNull private final WakeLockLog mPartialWakeLockLog;
+    @NonNull private final WakeLockLog mFullWakeLockLog;
     private final DisplayManagerInternal mDisplayManagerInternal;
 
     private final NotifierHandler mHandler;
@@ -250,7 +253,9 @@
         mShowWirelessChargingAnimationConfig = context.getResources().getBoolean(
                 com.android.internal.R.bool.config_showBuiltinWirelessChargingAnim);
 
-        mWakeLockLog = mInjector.getWakeLockLog(context);
+        mFullWakeLockLog = mInjector.getWakeLockLog(context);
+        mPartialWakeLockLog = mInjector.getWakeLockLog(context);
+
         // Initialize interactive state for battery stats.
         try {
             mBatteryStats.noteInteractive(true);
@@ -324,7 +329,8 @@
                     // Ignore
                 }
             }
-            mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, /*eventTime=*/ -1);
+            getWakeLockLog(flags).onWakeLockAcquired(tag,
+                    getUidForWakeLockLog(ownerUid, workSource), flags, /*eventTime=*/ -1);
         }
         mWakefulnessSessionObserver.onWakeLockAcquired(flags);
     }
@@ -473,7 +479,8 @@
                     // Ignore
                 }
             }
-            mWakeLockLog.onWakeLockReleased(tag, ownerUid, /*eventTime=*/ -1);
+            getWakeLockLog(flags).onWakeLockReleased(tag,
+                    getUidForWakeLockLog(ownerUid, workSource), /*eventTime=*/ -1);
         }
         mWakefulnessSessionObserver.onWakeLockReleased(flags, releaseReason);
     }
@@ -960,11 +967,18 @@
      * @param pw The stream to print to.
      */
     public void dump(PrintWriter pw) {
-        if (mWakeLockLog != null) {
-            mWakeLockLog.dump(pw);
-        }
+        pw.println("Notifier:");
 
-        mWakefulnessSessionObserver.dump(pw);
+        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
+        ipw.println("Partial Wakelock Log:");
+        mPartialWakeLockLog.dump(ipw);
+
+        ipw.println("");
+        ipw.println("Full Wakelock Log:");
+        mFullWakeLockLog.dump(ipw);
+
+        ipw.println("");
+        mWakefulnessSessionObserver.dump(ipw);
     }
 
     private void updatePendingBroadcastLocked() {
@@ -1232,7 +1246,9 @@
                 // Do Nothing
             }
         }
-        mWakeLockLog.onWakeLockAcquired(tag, ownerUid, flags, currentTime);
+
+        getWakeLockLog(flags).onWakeLockAcquired(tag, getUidForWakeLockLog(ownerUid, workSource),
+                flags, currentTime);
     }
 
     @SuppressLint("AndroidFrameworkRequiresPermission")
@@ -1253,7 +1269,8 @@
                 // Ignore
             }
         }
-        mWakeLockLog.onWakeLockReleased(tag, ownerUid, currentTime);
+        getWakeLockLog(flags).onWakeLockReleased(tag, getUidForWakeLockLog(ownerUid, workSource),
+                currentTime);
     }
 
     @SuppressLint("AndroidFrameworkRequiresPermission")
@@ -1419,6 +1436,15 @@
         }
     }
 
+    private @NonNull WakeLockLog getWakeLockLog(int flags) {
+        return PowerManagerService.isScreenLock(flags) ? mFullWakeLockLog : mPartialWakeLockLog;
+    }
+
+    private int getUidForWakeLockLog(int ownerUid, WorkSource workSource) {
+        int attributionUid = workSource != null ? workSource.getAttributionUid() : -1;
+        return attributionUid != -1 ? attributionUid : ownerUid;
+    }
+
     private final class NotifierHandler extends Handler {
 
         public NotifierHandler(Looper looper) {
@@ -1501,7 +1527,7 @@
         /**
          * Gets the WakeLockLog object
          */
-        WakeLockLog getWakeLockLog(Context context);
+        @NonNull WakeLockLog getWakeLockLog(Context context);
 
         /**
          * Gets the AppOpsManager system service
@@ -1522,7 +1548,7 @@
         }
 
         @Override
-        public WakeLockLog getWakeLockLog(Context context) {
+        public @NonNull WakeLockLog getWakeLockLog(Context context) {
             return new WakeLockLog(context);
         }
 
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index dd454cd..3eac4b5 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -1723,9 +1723,16 @@
         }
     }
 
-    @SuppressWarnings("deprecation")
     private static boolean isScreenLock(final WakeLock wakeLock) {
-        switch (wakeLock.mFlags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
+        return isScreenLock(wakeLock.mFlags);
+    }
+
+    /**
+     * Returns if a wakelock flag corresponds to a screen wake lock.
+     */
+    @SuppressWarnings("deprecation")
+    public static boolean isScreenLock(int flags) {
+        switch (flags & PowerManager.WAKE_LOCK_LEVEL_MASK) {
             case PowerManager.FULL_WAKE_LOCK:
             case PowerManager.SCREEN_BRIGHT_WAKE_LOCK:
             case PowerManager.SCREEN_DIM_WAKE_LOCK:
diff --git a/services/core/java/com/android/server/power/WakeLockLog.java b/services/core/java/com/android/server/power/WakeLockLog.java
index eda222e..7f152d6 100644
--- a/services/core/java/com/android/server/power/WakeLockLog.java
+++ b/services/core/java/com/android/server/power/WakeLockLog.java
@@ -81,11 +81,12 @@
     private static final int TYPE_ACQUIRE = 0x1;
     private static final int TYPE_RELEASE = 0x2;
     private static final int MAX_LOG_ENTRY_BYTE_SIZE = 9;
-    private static final int LOG_SIZE = 1024 * 10;
+    private static final int LOG_SIZE = 1024 * 3;
     private static final int LOG_SIZE_MIN = MAX_LOG_ENTRY_BYTE_SIZE + 1;
 
-    private static final int TAG_DATABASE_SIZE = 128;
+    private static final int TAG_DATABASE_SIZE = 64;
     private static final int TAG_DATABASE_SIZE_MAX = 128;
+    private static final int TAG_DATABASE_STARTING_SIZE = 16;
 
     private static final int LEVEL_SCREEN_TIMEOUT_OVERRIDE_WAKE_LOCK = 0;
     private static final int LEVEL_PARTIAL_WAKE_LOCK = 1;
@@ -182,7 +183,7 @@
      * @param pw The {@code PrintWriter} to write to.
      */
     public void dump(PrintWriter pw) {
-        dump(pw, false);
+        dump(pw, /* includeTagDb= */ true);
     }
 
     @VisibleForTesting
@@ -1161,15 +1162,16 @@
      */
     static class TagDatabase {
         private final int mInvalidIndex;
-        private final TagData[] mArray;
+        private final int mMaxArraySize;
+        private TagData[] mArray;
         private Callback mCallback;
 
         TagDatabase(Injector injector) {
-            int size = Math.min(injector.getTagDatabaseSize(), TAG_DATABASE_SIZE_MAX);
-
-            // Largest possible index used as "INVALID", hence the (size - 1) sizing.
-            mArray = new TagData[size - 1];
-            mInvalidIndex = size - 1;
+            // Largest possible index used as "INVALID", hence the (size - 1) sizing
+            mMaxArraySize = Math.min(injector.getTagDatabaseSize(), TAG_DATABASE_SIZE_MAX - 1);
+            int startingSize = Math.min(mMaxArraySize, injector.getTagDatabaseStartingSize());
+            mArray = new TagData[startingSize];
+            mInvalidIndex = mMaxArraySize;
         }
 
         @Override
@@ -1195,8 +1197,10 @@
             sb.append(", entries: ").append(entries);
             sb.append(", Bytes used: ").append(byteEstimate);
             if (DEBUG) {
-                sb.append(", Avg tag size: ").append(tagSize / tags);
-                sb.append("\n    ").append(Arrays.toString(mArray));
+                sb.append(", Avg tag size: ").append(tags == 0 ? 0 : (tagSize / tags));
+                for (int i = 0; i < mArray.length; i++) {
+                    sb.append("\n  [").append(i).append("] ").append(mArray[i]);
+                }
             }
             return sb.toString();
         }
@@ -1284,6 +1288,18 @@
                 return null;
             }
 
+            // We don't have a spot available, see if we can still increase the array size
+            if (firstAvailable == -1) {
+                if (mArray.length < mMaxArraySize) {
+                    int oldSize = mArray.length;
+                    int newSize = Math.min(oldSize * 2, mMaxArraySize);
+                    TagData[] newArray = new TagData[newSize];
+                    System.arraycopy(mArray, 0, newArray, 0, oldSize);
+                    mArray = newArray;
+                    firstAvailable = oldSize;
+                }
+            }
+
             // If we need to remove an index, report to listeners that we are removing an index.
             boolean useOldest = firstAvailable == -1;
             if (useOldest && mCallback != null) {
@@ -1402,6 +1418,10 @@
             return TAG_DATABASE_SIZE;
         }
 
+        public int getTagDatabaseStartingSize() {
+            return TAG_DATABASE_STARTING_SIZE;
+        }
+
         public int getLogSize() {
             return LOG_SIZE;
         }
diff --git a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
index ebc50fd..52d4555 100644
--- a/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
+++ b/services/core/java/com/android/server/power/feature/PowerManagerFlags.java
@@ -67,6 +67,10 @@
             new FlagState(Flags.FLAG_WAKELOCK_ATTRIBUTION_VIA_WORKCHAIN,
                     Flags::wakelockAttributionViaWorkchain);
 
+    private final FlagState mDisableFrozenProcessWakelocks =
+            new FlagState(Flags.FLAG_DISABLE_FROZEN_PROCESS_WAKELOCKS,
+                    Flags::disableFrozenProcessWakelocks);
+
     /** Returns whether early-screen-timeout-detector is enabled on not. */
     public boolean isEarlyScreenTimeoutDetectorEnabled() {
         return mEarlyScreenTimeoutDetectorFlagState.isEnabled();
@@ -121,6 +125,13 @@
     }
 
     /**
+     * @return Whether the feature to disable the frozen process wakelocks is enabled
+     */
+    public boolean isDisableFrozenProcessWakelocksEnabled() {
+        return mDisableFrozenProcessWakelocks.isEnabled();
+    }
+
+    /**
      * dumps all flagstates
      * @param pw printWriter
      */
@@ -132,6 +143,7 @@
         pw.println(" " + mFrameworkWakelockInfo);
         pw.println(" " + mMoveWscLoggingToNotifier);
         pw.println(" " + mWakelockAttributionViaWorkchain);
+        pw.println(" " + mDisableFrozenProcessWakelocks);
     }
 
     private static class FlagState {
diff --git a/services/core/java/com/android/server/power/feature/power_flags.aconfig b/services/core/java/com/android/server/power/feature/power_flags.aconfig
index fefe195..ad8ec03 100644
--- a/services/core/java/com/android/server/power/feature/power_flags.aconfig
+++ b/services/core/java/com/android/server/power/feature/power_flags.aconfig
@@ -70,3 +70,10 @@
     description: "Feature flag to move logging of WakelockStateChanged atoms from BatteryStatsImpl to Notifier."
     bug: "352602149"
 }
+
+flag {
+    name: "disable_frozen_process_wakelocks"
+    namespace: "power"
+    description: "Feature flag to disable/enable wakelocks of a process when it is frozen/unfrozen"
+    bug: "291115867"
+}
diff --git a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
index 93fd276..8c3b7c6 100644
--- a/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
+++ b/services/core/java/com/android/server/security/advancedprotection/AdvancedProtectionService.java
@@ -17,13 +17,17 @@
 package com.android.server.security.advancedprotection;
 
 import static android.provider.Settings.Secure.ADVANCED_PROTECTION_MODE;
+import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
 
 import android.Manifest;
 import android.annotation.EnforcePermission;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.app.StatsManager;
 import android.content.Context;
+import android.content.SharedPreferences;
 import android.os.Binder;
+import android.os.Environment;
 import android.os.Handler;
 import android.os.IBinder;
 import android.os.Looper;
@@ -32,14 +36,22 @@
 import android.os.RemoteException;
 import android.os.ResultReceiver;
 import android.os.ShellCallback;
+import android.os.UserHandle;
 import android.provider.Settings;
 import android.security.advancedprotection.AdvancedProtectionFeature;
+import android.security.advancedprotection.AdvancedProtectionManager;
+import android.security.advancedprotection.AdvancedProtectionManager.FeatureId;
+import android.security.advancedprotection.AdvancedProtectionManager.SupportDialogType;
 import android.security.advancedprotection.IAdvancedProtectionCallback;
 import android.security.advancedprotection.IAdvancedProtectionService;
+import android.security.advancedprotection.AdvancedProtectionProtoEnums;
 import android.util.ArrayMap;
 import android.util.Slog;
+import android.util.StatsEvent;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.FrameworkStatsLog;
 import com.android.server.FgThread;
 import com.android.server.LocalServices;
 import com.android.server.SystemService;
@@ -50,8 +62,11 @@
 import com.android.server.security.advancedprotection.features.DisallowInstallUnknownSourcesAdvancedProtectionHook;
 import com.android.server.security.advancedprotection.features.MemoryTaggingExtensionHook;
 import com.android.server.security.advancedprotection.features.UsbDataAdvancedProtectionHook;
+import com.android.server.security.advancedprotection.features.DisallowWepAdvancedProtectionProvider;
 
+import java.io.File;
 import java.io.FileDescriptor;
+import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -61,6 +76,15 @@
     private static final int MODE_CHANGED = 0;
     private static final int CALLBACK_ADDED = 1;
 
+    // Shared preferences keys
+    private static final String PREFERENCE = "advanced_protection_preference";
+    private static final String ENABLED_CHANGE_TIME = "enabled_change_time";
+    private static final String LAST_DIALOG_FEATURE_ID = "last_dialog_feature_id";
+    private static final String LAST_DIALOG_TYPE = "last_dialog_type";
+    private static final String LAST_DIALOG_HOURS_SINCE_ENABLED = "last_dialog_hours_since_enabled";
+    private static final String LAST_DIALOG_LEARN_MORE_CLICKED = "last_dialog_learn_more_clicked";
+    private static final long MILLIS_PER_HOUR = 60 * 60 * 1000;
+
     private final Context mContext;
     private final Handler mHandler;
     private final AdvancedProtectionStore mStore;
@@ -72,6 +96,10 @@
     // For tracking only - not called on state change
     private final ArrayList<AdvancedProtectionProvider> mProviders = new ArrayList<>();
 
+    // Used to store logging data
+    private SharedPreferences mSharedPreferences;
+    private boolean mEmitLogs = true;
+
     private AdvancedProtectionService(@NonNull Context context) {
         super(PermissionEnforcer.fromContext(context));
         mContext = context;
@@ -107,7 +135,18 @@
           } catch (Exception e) {
             Slog.e(TAG, "Failed to initialize UsbDataAdvancedProtection", e);
           }
-      }
+        }
+
+        mProviders.add(new DisallowWepAdvancedProtectionProvider());
+    }
+
+    private void initLogging() {
+        StatsManager statsManager = mContext.getSystemService(StatsManager.class);
+        statsManager.setPullAtomCallback(
+                FrameworkStatsLog.ADVANCED_PROTECTION_STATE_INFO,
+                null, // use default PullAtomMetadata values
+                DIRECT_EXECUTOR,
+                new AdvancedProtectionStatePullAtomCallback());
     }
 
     // Only for tests
@@ -126,6 +165,8 @@
         if (provider != null) {
             mProviders.add(provider);
         }
+
+        mEmitLogs = false;
     }
 
     @Override
@@ -178,7 +219,7 @@
                 if (enabled != isAdvancedProtectionEnabledInternal()) {
                     mStore.store(enabled);
                     sendModeChanged(enabled);
-                    Slog.i(TAG, "Advanced protection is " + (enabled ? "enabled" : "disabled"));
+                    logAdvancedProtectionEnabled(enabled);
                 }
             }
         } finally {
@@ -188,11 +229,96 @@
 
     @Override
     @EnforcePermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
+    public void logDialogShown(@FeatureId int featureId, @SupportDialogType int type,
+            boolean learnMoreClicked) {
+        logDialogShown_enforcePermission();
+
+        if (!mEmitLogs) {
+            return;
+        }
+
+        int hoursSinceEnabled = hoursSinceLastChange();
+        FrameworkStatsLog.write(FrameworkStatsLog.ADVANCED_PROTECTION_SUPPORT_DIALOG_DISPLAYED,
+                /*feature_id*/ featureIdToLogEnum(featureId),
+                /*dialogue_type*/ dialogueTypeToLogEnum(type),
+                /*learn_more_clicked*/ learnMoreClicked,
+                /*hours_since_last_change*/ hoursSinceEnabled);
+
+        getSharedPreferences().edit()
+                .putInt(LAST_DIALOG_FEATURE_ID, featureId)
+                .putInt(LAST_DIALOG_TYPE, type)
+                .putBoolean(LAST_DIALOG_LEARN_MORE_CLICKED, learnMoreClicked)
+                .putInt(LAST_DIALOG_HOURS_SINCE_ENABLED, hoursSinceEnabled)
+                .apply();
+    }
+
+    private int featureIdToLogEnum(@FeatureId int featureId) {
+        switch (featureId) {
+            case AdvancedProtectionManager.FEATURE_ID_DISALLOW_CELLULAR_2G:
+                return AdvancedProtectionProtoEnums.FEATURE_ID_DISALLOW_CELLULAR_2G;
+            case AdvancedProtectionManager.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES:
+                return AdvancedProtectionProtoEnums.FEATURE_ID_DISALLOW_INSTALL_UNKNOWN_SOURCES;
+            case AdvancedProtectionManager.FEATURE_ID_DISALLOW_USB:
+                return AdvancedProtectionProtoEnums.FEATURE_ID_DISALLOW_USB;
+            case AdvancedProtectionManager.FEATURE_ID_DISALLOW_WEP:
+                return AdvancedProtectionProtoEnums.FEATURE_ID_DISALLOW_WEP;
+            case AdvancedProtectionManager.FEATURE_ID_ENABLE_MTE:
+                return AdvancedProtectionProtoEnums.FEATURE_ID_ENABLE_MTE;
+            default:
+                return AdvancedProtectionProtoEnums.FEATURE_ID_UNKNOWN;
+        }
+    }
+
+    private int dialogueTypeToLogEnum(@SupportDialogType int type) {
+        switch (type) {
+            case AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_UNKNOWN:
+                return AdvancedProtectionProtoEnums.DIALOGUE_TYPE_UNKNOWN;
+            case AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_BLOCKED_INTERACTION:
+                return AdvancedProtectionProtoEnums.DIALOGUE_TYPE_BLOCKED_INTERACTION;
+            case AdvancedProtectionManager.SUPPORT_DIALOG_TYPE_DISABLED_SETTING:
+                return AdvancedProtectionProtoEnums.DIALOGUE_TYPE_DISABLED_SETTING;
+            default:
+                return AdvancedProtectionProtoEnums.DIALOGUE_TYPE_UNKNOWN;
+        }
+    }
+
+    private void logAdvancedProtectionEnabled(boolean enabled) {
+        if (!mEmitLogs) {
+            return;
+        }
+
+        Slog.i(TAG, "Advanced protection has been " + (enabled ? "enabled" : "disabled"));
+        SharedPreferences prefs = getSharedPreferences();
+        FrameworkStatsLog.write(FrameworkStatsLog.ADVANCED_PROTECTION_STATE_CHANGED,
+                /*enabled*/ enabled,
+                /*hours_since_enabled*/ hoursSinceLastChange(),
+                /*last_dialog_feature_id*/ featureIdToLogEnum(
+                    prefs.getInt(LAST_DIALOG_FEATURE_ID, -1)),
+                /*_type*/ dialogueTypeToLogEnum(prefs.getInt(LAST_DIALOG_TYPE, -1)),
+                /*_learn_more_clicked*/ prefs.getBoolean(LAST_DIALOG_LEARN_MORE_CLICKED, false),
+                /*_hours_since_enabled*/ prefs.getInt(LAST_DIALOG_HOURS_SINCE_ENABLED, -1));
+        prefs.edit()
+                .putLong(ENABLED_CHANGE_TIME, System.currentTimeMillis())
+                .apply();
+    }
+
+    private int hoursSinceLastChange() {
+        int hoursSinceEnabled = -1;
+        long lastChangeTimeMillis = getSharedPreferences().getLong(ENABLED_CHANGE_TIME, -1);
+        if (lastChangeTimeMillis != -1) {
+            hoursSinceEnabled = (int)
+                    ((System.currentTimeMillis() - lastChangeTimeMillis) / MILLIS_PER_HOUR);
+        }
+        return hoursSinceEnabled;
+    }
+
+    @Override
+    @EnforcePermission(Manifest.permission.MANAGE_ADVANCED_PROTECTION_MODE)
     public List<AdvancedProtectionFeature> getAdvancedProtectionFeatures() {
         getAdvancedProtectionFeatures_enforcePermission();
         List<AdvancedProtectionFeature> features = new ArrayList<>();
         for (int i = 0; i < mProviders.size(); i++) {
-            features.addAll(mProviders.get(i).getFeatures());
+            features.addAll(mProviders.get(i).getFeatures(mContext));
         }
 
         for (int i = 0; i < mHooks.size(); i++) {
@@ -213,6 +339,30 @@
                 .exec(this, in, out, err, args, callback, resultReceiver);
     }
 
+    @Override
+    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
+        if (!DumpUtils.checkDumpPermission(mContext, TAG, writer)) return;
+        writer.println("AdvancedProtectionService");
+        writer.println("  isAdvancedProtectionEnabled: " + isAdvancedProtectionEnabledInternal());
+        writer.println("  mHooks.size(): " + mHooks.size());
+        writer.println("  mCallbacks.size(): " + mCallbacks.size());
+        writer.println("  mProviders.size(): " + mProviders.size());
+
+        writer.println("Hooks: ");
+        mHooks.stream().forEach(hook -> {
+            writer.println("    " + hook.getClass().getSimpleName() +
+                                   " available: " + hook.isAvailable());
+        });
+        writer.println("  Providers: ");
+        mProviders.stream().forEach(provider -> {
+            writer.println("    " + provider.getClass().getSimpleName());
+            provider.getFeatures(mContext).stream().forEach(feature -> {
+                writer.println("      " + feature.getClass().getSimpleName());
+            });
+        });
+        writer.println("  mSharedPreferences: " + getSharedPreferences().getAll());
+    }
+
     void sendModeChanged(boolean enabled) {
         Message.obtain(mHandler, MODE_CHANGED, /*enabled*/ enabled ? 1 : 0, /*unused */ -1)
                 .sendToTarget();
@@ -224,6 +374,22 @@
                 .sendToTarget();
     }
 
+    private SharedPreferences getSharedPreferences() {
+        if (mSharedPreferences == null) {
+            initSharedPreferences();
+        }
+        return mSharedPreferences;
+    }
+
+    private synchronized void initSharedPreferences() {
+        if (mSharedPreferences == null) {
+            Context deviceContext = mContext.createDeviceProtectedStorageContext();
+            File sharedPrefs = new File(Environment.getDataSystemDirectory(), PREFERENCE);
+            mSharedPreferences = deviceContext.getSharedPreferences(sharedPrefs,
+                    Context.MODE_PRIVATE);
+        }
+    }
+
     public static final class Lifecycle extends SystemService {
         private final AdvancedProtectionService mService;
 
@@ -245,6 +411,7 @@
                     Slog.i(TAG, "Advanced protection is enabled");
                 }
                 mService.initFeatures(enabled);
+                mService.initLogging();
             }
         }
     }
@@ -346,4 +513,22 @@
             }
         }
     }
+
+    private class AdvancedProtectionStatePullAtomCallback
+            implements StatsManager.StatsPullAtomCallback {
+
+        @Override
+        public int onPullAtom(int atomTag, List<StatsEvent> data) {
+            if (atomTag != FrameworkStatsLog.ADVANCED_PROTECTION_STATE_INFO) {
+                return StatsManager.PULL_SKIP;
+            }
+
+            data.add(
+                    FrameworkStatsLog.buildStatsEvent(
+                            FrameworkStatsLog.ADVANCED_PROTECTION_STATE_INFO,
+                            /*enabled*/ isAdvancedProtectionEnabledInternal(),
+                            /*hours_since_enabled*/ hoursSinceLastChange()));
+            return StatsManager.PULL_SUCCESS;
+        }
+    }
 }
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java b/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java
index ed451f1..6498cfc 100644
--- a/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java
+++ b/services/core/java/com/android/server/security/advancedprotection/features/AdvancedProtectionProvider.java
@@ -16,6 +16,8 @@
 
 package com.android.server.security.advancedprotection.features;
 
+import android.annotation.NonNull;
+import android.content.Context;
 import android.security.advancedprotection.AdvancedProtectionFeature;
 
 import java.util.List;
@@ -23,5 +25,5 @@
 /** @hide */
 public abstract class AdvancedProtectionProvider {
     /** The list of features provided */
-    public abstract List<AdvancedProtectionFeature> getFeatures();
+    public abstract List<AdvancedProtectionFeature> getFeatures(@NonNull Context context);
 }
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java
index be26334..bf464be 100644
--- a/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java
+++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowCellular2GAdvancedProtectionHook.java
@@ -22,16 +22,11 @@
 import android.annotation.NonNull;
 import android.app.admin.DevicePolicyManager;
 import android.content.Context;
+import android.content.pm.PackageManager;
 import android.os.UserManager;
 import android.security.advancedprotection.AdvancedProtectionFeature;
-import android.telephony.SubscriptionInfo;
-import android.telephony.SubscriptionManager;
-import android.telephony.TelephonyManager;
 import android.util.Slog;
 
-import java.util.ArrayList;
-import java.util.List;
-
 /** @hide */
 public final class DisallowCellular2GAdvancedProtectionHook extends AdvancedProtectionHook {
     private static final String TAG = "AdvancedProtectionDisallowCellular2G";
@@ -39,14 +34,12 @@
     private final AdvancedProtectionFeature mFeature =
             new AdvancedProtectionFeature(FEATURE_ID_DISALLOW_CELLULAR_2G);
     private final DevicePolicyManager mDevicePolicyManager;
-    private final TelephonyManager mTelephonyManager;
-    private final SubscriptionManager mSubscriptionManager;
+    private final PackageManager mPackageManager;
 
     public DisallowCellular2GAdvancedProtectionHook(@NonNull Context context, boolean enabled) {
         super(context, enabled);
         mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
-        mTelephonyManager = context.getSystemService(TelephonyManager.class);
-        mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+        mPackageManager = context.getPackageManager();
 
         onAdvancedProtectionChanged(enabled);
     }
@@ -57,40 +50,9 @@
         return mFeature;
     }
 
-    private static boolean isEmbeddedSubscriptionVisible(SubscriptionInfo subInfo) {
-        if (subInfo.isEmbedded()
-                && (subInfo.getProfileClass() == SubscriptionManager.PROFILE_CLASS_PROVISIONING
-                        || subInfo.isOnlyNonTerrestrialNetwork())) {
-            return false;
-        }
-
-        return true;
-    }
-
-    private List<TelephonyManager> getActiveTelephonyManagers() {
-        List<TelephonyManager> telephonyManagers = new ArrayList<>();
-
-        for (SubscriptionInfo subInfo : mSubscriptionManager.getActiveSubscriptionInfoList()) {
-            if (isEmbeddedSubscriptionVisible(subInfo)) {
-                telephonyManagers.add(
-                        mTelephonyManager.createForSubscriptionId(subInfo.getSubscriptionId()));
-            }
-        }
-
-        return telephonyManagers;
-    }
-
     @Override
     public boolean isAvailable() {
-        for (TelephonyManager telephonyManager : getActiveTelephonyManagers()) {
-            if (telephonyManager.isDataCapable()
-                    && telephonyManager.isRadioInterfaceCapabilitySupported(
-                            mTelephonyManager.CAPABILITY_USES_ALLOWED_NETWORK_TYPES_BITMASK)) {
-                return true;
-            }
-        }
-
-        return false;
+        return mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY);
     }
 
     @Override
diff --git a/services/core/java/com/android/server/security/advancedprotection/features/DisallowWepAdvancedProtectionProvider.java b/services/core/java/com/android/server/security/advancedprotection/features/DisallowWepAdvancedProtectionProvider.java
new file mode 100644
index 0000000..1505f68
--- /dev/null
+++ b/services/core/java/com/android/server/security/advancedprotection/features/DisallowWepAdvancedProtectionProvider.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.security.advancedprotection.features;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.net.wifi.WifiManager;
+import android.security.advancedprotection.AdvancedProtectionFeature;
+
+import java.util.List;
+
+public class DisallowWepAdvancedProtectionProvider extends AdvancedProtectionProvider {
+    public List<AdvancedProtectionFeature> getFeatures(@NonNull Context context) {
+        WifiManager wifiManager = context.getSystemService(WifiManager.class);
+        return wifiManager.getAvailableAdvancedProtectionFeatures();
+    }
+}
diff --git a/services/core/java/com/android/server/sensors/OWNERS b/services/core/java/com/android/server/sensors/OWNERS
new file mode 100644
index 0000000..6b22473
--- /dev/null
+++ b/services/core/java/com/android/server/sensors/OWNERS
@@ -0,0 +1 @@
+include platform/frameworks/native:/services/sensorservice/OWNERS
diff --git a/services/core/java/com/android/server/sensors/SensorManagerInternal.java b/services/core/java/com/android/server/sensors/SensorManagerInternal.java
index 7ff4ade..9636cc6 100644
--- a/services/core/java/com/android/server/sensors/SensorManagerInternal.java
+++ b/services/core/java/com/android/server/sensors/SensorManagerInternal.java
@@ -17,6 +17,7 @@
 package com.android.server.sensors;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.hardware.SensorDirectChannel;
 import android.os.ParcelFileDescriptor;
 
@@ -71,7 +72,7 @@
     /**
      * Sends an event for the runtime sensor with the given handle to the framework.
      *
-     * Only relevant for sending runtime sensor events. @see #createRuntimeSensor.
+     * <p>Only relevant for sending runtime sensor events. @see #createRuntimeSensor.</p>
      *
      * @param handle The sensor handle.
      * @param type The type of the sensor.
@@ -83,6 +84,21 @@
             @NonNull float[] values);
 
     /**
+     * Sends an additional info event for the runtime sensor with the given handle to the framework.
+     *
+     * <p>Only relevant for runtime sensors. @see #createRuntimeSensor.</p>
+     *
+     * @param handle The sensor handle.
+     * @param type The type of payload data.
+     * @param serial The sequence number of this frame for this type.
+     * @param timestampNanos Timestamp of the event.
+     * @param values The payload data represented in float values.
+     * @return Whether the event injection was successful.
+     */
+    public abstract boolean sendSensorAdditionalInfo(int handle, int type, int serial,
+            long timestampNanos, @Nullable float[] values);
+
+    /**
      * Listener for proximity sensor state changes.
      */
     public interface ProximityActiveListener {
diff --git a/services/core/java/com/android/server/sensors/SensorService.java b/services/core/java/com/android/server/sensors/SensorService.java
index 3de1910..0d31b22 100644
--- a/services/core/java/com/android/server/sensors/SensorService.java
+++ b/services/core/java/com/android/server/sensors/SensorService.java
@@ -19,6 +19,7 @@
 import static com.android.server.sensors.SensorManagerInternal.ProximityActiveListener;
 
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.content.Context;
 import android.util.ArrayMap;
 
@@ -62,6 +63,9 @@
     private static native void unregisterRuntimeSensorNative(long ptr, int handle);
     private static native boolean sendRuntimeSensorEventNative(long ptr, int handle, int type,
             long timestampNanos, float[] values);
+    private static native boolean sendRuntimeSensorAdditionalInfoNative(long ptr, int handle,
+            int type, int serial, long timestampNanos, float[] values);
+
 
     public SensorService(Context ctx) {
         super(ctx);
@@ -129,6 +133,18 @@
         }
 
         @Override
+        public boolean sendSensorAdditionalInfo(int handle, int type, int serial,
+                long timestampNanos, @Nullable float[] values) {
+            synchronized (mLock) {
+                if (!mRuntimeSensorHandles.contains(handle)) {
+                    return false;
+                }
+                return sendRuntimeSensorAdditionalInfoNative(mPtr, handle, type, serial,
+                        timestampNanos, values);
+            }
+        }
+
+        @Override
         public void addProximityActiveListener(@NonNull Executor executor,
                 @NonNull ProximityActiveListener listener) {
             Objects.requireNonNull(executor, "executor must not be null");
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
index 6e640d8..e22bc7d 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperCropper.java
@@ -856,9 +856,13 @@
             BitmapFactory.decodeFile(wallpaperFile.getAbsolutePath(), options);
             wallpaperImageSize.set(options.outWidth, options.outHeight);
         }
+        boolean isRtl = TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())
+                == View.LAYOUT_DIRECTION_RTL;
+        Rect croppedImageBound = getCrop(displaySize, mDefaultDisplayInfo, wallpaperImageSize,
+                getRelativeCropHints(wallpaperData), isRtl);
 
-        double maxDisplayToImageRatio = Math.max((double) displaySize.x / wallpaperImageSize.x,
-                (double) displaySize.y / wallpaperImageSize.y);
+        double maxDisplayToImageRatio = Math.max((double) displaySize.x / croppedImageBound.width(),
+                (double) displaySize.y / croppedImageBound.height());
         if (maxDisplayToImageRatio > 1.5) {
             return false;
         }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java
index f413fe3..58f34d0 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerInternal.java
@@ -36,7 +36,4 @@
 
     /** Notifies when the screen starts turning on and is not yet visible to the user. */
     public abstract void onScreenTurningOn(int displayId);
-
-    /** Notifies when the keyguard is going away. Sent right after the bouncer is gone. */
-    public abstract void onKeyguardGoingAway();
 }
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index e7da33d..274175a 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -22,6 +22,7 @@
 import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
 import static android.app.Flags.fixWallpaperChanged;
 import static android.app.Flags.liveWallpaperContentHandling;
+import static android.app.Flags.notifyKeyguardEvents;
 import static android.app.Flags.removeNextWallpaperComponent;
 import static android.app.WallpaperManager.COMMAND_REAPPLY;
 import static android.app.WallpaperManager.FLAG_LOCK;
@@ -1709,8 +1710,32 @@
         mWallpaperDataParser = new WallpaperDataParser(mContext, mWallpaperDisplayHelper,
                 mWallpaperCropper);
         LocalServices.addService(WallpaperManagerInternal.class, new LocalService());
+
+        LocalServices.getService(ActivityTaskManagerInternal.class)
+                .registerScreenObserver(mKeyguardObserver);
+
     }
 
+    private final ActivityTaskManagerInternal.ScreenObserver mKeyguardObserver =
+            new ActivityTaskManagerInternal.ScreenObserver() {
+                @Override
+                public void onKeyguardStateChanged(boolean isShowing) {
+                    if (!notifyKeyguardEvents()) {
+                        return;
+                    }
+                    if (isShowing) {
+                        notifyKeyguardAppearing();
+                    } else {
+                        notifyKeyguardGoingAway();
+                    }
+                }
+
+                @Override
+                public void onKeyguardGoingAway() {
+                    notifyKeyguardGoingAway();
+                }
+            };
+
     private final class LocalService extends WallpaperManagerInternal {
         @Override
         public void onDisplayAddSystemDecorations(int displayId) {
@@ -1733,11 +1758,6 @@
         public void onScreenTurningOn(int displayId) {
             notifyScreenTurningOn(displayId);
         }
-
-        @Override
-        public void onKeyguardGoingAway() {
-            notifyKeyguardGoingAway();
-        }
     }
 
     void initialize() {
@@ -2571,6 +2591,18 @@
         return mContext.checkCallingOrSelfPermission(permission) == PERMISSION_GRANTED;
     }
 
+    private boolean hasPermission(WallpaperData data, String permission) {
+        try {
+            return PackageManager.PERMISSION_GRANTED == mIPackageManager.checkPermission(
+                    permission,
+                    data.getComponent().getPackageName(),
+                    data.userId);
+        } catch (RemoteException e) {
+            Slog.e(TAG, "Failed to check wallpaper service permission", e);
+            return false;
+        }
+    }
+
     private boolean hasAppOpPermission(String permission, int callingUid, String callingPackage,
             String attributionTag, String message) {
         final String op = AppOpsManager.permissionToOp(permission);
@@ -2873,16 +2905,37 @@
      * Propagate a keyguard going away event to the wallpaper engine.
      */
     private void notifyKeyguardGoingAway() {
+        dispatchKeyguardCommand(WallpaperManager.COMMAND_KEYGUARD_GOING_AWAY);
+    }
+
+    /**
+     * Propagate a keyguard appearing event to the wallpaper engine.
+     */
+    private void notifyKeyguardAppearing() {
+        dispatchKeyguardCommand(WallpaperManager.COMMAND_KEYGUARD_APPEARING);
+    }
+
+    /**
+     * Propagate a keyguard-related event to the wallpaper engine.
+     *
+     * When the flag below is enabled, the event will only be dispatched in case the recipient
+     * has {@link android.Manifest.pertmission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE} permission.
+     */
+    private void dispatchKeyguardCommand(String command) {
         synchronized (mLock) {
             for (WallpaperData data : getActiveWallpapers()) {
+                if (notifyKeyguardEvents() && !hasPermission(
+                        data, android.Manifest.permission.SUBSCRIBE_TO_KEYGUARD_LOCKED_STATE)) {
+                    continue;
+                }
+
                 data.connection.forEachDisplayConnector(displayConnector -> {
                     if (displayConnector.mEngine != null) {
                         try {
                             displayConnector.mEngine.dispatchWallpaperCommand(
-                                    WallpaperManager.COMMAND_KEYGUARD_GOING_AWAY,
-                                    -1, -1, -1, new Bundle());
+                                    command, -1, -1, -1, new Bundle());
                         } catch (RemoteException e) {
-                            Slog.w(TAG, "Failed to notify that the keyguard is going away", e);
+                            Slog.w(TAG, "Failed to dispatch wallpaper command: " + command, e);
                         }
                     }
                 });
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index a731bf7..70fc6ba 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -82,6 +82,7 @@
      */
     @VisibleForTesting
     static final int SNAPSHOT_MODE_NONE = 2;
+    static final float THEME_SNAPSHOT_MIN_Length = 128.0f;
 
     protected final WindowManagerService mService;
     protected final float mHighResSnapshotScale;
@@ -436,14 +437,21 @@
         final Rect taskBounds = source.getBounds();
         final InsetsState insetsState = mainWindow.getInsetsStateWithVisibilityOverride();
         final Rect systemBarInsets = getSystemBarInsets(mainWindow.getFrame(), insetsState);
+        final int taskWidth = taskBounds.width();
+        final int taskHeight = taskBounds.height();
+        float scale = mHighResSnapshotScale;
+        if (Flags.reduceTaskSnapshotMemoryUsage()) {
+            final int minLength = Math.min(taskWidth, taskHeight);
+            if (THEME_SNAPSHOT_MIN_Length < minLength) {
+                scale = Math.min(THEME_SNAPSHOT_MIN_Length / minLength, scale);
+            }
+        }
         final SnapshotDrawerUtils.SystemBarBackgroundPainter
                 decorPainter = new SnapshotDrawerUtils.SystemBarBackgroundPainter(attrs.flags,
                 attrs.privateFlags, attrs.insetsFlags.appearance, taskDescription,
-                mHighResSnapshotScale, mainWindow.getRequestedVisibleTypes());
-        final int taskWidth = taskBounds.width();
-        final int taskHeight = taskBounds.height();
-        final int width = (int) (taskWidth * mHighResSnapshotScale);
-        final int height = (int) (taskHeight * mHighResSnapshotScale);
+                scale, mainWindow.getRequestedVisibleTypes());
+        final int width = (int) (taskWidth * scale);
+        final int height = (int) (taskHeight * scale);
         final RenderNode node = RenderNode.create("SnapshotController", null);
         node.setLeftTopRightBottom(0, 0, width, height);
         node.setClipToBounds(false);
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index df00fa1..b76b231 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -5583,6 +5583,13 @@
         // called for updating snapshot states.
         if (!fromTransition) {
             mWmService.mSnapshotController.notifyAppVisibilityChanged(this, visible);
+            if (visible) {
+                // In case the activity becomes visible without transition, the client still expects
+                // to receive Activity#onEnterAnimationComplete.
+                mEnteringAnimation = true;
+                mWmService.mActivityManagerAppTransitionNotifier.onAppTransitionFinishedLocked(
+                        token);
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index 5cc186c..a19f438 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -272,6 +272,12 @@
             mActivityOptions = interceptResult.getActivityOptions();
             mCallingPid = mRealCallingPid;
             mCallingUid = mRealCallingUid;
+            // When an activity launch is intercepted, Intent#prepareToLeaveProcess is not called
+            // since the interception happens in the system_server. So if any activity is calling
+            // a trampoline activity, the keys do not get collected. Since all the interceptors
+            // are present in the system_server, add the creator token before launching the
+            // intercepted intent.
+            mService.mAmInternal.addCreatorToken(mIntent, mCallingPackage);
             if (interceptResult.isActivityResolved()) {
                 return true;
             }
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index c243cdc..21b730e 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -124,8 +124,9 @@
     public static final String ASSIST_KEY_RECEIVER_EXTRAS = "receiverExtras";
 
     public interface ScreenObserver {
-        void onAwakeStateChanged(boolean isAwake);
-        void onKeyguardStateChanged(boolean isShowing);
+        default void onAwakeStateChanged(boolean isAwake) {}
+        default void onKeyguardStateChanged(boolean isShowing) {}
+        default void onKeyguardGoingAway() {}
     }
 
     /**
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 9c96566..46d24b0 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -281,7 +281,6 @@
 import com.android.server.statusbar.StatusBarManagerInternal;
 import com.android.server.uri.NeededUriGrants;
 import com.android.server.uri.UriGrantsManagerInternal;
-import com.android.server.wallpaper.WallpaperManagerInternal;
 import com.android.server.wm.utils.WindowStyleCache;
 import com.android.wm.shell.Flags;
 
@@ -373,7 +372,6 @@
     private ComponentName mSysUiServiceComponent;
     private PermissionPolicyInternal mPermissionPolicyInternal;
     private StatusBarManagerInternal mStatusBarManagerInternal;
-    private WallpaperManagerInternal mWallpaperManagerInternal;
     private UserManagerInternal mUserManagerInternal;
     @VisibleForTesting
     final ActivityTaskManagerInternal mInternal;
@@ -3719,10 +3717,12 @@
                 if (isPowerModePreApplied && !foundResumed) {
                     endPowerMode(POWER_MODE_REASON_START_ACTIVITY);
                 }
-            }
-            WallpaperManagerInternal wallpaperManagerInternal = getWallpaperManagerInternal();
-            if (wallpaperManagerInternal != null) {
-                wallpaperManagerInternal.onKeyguardGoingAway();
+
+                mH.post(() -> {
+                    for (int i = mScreenObservers.size() - 1; i >= 0; i--) {
+                        mScreenObservers.get(i).onKeyguardGoingAway();
+                    }
+                });
             }
         } finally {
             Binder.restoreCallingIdentity(token);
@@ -5573,13 +5573,6 @@
         return mStatusBarManagerInternal;
     }
 
-    WallpaperManagerInternal getWallpaperManagerInternal() {
-        if (mWallpaperManagerInternal == null) {
-            mWallpaperManagerInternal = LocalServices.getService(WallpaperManagerInternal.class);
-        }
-        return mWallpaperManagerInternal;
-    }
-
     UserManagerInternal getUserManagerInternal() {
         if (mUserManagerInternal == null) {
             mUserManagerInternal = LocalServices.getService(UserManagerInternal.class);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
index b7ef105..0e14f83 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java
@@ -2650,9 +2650,13 @@
      */
     void endDeferResume() {
         mDeferResumeCount--;
-        if (readyToResume() && mLastReportedTopResumedActivity != null
-                && mTopResumedActivity != mLastReportedTopResumedActivity) {
-            scheduleTopResumedActivityStateLossIfNeeded();
+        if (readyToResume()) {
+            if (mLastReportedTopResumedActivity != null
+                    && mTopResumedActivity != mLastReportedTopResumedActivity) {
+                scheduleTopResumedActivityStateLossIfNeeded();
+            } else if (mLastReportedTopResumedActivity == null) {
+                scheduleTopResumedActivityStateIfNeeded();
+            }
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/AppCompatSafeRegionPolicy.java b/services/core/java/com/android/server/wm/AppCompatSafeRegionPolicy.java
index 9596093..cd6a014 100644
--- a/services/core/java/com/android/server/wm/AppCompatSafeRegionPolicy.java
+++ b/services/core/java/com/android/server/wm/AppCompatSafeRegionPolicy.java
@@ -156,6 +156,8 @@
     void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
         if (mNeedsSafeRegionBounds) {
             pw.println(prefix + " mNeedsSafeRegionBounds=true");
+            pw.println(
+                    prefix + " latestSafeRegionBoundsOnActivity=" + getLatestSafeRegionBounds());
         }
         if (isLetterboxedForSafeRegionOnlyAllowed()) {
             pw.println(prefix + " isLetterboxForSafeRegionOnlyAllowed=true");
diff --git a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
index fee5566..d808726 100644
--- a/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
+++ b/services/core/java/com/android/server/wm/DesktopAppCompatAspectRatioPolicy.java
@@ -69,11 +69,11 @@
      * Calculates the final aspect ratio of an launching activity based on the task it will be
      * launched in. Takes into account any min or max aspect ratio constraints.
      */
-    float calculateAspectRatio(@NonNull Task task) {
+    float calculateAspectRatio(@NonNull Task task, boolean hasOrientationMismatch) {
         final float maxAspectRatio = getMaxAspectRatio();
         final float minAspectRatio = getMinAspectRatio(task);
         float desiredAspectRatio = 0;
-        desiredAspectRatio = getDesiredAspectRatio(task);
+        desiredAspectRatio = getDesiredAspectRatio(task, hasOrientationMismatch);
         if (maxAspectRatio >= 1 && desiredAspectRatio > maxAspectRatio) {
             desiredAspectRatio = maxAspectRatio;
         } else if (minAspectRatio >= 1 && desiredAspectRatio < minAspectRatio) {
@@ -87,13 +87,14 @@
      * any min or max aspect ratio constraints.
      */
     @VisibleForTesting
-    float getDesiredAspectRatio(@NonNull Task task) {
+    float getDesiredAspectRatio(@NonNull Task task, boolean hasOrientationMismatch) {
         final float letterboxAspectRatioOverride = getFixedOrientationLetterboxAspectRatio(task);
         // Aspect ratio as suggested by the system. Apps requested mix/max aspect ratio will
         // be respected in #calculateAspectRatio.
         if (isDefaultMultiWindowLetterboxAspectRatioDesired(task)) {
             return DEFAULT_LETTERBOX_ASPECT_RATIO_FOR_MULTI_WINDOW;
-        } else if (letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
+        } else if (hasOrientationMismatch
+                && letterboxAspectRatioOverride > MIN_FIXED_ORIENTATION_LETTERBOX_ASPECT_RATIO) {
             return letterboxAspectRatioOverride;
         }
         return AppCompatUtils.computeAspectRatio(task.getDisplayArea().getBounds());
diff --git a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
index ce3ad88..83ca5f6 100644
--- a/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
+++ b/services/core/java/com/android/server/wm/DesktopModeBoundsCalculator.java
@@ -17,7 +17,6 @@
 package com.android.server.wm;
 
 import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LOCKED;
-import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
 import static android.content.pm.ActivityInfo.isFixedOrientation;
 import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
 import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
@@ -32,8 +31,8 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.app.ActivityOptions;
-import android.content.pm.ActivityInfo.ScreenOrientation;
 import android.content.pm.ActivityInfo.WindowLayout;
+import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.SystemProperties;
 import android.util.Size;
@@ -73,9 +72,12 @@
         final Rect stableBounds = new Rect();
         task.getDisplayArea().getStableRect(stableBounds);
 
-        // If the options bounds size is flexible, update size with calculated desired size.
+        final boolean hasFullscreenOverride = activity != null
+                && activity.mAppCompatController.getAspectRatioOverrides().hasFullscreenOverride();
+        // If the options bounds size is flexible and no fullscreen override has been applied,
+        // update size with calculated desired size.
         final boolean updateOptionBoundsSize = options != null
-                && options.getFlexibleLaunchSize();
+                && options.getFlexibleLaunchSize() && !hasFullscreenOverride;
         // If cascading is also enabled, the position of the options bounds must be respected
         // during the size update.
         final boolean shouldRespectOptionPosition =
@@ -149,19 +151,25 @@
         }
         final DesktopAppCompatAspectRatioPolicy desktopAppCompatAspectRatioPolicy =
                 activity.mAppCompatController.getDesktopAspectRatioPolicy();
-        float appAspectRatio = desktopAppCompatAspectRatioPolicy.calculateAspectRatio(task);
+        final int stableBoundsOrientation = stableBounds.height() >= stableBounds.width()
+                ? ORIENTATION_PORTRAIT : ORIENTATION_LANDSCAPE;
+        int activityOrientation = getActivityConfigurationOrientation(
+                activity, task, stableBoundsOrientation);
+        // Use orientation mismatch to resolve aspect ratio to match fixed orientation letterboxing
+        // policy in {@link ActivityRecord.resolveFixedOrientationConfiguration}
+        final boolean hasOrientationMismatch = stableBoundsOrientation != activityOrientation;
+        float appAspectRatio = desktopAppCompatAspectRatioPolicy.calculateAspectRatio(
+                task, hasOrientationMismatch);
         final float tdaWidth = stableBounds.width();
         final float tdaHeight = stableBounds.height();
-        final int taskConfigOrientation = task.getConfiguration().orientation;
-        final int activityOrientation = getActivityOrientation(activity, task);
-        final Size initialSize = switch (taskConfigOrientation) {
+        final Size initialSize = switch (stableBoundsOrientation) {
             case ORIENTATION_LANDSCAPE -> {
                 // Device in landscape orientation.
                 if (appAspectRatio == 0) {
                     appAspectRatio = 1;
                 }
                 if (canChangeAspectRatio(desktopAppCompatAspectRatioPolicy, task)) {
-                    if (isFixedOrientationPortrait(activityOrientation)) {
+                    if (hasOrientationMismatch) {
                         // For portrait resizeable activities, respect apps fullscreen width but
                         // apply ideal size height.
                         yield new Size((int) ((tdaHeight / appAspectRatio) + 0.5f),
@@ -180,7 +188,7 @@
                 final int customPortraitWidthForLandscapeApp = screenBounds.width()
                         - (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2);
                 if (canChangeAspectRatio(desktopAppCompatAspectRatioPolicy, task)) {
-                    if (isFixedOrientationLandscape(activityOrientation)) {
+                    if (hasOrientationMismatch) {
                         if (appAspectRatio == 0) {
                             appAspectRatio = tdaWidth / (tdaWidth - 1);
                         }
@@ -195,7 +203,7 @@
                 if (appAspectRatio == 0) {
                     appAspectRatio = 1;
                 }
-                if (isFixedOrientationLandscape(activityOrientation)) {
+                if (hasOrientationMismatch) {
                     // For landscape unresizeable activities, apply custom app width to ideal size
                     // and calculate maximum size with this area while maintaining original aspect
                     // ratio.
@@ -227,19 +235,23 @@
                 && !desktopAppCompatAspectRatioPolicy.hasMinAspectRatioOverride(task);
     }
 
-    private static @ScreenOrientation int getActivityOrientation(
-            @NonNull ActivityRecord activity, @NonNull Task task) {
+    private static @Configuration.Orientation int getActivityConfigurationOrientation(
+            @NonNull ActivityRecord activity, @NonNull Task task,
+            @Configuration.Orientation int stableBoundsOrientation) {
         final int activityOrientation = activity.getOverrideOrientation();
         final DesktopAppCompatAspectRatioPolicy desktopAppCompatAspectRatioPolicy =
                 activity.mAppCompatController.getDesktopAspectRatioPolicy();
-        if (desktopAppCompatAspectRatioPolicy.shouldApplyUserMinAspectRatioOverride(task)
+        if ((desktopAppCompatAspectRatioPolicy.shouldApplyUserMinAspectRatioOverride(task)
                 && (!isFixedOrientation(activityOrientation)
-                    || activityOrientation == SCREEN_ORIENTATION_LOCKED)) {
+                    || activityOrientation == SCREEN_ORIENTATION_LOCKED))
+                || isFixedOrientationPortrait(activityOrientation)) {
             // If a user aspect ratio override should be applied, treat the activity as portrait if
             // it has not specified a fix orientation.
-            return SCREEN_ORIENTATION_PORTRAIT;
+            return ORIENTATION_PORTRAIT;
         }
-        return activityOrientation;
+        // If activity orientation is undefined inherit task orientation.
+        return isFixedOrientationLandscape(activityOrientation)
+                ?  ORIENTATION_LANDSCAPE : stableBoundsOrientation;
     }
 
     /**
@@ -249,7 +261,7 @@
     // TODO(b/400617906): Merge duplicate initial bounds calculations to shared class.
     @NonNull
     private static Size maximizeSizeGivenAspectRatio(
-            @ScreenOrientation int orientation,
+            @Configuration.Orientation int orientation,
             @NonNull Size targetArea,
             float aspectRatio,
             int captionHeight
@@ -258,7 +270,7 @@
         final int targetWidth = targetArea.getWidth();
         final int finalHeight;
         final int finalWidth;
-        if (isFixedOrientationPortrait(orientation)) {
+        if (orientation == ORIENTATION_PORTRAIT) {
             // Portrait activity.
             // Calculate required width given ideal height and aspect ratio.
             int tempWidth = (int) (targetHeight / aspectRatio);
diff --git a/services/core/java/com/android/server/wm/Dimmer.java b/services/core/java/com/android/server/wm/Dimmer.java
index 2798e84..ab87459 100644
--- a/services/core/java/com/android/server/wm/Dimmer.java
+++ b/services/core/java/com/android/server/wm/Dimmer.java
@@ -218,6 +218,11 @@
      */
     protected void adjustAppearance(@NonNull WindowState dimmingContainer,
                                     float alpha, int blurRadius) {
+        if (!mHost.isVisibleRequested()) {
+            // If the host is already going away, there is no point in keeping dimming
+            return;
+        }
+
         if (mDimState != null || (alpha != 0 || blurRadius != 0)) {
             final DimState d = obtainDimState(dimmingContainer);
             d.prepareLookChange(alpha, blurRadius);
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 76a39d9..2f9242f 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -41,6 +41,7 @@
 import static android.util.TypedValue.COMPLEX_UNIT_MASK;
 import static android.util.TypedValue.COMPLEX_UNIT_SHIFT;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.FLAG_ALLOWS_CONTENT_MODE_SWITCH;
 import static android.view.Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
 import static android.view.Display.FLAG_PRIVATE;
 import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
@@ -2161,7 +2162,7 @@
     /** Re-show the previously hidden windows if all seamless rotated windows are done. */
     void finishAsyncRotationIfPossible() {
         final AsyncRotationController controller = mAsyncRotationController;
-        if (controller != null && !mDisplayRotation.hasSeamlessRotatingWindow()) {
+        if (controller != null) {
             controller.completeAll();
             mAsyncRotationController = null;
         }
@@ -2238,11 +2239,7 @@
      */
     private void applyRotation(final int oldRotation, final int rotation) {
         mDisplayRotation.applyCurrentRotation(rotation);
-        final boolean shellTransitions = mTransitionController.getTransitionPlayer() != null;
-        final boolean rotateSeamlessly =
-                mDisplayRotation.isRotatingSeamlessly() && !shellTransitions;
-        final Transaction transaction =
-                shellTransitions ? getSyncTransaction() : getPendingTransaction();
+
         // We need to update our screen size information to match the new rotation. If the rotation
         // has actually changed then this method will return true and, according to the comment at
         // the top of the method, the caller is obligated to call computeNewConfigurationLocked().
@@ -2250,25 +2247,13 @@
         // #computeScreenConfiguration() later.
         updateDisplayAndOrientation(null /* outConfig */);
 
-        if (!shellTransitions) {
-            forAllWindows(w -> {
-                w.seamlesslyRotateIfAllowed(transaction, oldRotation, rotation, rotateSeamlessly);
-            }, true /* traverseTopToBottom */);
-            mPinnedTaskController.startSeamlessRotationIfNeeded(transaction, oldRotation, rotation);
-            if (!mDisplayRotation.hasSeamlessRotatingWindow()) {
-                // Make sure DisplayRotation#isRotatingSeamlessly() will return false.
-                mDisplayRotation.cancelSeamlessRotation();
-            }
-        }
+        // Before setDisplayProjection is applied by the start transaction of transition,
+        // set the transform hint to avoid using surface in old rotation.
+        setFixedTransformHint(getPendingTransaction(), mSurfaceControl, rotation);
+        // The sync transaction should already contains setDisplayProjection, so unset the
+        // hint to restore the natural state when the transaction is applied.
+        getSyncTransaction().unsetFixedTransformHint(mSurfaceControl);
 
-        if (shellTransitions) {
-            // Before setDisplayProjection is applied by the start transaction of transition,
-            // set the transform hint to avoid using surface in old rotation.
-            setFixedTransformHint(getPendingTransaction(), mSurfaceControl, rotation);
-            // The sync transaction should already contains setDisplayProjection, so unset the
-            // hint to restore the natural state when the transaction is applied.
-            transaction.unsetFixedTransformHint(mSurfaceControl);
-        }
         scheduleAnimation();
 
         mWmService.mRotationWatcherController.dispatchDisplayRotationChange(mDisplayId, rotation);
@@ -2870,8 +2855,7 @@
         // If the transition finished callback cannot match the token for some reason, make sure the
         // rotated state is cleared if it is already invisible.
         if (mFixedRotationLaunchingApp != null && !mFixedRotationLaunchingApp.isVisibleRequested()
-                && !mFixedRotationLaunchingApp.isVisible()
-                && !mDisplayRotation.isRotatingSeamlessly()) {
+                && !mFixedRotationLaunchingApp.isVisible()) {
             clearFixedRotationLaunchingApp();
         }
         // If there won't be a transition to notify the launch is done, then it should be ready to
@@ -3283,26 +3267,30 @@
                 /* inTopology= */ shouldShowContent);
     }
 
-     /**
-      * Whether the display is allowed to switch the content mode between extended and mirroring.
-      * If the content mode is extended, the display will start home activity and show system
-      * decorations, such as wallpapaer, status bar and navigation bar.
-      * If the content mode is mirroring, the display will not show home activity or system
-      * decorations.
-      * The content mode is switched when {@link Display#canHostTasks()} changes.
-      *
-      * Note that we only allow displays that are able to show system decorations to use the content
-      * mode switch; however, not all displays that are able to show system decorations are allowed
-      * to use the content mode switch.
-      */
-     boolean allowContentModeSwitch() {
+    /**
+     * Whether the display is allowed to switch the content mode between extended and mirroring.
+     * If the content mode is extended, the display will start home activity and show system
+     * decorations, such as wallpapaer, status bar and navigation bar.
+     * If the content mode is mirroring, the display will not show home activity or system
+     * decorations.
+     * The content mode is switched when {@link Display#canHostTasks()} changes.
+     *
+     * Note that we only allow displays that are able to show system decorations to use the content
+     * mode switch; however, not all displays that are able to show system decorations are allowed
+     * to use the content mode switch.
+     */
+    boolean allowContentModeSwitch() {
+        if ((mDisplay.getFlags() & FLAG_ALLOWS_CONTENT_MODE_SWITCH) == 0) {
+            return false;
+        }
+
         // The default display should always show system decorations.
         if (isDefaultDisplay) {
             return false;
         }
 
-        // Private display should never show system decorations.
-        if (isPrivate()) {
+        // Private or untrusted display should never show system decorations.
+        if (isPrivate() || !isTrusted()) {
             return false;
         }
 
@@ -3310,14 +3298,9 @@
             return false;
         }
 
-        // TODO(b/391965805): Remove this after introducing FLAG_ALLOW_CONTENT_MODE_SWITCH.
-        if ((mDisplay.getFlags() & Display.FLAG_REAR) != 0) {
-            return false;
-        }
-
-        // TODO(b/391965805): Remove this after introducing FLAG_ALLOW_CONTENT_MODE_SWITCH.
-        // Virtual displays cannot add or remove system decorations during their lifecycle.
-        if (mDisplay.getType() == Display.TYPE_VIRTUAL) {
+        // Display with FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS enabled should always show system
+        // decorations, and should not switch the content mode.
+        if ((mDisplay.getFlags() & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
             return false;
         }
 
@@ -5072,7 +5055,7 @@
         }
 
         mLastHasContent = mTmpApplySurfaceChangesTransactionState.displayHasContent;
-        if (!inTransition() && !mDisplayRotation.isRotatingSeamlessly()) {
+        if (!inTransition()) {
             mWmService.mDisplayManagerInternal.setDisplayProperties(mDisplayId,
                     mLastHasContent,
                     mTmpApplySurfaceChangesTransactionState.preferredRefreshRate,
@@ -7102,12 +7085,13 @@
         }
 
         @Override
-        public void setAnimatingTypes(@InsetsType int animatingTypes) {
+        public void setAnimatingTypes(@InsetsType int animatingTypes,
+                @Nullable ImeTracker.Token statsToken) {
             if (mAnimatingTypes != animatingTypes) {
                 mAnimatingTypes = animatingTypes;
 
                 if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) {
-                    getInsetsStateController().onAnimatingTypesChanged(this);
+                    getInsetsStateController().onAnimatingTypesChanged(this, statsToken);
                 }
             }
         }
diff --git a/services/core/java/com/android/server/wm/DisplayRotation.java b/services/core/java/com/android/server/wm/DisplayRotation.java
index 9cf792d..9edbb70 100644
--- a/services/core/java/com/android/server/wm/DisplayRotation.java
+++ b/services/core/java/com/android/server/wm/DisplayRotation.java
@@ -168,19 +168,6 @@
     private int mDeferredRotationPauseCount;
 
     /**
-     * A count of the windows which are 'seamlessly rotated', e.g. a surface at an old orientation
-     * is being transformed. We freeze orientation updates while any windows are seamlessly rotated,
-     * so we need to track when this hits zero so we can apply deferred orientation updates.
-     */
-    private int mSeamlessRotationCount;
-
-    /**
-     * True in the interval from starting seamless rotation until the last rotated window draws in
-     * the new orientation.
-     */
-    private boolean mRotatingSeamlessly;
-
-    /**
      * Behavior of rotation suggestions.
      *
      * @see Settings.Secure#SHOW_ROTATION_SUGGESTIONS
@@ -630,15 +617,6 @@
             return true;
         }
 
-        if (shouldRotateSeamlessly(oldRotation, rotation, forceUpdate)) {
-            // The screen rotation animation uses a screenshot to freeze the screen while windows
-            // resize underneath. When we are rotating seamlessly, we allow the elements to
-            // transition to their rotated state independently and without a freeze required.
-            prepareSeamlessRotation();
-        } else {
-            cancelSeamlessRotation();
-        }
-
         // Give a remote handler (system ui) some time to reposition things.
         startRemoteRotation(oldRotation, mRotation);
 
@@ -677,42 +655,6 @@
         }
     }
 
-    /**
-     * This ensures that normal rotation animation is used. E.g. {@link #mRotatingSeamlessly} was
-     * set by previous {@link #updateRotationUnchecked}, but another orientation change happens
-     * before calling {@link DisplayContent#sendNewConfiguration} (remote rotation hasn't finished)
-     * and it doesn't choose seamless rotation.
-     */
-    void cancelSeamlessRotation() {
-        if (!mRotatingSeamlessly) {
-            return;
-        }
-        mDisplayContent.forAllWindows(w -> {
-            if (w.mSeamlesslyRotated) {
-                w.cancelSeamlessRotation();
-                w.mSeamlesslyRotated = false;
-            }
-        }, true /* traverseTopToBottom */);
-        mSeamlessRotationCount = 0;
-        mRotatingSeamlessly = false;
-        mDisplayContent.finishAsyncRotationIfPossible();
-    }
-
-    private void prepareSeamlessRotation() {
-        // We are careful to reset this in case a window was removed before it finished
-        // seamless rotation.
-        mSeamlessRotationCount = 0;
-        mRotatingSeamlessly = true;
-    }
-
-    boolean isRotatingSeamlessly() {
-        return mRotatingSeamlessly;
-    }
-
-    boolean hasSeamlessRotatingWindow() {
-        return mSeamlessRotationCount > 0;
-    }
-
     @VisibleForTesting
     boolean shouldRotateSeamlessly(int oldRotation, int newRotation, boolean forceUpdate) {
         // Display doesn't need to be frozen because application has been started in correct
@@ -750,13 +692,6 @@
             return false;
         }
 
-        // We can't rotate (seamlessly or not) while waiting for the last seamless rotation to
-        // complete (that is, waiting for windows to redraw). It's tempting to check
-        // mSeamlessRotationCount but that could be incorrect in the case of window-removal.
-        if (!forceUpdate && mDisplayContent.getWindow(win -> win.mSeamlesslyRotated) != null) {
-            return false;
-        }
-
         return true;
     }
 
@@ -774,28 +709,6 @@
         return oldRotation != Surface.ROTATION_180 && newRotation != Surface.ROTATION_180;
     }
 
-    void markForSeamlessRotation(WindowState w, boolean seamlesslyRotated) {
-        if (seamlesslyRotated == w.mSeamlesslyRotated || w.mForceSeamlesslyRotate) {
-            return;
-        }
-
-        w.mSeamlesslyRotated = seamlesslyRotated;
-        if (seamlesslyRotated) {
-            mSeamlessRotationCount++;
-        } else {
-            mSeamlessRotationCount--;
-        }
-        if (mSeamlessRotationCount == 0) {
-            ProtoLog.i(WM_DEBUG_ORIENTATION,
-                    "Performing post-rotate rotation after seamless rotation");
-            // Finish seamless rotation.
-            mRotatingSeamlessly = false;
-            mDisplayContent.finishAsyncRotationIfPossible();
-
-            updateRotationAndSendNewConfigIfChanged();
-        }
-    }
-
     void restoreSettings(int userRotationMode, int userRotation, int fixedToUserRotation) {
         mFixedToUserRotation = fixedToUserRotation;
 
diff --git a/services/core/java/com/android/server/wm/EmbeddedWindowController.java b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
index 7b6fc9e..64ae21d 100644
--- a/services/core/java/com/android/server/wm/EmbeddedWindowController.java
+++ b/services/core/java/com/android/server/wm/EmbeddedWindowController.java
@@ -239,9 +239,10 @@
 
     static class EmbeddedWindow implements InputTarget {
         final IBinder mClient;
-        @Nullable final WindowState mHostWindowState;
+        @Nullable WindowState mHostWindowState;
         @Nullable final ActivityRecord mHostActivityRecord;
-        final String mName;
+        String mName;
+        final String mInputHandleName;
         final int mOwnerUid;
         final int mOwnerPid;
         final WindowManagerService mWmService;
@@ -279,13 +280,12 @@
          * @param displayId used for focus requests
          */
         EmbeddedWindow(Session session, WindowManagerService service, IBinder clientToken,
-                       WindowState hostWindowState, int ownerUid, int ownerPid, int windowType,
-                       int displayId, InputTransferToken inputTransferToken, String inputHandleName,
-                       boolean isFocusable) {
+                       @Nullable WindowState hostWindowState, int ownerUid, int ownerPid,
+                       int windowType, int displayId, InputTransferToken inputTransferToken,
+                       String inputHandleName, boolean isFocusable) {
             mSession = session;
             mWmService = service;
             mClient = clientToken;
-            mHostWindowState = hostWindowState;
             mHostActivityRecord = (mHostWindowState != null) ? mHostWindowState.mActivityRecord
                     : null;
             mOwnerUid = ownerUid;
@@ -293,11 +293,9 @@
             mWindowType = windowType;
             mDisplayId = displayId;
             mInputTransferToken = inputTransferToken;
-            final String hostWindowName =
-                    (mHostWindowState != null) ? "-" + mHostWindowState.getWindowTag().toString()
-                            : "";
             mIsFocusable = isFocusable;
-            mName = "Embedded{" + inputHandleName + hostWindowName + "}";
+            mInputHandleName = inputHandleName;
+            updateHost(hostWindowState);
         }
 
         @Override
@@ -486,5 +484,19 @@
             proto.end(token2);
             proto.end(token);
         }
+
+        public void updateHost(WindowState hostWindowState) {
+            if (mHostWindowState == hostWindowState && mName != null) {
+                return;
+            }
+
+            ProtoLog.d(WM_DEBUG_EMBEDDED_WINDOWS, "[%s] Updated host window from %s to %s",
+                    this, mHostWindowState, hostWindowState);
+            mHostWindowState = hostWindowState;
+            final String hostWindowName =
+                    (mHostWindowState != null) ? "-" + mHostWindowState.getWindowTag().toString()
+                            : "";
+            mName = "Embedded{" + mInputHandleName + hostWindowName + "}";
+        }
     }
 }
diff --git a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
index 040bbe4..53681f9 100644
--- a/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/ImeInsetsSourceProvider.java
@@ -82,6 +82,13 @@
      */
     private boolean mGivenInsetsReady = false;
 
+    /**
+     * The last state of the windowContainer. This is used to reset server visibility, in case of
+     * the IME (temporarily) redrawing  (e.g. during a rotation), to dispatch the control with
+     * leash again after it has finished drawing.
+     */
+    private boolean mLastDrawn = false;
+
     ImeInsetsSourceProvider(@NonNull InsetsSource source,
             @NonNull InsetsStateController stateController,
             @NonNull DisplayContent displayContent) {
@@ -97,6 +104,7 @@
             final WindowState ws =
                     mWindowContainer != null ? mWindowContainer.asWindowState() : null;
             final boolean givenInsetsPending = ws != null && ws.mGivenInsetsPending;
+            mLastDrawn = ws != null && ws.isDrawn();
 
             // isLeashReadyForDispatching (used to dispatch the leash of the control) is
             // depending on mGivenInsetsReady. Therefore, triggering notifyControlChanged here
@@ -158,6 +166,35 @@
         }
     }
 
+    /**
+     * This is used to determine the desired serverVisibility state. For the IME, just having a
+     * window state that would be visible by policy is not enough.
+     */
+    @Override
+    protected boolean isSurfaceVisible() {
+        final boolean isSurfaceVisible = super.isSurfaceVisible();
+        if (android.view.inputmethod.Flags.refactorInsetsController()) {
+            final WindowState windowState = mWindowContainer.asWindowState();
+            if (mControl != null && windowState != null) {
+                final boolean isDrawn = windowState.isDrawn();
+                if (!isServerVisible() && isSurfaceVisible) {
+                    // In case the IME becomes visible, we need to check if it is already drawn and
+                    // does not have given insets pending. If it's not yet drawn, we do not set
+                    // server visibility
+                    return isDrawn && !windowState.mGivenInsetsPending;
+                } else if (mLastDrawn && !isDrawn) {
+                    // If the IME was drawn before, but is not drawn anymore, we need to reset
+                    // server visibility, which will also reset {@link
+                    // ImeInsetsSourceProvider#mGivenInsetsReady}. Otherwise, the new control
+                    // with leash won't be dispatched after the surface has redrawn.
+                    return false;
+                }
+            }
+        }
+        return isSurfaceVisible;
+    }
+
+
     @Nullable
     @Override
     InsetsSourceControl getControl(InsetsControlTarget target) {
@@ -284,7 +321,7 @@
         if (Flags.refactorInsetsController()) {
             // TODO(b/353463205) investigate if we should fail the statsToken, or if it's only
             //  temporary null.
-            if (target != null) {
+            if (target != null && target == mControlTarget) {
                 // If insets target is not available (e.g. RemoteInsetsControlTarget), use current
                 // IME input target to update IME request state. For example, switch from a task
                 // with showing IME to a split-screen task without showing IME.
@@ -297,6 +334,11 @@
                 } else {
                     invokeOnImeRequestedChangedListener(target, statsToken);
                 }
+            } else {
+                ProtoLog.w(WM_DEBUG_IME,
+                        "Not invoking onImeRequestedChangedListener, target=%s, current "
+                                + "controlTarget=%s",
+                        target, mControlTarget);
             }
         }
     }
@@ -424,7 +466,8 @@
     }
 
     @Override
-    void onAnimatingTypesChanged(InsetsControlTarget caller) {
+    void onAnimatingTypesChanged(InsetsControlTarget caller,
+            @Nullable ImeTracker.Token statsToken) {
         if (Flags.reportAnimatingInsetsTypes()) {
             final InsetsControlTarget controlTarget = getControlTarget();
             // If the IME is not being requested anymore and the animation is finished, we need to
@@ -432,8 +475,12 @@
             if (caller != null && caller == controlTarget && !caller.isRequestedVisible(
                     WindowInsets.Type.ime())
                     && (caller.getAnimatingTypes() & WindowInsets.Type.ime()) == 0) {
-                // TODO(b/353463205) check statsToken
-                invokeOnImeRequestedChangedListener(caller, null);
+                ImeTracker.forLogging().onFailed(statsToken,
+                        ImeTracker.PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED);
+                invokeOnImeRequestedChangedListener(caller, statsToken);
+            } else {
+                ImeTracker.forLogging().onCancelled(statsToken,
+                        ImeTracker.PHASE_WM_NOTIFY_HIDE_ANIMATION_FINISHED);
             }
         }
     }
@@ -779,6 +826,8 @@
         pw.print(prefix);
         pw.print("mImeShowing=");
         pw.print(mImeShowing);
+        pw.print(" mLastDrawn=");
+        pw.print(mLastDrawn);
         if (mImeRequester != null) {
             pw.print(prefix);
             pw.print("showImePostLayout pending for mImeRequester=");
diff --git a/services/core/java/com/android/server/wm/InsetsControlTarget.java b/services/core/java/com/android/server/wm/InsetsControlTarget.java
index 6462a37..3c248fb 100644
--- a/services/core/java/com/android/server/wm/InsetsControlTarget.java
+++ b/services/core/java/com/android/server/wm/InsetsControlTarget.java
@@ -107,8 +107,10 @@
 
     /**
      * @param animatingTypes the {@link InsetsType}s, that are currently animating
+     * @param statsToken the token tracking the current IME request or {@code null} otherwise.
      */
-    default void setAnimatingTypes(@InsetsType int animatingTypes) {
+    default void setAnimatingTypes(@InsetsType int animatingTypes,
+            @Nullable ImeTracker.Token statsToken) {
     }
 
     /** Returns {@code target.getWindow()}, or null if {@code target} is {@code null}. */
diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
index 1b693fc..3b715d6 100644
--- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java
+++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java
@@ -176,6 +176,16 @@
     }
 
     /**
+     * @return Whether the current window container has a visible surface.
+     */
+    protected boolean isSurfaceVisible() {
+        final WindowState windowState = mWindowContainer.asWindowState();
+        return windowState != null
+                ? windowState.wouldBeVisibleIfPolicyIgnored() && windowState.isVisibleByPolicy()
+                : mWindowContainer.isVisibleRequested();
+    }
+
+    /**
      * Updates the window container that currently backs this source.
      *
      * @param windowContainer The window container that links to this source.
@@ -368,20 +378,9 @@
         if (mWindowContainer == null) {
             return;
         }
-        WindowState windowState = mWindowContainer.asWindowState();
-        boolean isServerVisible = windowState != null
-                ? windowState.wouldBeVisibleIfPolicyIgnored() && windowState.isVisibleByPolicy()
-                : mWindowContainer.isVisibleRequested();
+        final WindowState windowState = mWindowContainer.asWindowState();
+        final boolean isServerVisible = isSurfaceVisible();
 
-        if (android.view.inputmethod.Flags.refactorInsetsController()) {
-            if (mControl != null && mControl.getType() == WindowInsets.Type.ime() && !mServerVisible
-                    && isServerVisible && windowState != null) {
-                // in case the IME becomes visible, we need to check if it is already drawn and
-                // does not have given insets pending. If it's not yet drawn, we do not set
-                // server visibility
-                isServerVisible = windowState.isDrawn() && !windowState.mGivenInsetsPending;
-            }
-        }
         final boolean serverVisibleChanged = mServerVisible != isServerVisible;
         setServerVisible(isServerVisible);
         if (mControl != null && mControlTarget != null) {
@@ -673,7 +672,8 @@
                 mServerVisible, mClientVisible);
     }
 
-    void onAnimatingTypesChanged(InsetsControlTarget caller) {
+    void onAnimatingTypesChanged(InsetsControlTarget caller,
+            @Nullable ImeTracker.Token statsToken) {
     }
 
     protected boolean isLeashReadyForDispatching() {
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 810e48f..64fe669 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -393,10 +393,12 @@
         }
     }
 
-    void onAnimatingTypesChanged(InsetsControlTarget target) {
+    void onAnimatingTypesChanged(InsetsControlTarget target,
+            @Nullable ImeTracker.Token statsToken) {
         for (int i = mProviders.size() - 1; i >= 0; i--) {
             final InsetsSourceProvider provider = mProviders.valueAt(i);
-            provider.onAnimatingTypesChanged(target);
+            final boolean isImeProvider = provider.getSource().getType() == WindowInsets.Type.ime();
+            provider.onAnimatingTypesChanged(target, isImeProvider ? statsToken : null);
         }
     }
 
diff --git a/services/core/java/com/android/server/wm/PinnedTaskController.java b/services/core/java/com/android/server/wm/PinnedTaskController.java
index 6dd7d35..6e59828 100644
--- a/services/core/java/com/android/server/wm/PinnedTaskController.java
+++ b/services/core/java/com/android/server/wm/PinnedTaskController.java
@@ -21,20 +21,13 @@
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
 import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
 
-import android.app.PictureInPictureParams;
 import android.content.res.Resources;
-import android.graphics.Insets;
-import android.graphics.Matrix;
 import android.graphics.Rect;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.util.Log;
-import android.util.RotationUtils;
 import android.util.Slog;
 import android.view.IPinnedTaskListener;
-import android.view.Surface;
-import android.view.SurfaceControl;
-import android.window.PictureInPictureSurfaceTransaction;
 
 import java.io.PrintWriter;
 
@@ -71,11 +64,7 @@
      * based on the new rotation.
      */
     private Rect mDestRotatedBounds;
-    /**
-     * Non-null if the entering PiP task from recents animation will cause display rotation to
-     * change. The transaction is based on the old rotation.
-     */
-    private PictureInPictureSurfaceTransaction mPipTransaction;
+
     /** Whether to skip task configuration change once. */
     private boolean mFreezingTaskConfig;
     /** Defer display orientation change if the PiP task is animating across orientations. */
@@ -212,14 +201,12 @@
     }
 
     /**
-     * Sets the transaction for {@link #startSeamlessRotationIfNeeded} if the orientation of display
-     * will be changed. This is only called when finishing recents animation with pending
-     * orientation change that will be handled by
-     * {@link DisplayContent.FixedRotationTransitionListener#onFinishRecentsAnimation}.
+     * Sets a hint if the orientation of display will be changed. This is only called when
+     * finishing recents animation with pending orientation change that will be handled by
+     * {@link DisplayContent.FixedRotationTransitionListener}.
      */
-    void setEnterPipTransaction(PictureInPictureSurfaceTransaction tx) {
+    void setEnterPipWithRotatedTransientLaunch() {
         mFreezingTaskConfig = true;
-        mPipTransaction = tx;
     }
 
     /** Called when the activity in PiP task has PiP windowing mode (at the end of animation). */
@@ -233,81 +220,6 @@
     }
 
     /**
-     * Resets rotation and applies scale and position to PiP task surface to match the current
-     * rotation of display. The final surface matrix will be replaced by PiPTaskOrganizer after it
-     * receives the callback of fixed rotation completion.
-     */
-    void startSeamlessRotationIfNeeded(SurfaceControl.Transaction t,
-            int oldRotation, int newRotation) {
-        final Rect bounds = mDestRotatedBounds;
-        final PictureInPictureSurfaceTransaction pipTx = mPipTransaction;
-        final boolean emptyPipPositionTx = pipTx == null || pipTx.mPosition == null;
-        if (bounds == null && emptyPipPositionTx) {
-            return;
-        }
-        final TaskDisplayArea taskArea = mDisplayContent.getDefaultTaskDisplayArea();
-        final Task pinnedTask = taskArea.getRootPinnedTask();
-        if (pinnedTask == null) {
-            return;
-        }
-
-        mDestRotatedBounds = null;
-        mPipTransaction = null;
-        final Rect areaBounds = taskArea.getBounds();
-        if (!emptyPipPositionTx) {
-            // The transaction from recents animation is in old rotation. So the position needs to
-            // be rotated.
-            float dx = pipTx.mPosition.x;
-            float dy = pipTx.mPosition.y;
-            final Matrix matrix = pipTx.getMatrix();
-            if (pipTx.mRotation == 90) {
-                dx = pipTx.mPosition.y;
-                dy = areaBounds.right - pipTx.mPosition.x;
-                matrix.postRotate(-90);
-            } else if (pipTx.mRotation == -90) {
-                dx = areaBounds.bottom - pipTx.mPosition.y;
-                dy = pipTx.mPosition.x;
-                matrix.postRotate(90);
-            }
-            matrix.postTranslate(dx, dy);
-            final SurfaceControl leash = pinnedTask.getSurfaceControl();
-            t.setMatrix(leash, matrix, new float[9]);
-            if (pipTx.hasCornerRadiusSet()) {
-                t.setCornerRadius(leash, pipTx.mCornerRadius);
-            }
-            Slog.i(TAG, "Seamless rotation PiP tx=" + pipTx + " pos=" + dx + "," + dy);
-            return;
-        }
-
-        final PictureInPictureParams params = pinnedTask.getPictureInPictureParams();
-        final Rect sourceHintRect = params != null && params.hasSourceBoundsHint()
-                ? params.getSourceRectHint()
-                : null;
-        Slog.i(TAG, "Seamless rotation PiP bounds=" + bounds + " hintRect=" + sourceHintRect);
-        final int rotationDelta = RotationUtils.deltaRotation(oldRotation, newRotation);
-        // Adjust for display cutout if applicable.
-        if (sourceHintRect != null && rotationDelta == Surface.ROTATION_270) {
-            if (pinnedTask.getDisplayCutoutInsets() != null) {
-                final int rotationBackDelta = RotationUtils.deltaRotation(newRotation, oldRotation);
-                final Rect displayCutoutInsets = RotationUtils.rotateInsets(
-                        Insets.of(pinnedTask.getDisplayCutoutInsets()), rotationBackDelta).toRect();
-                sourceHintRect.offset(displayCutoutInsets.left, displayCutoutInsets.top);
-            }
-        }
-        final Rect contentBounds = sourceHintRect != null && areaBounds.contains(sourceHintRect)
-                ? sourceHintRect : areaBounds;
-        final int w = contentBounds.width();
-        final int h = contentBounds.height();
-        final float scale = w <= h ? (float) bounds.width() / w : (float) bounds.height() / h;
-        final int insetLeft = (int) ((contentBounds.left - areaBounds.left) * scale + .5f);
-        final int insetTop = (int) ((contentBounds.top - areaBounds.top) * scale + .5f);
-        final Matrix matrix = new Matrix();
-        matrix.setScale(scale, scale);
-        matrix.postTranslate(bounds.left - insetLeft, bounds.top - insetTop);
-        t.setMatrix(pinnedTask.getSurfaceControl(), matrix, new float[9]);
-    }
-
-    /**
      * Returns {@code true} to skip {@link Task#onConfigurationChanged} because it is expected that
      * there will be a orientation change and a PiP configuration change.
      */
@@ -321,7 +233,6 @@
         mFreezingTaskConfig = false;
         mDeferOrientationChanging = false;
         mDestRotatedBounds = null;
-        mPipTransaction = null;
     }
 
     /**
@@ -381,9 +292,6 @@
         if (mDestRotatedBounds != null) {
             pw.println(prefix + "  mPendingBounds=" + mDestRotatedBounds);
         }
-        if (mPipTransaction != null) {
-            pw.println(prefix + "  mPipTransaction=" + mPipTransaction);
-        }
         pw.println(prefix + "  mIsImeShowing=" + mIsImeShowing);
         pw.println(prefix + "  mImeHeight=" + mImeHeight);
         pw.println(prefix + "  mMinAspectRatio=" + mMinAspectRatio);
diff --git a/services/core/java/com/android/server/wm/PointerEventDispatcher.java b/services/core/java/com/android/server/wm/PointerEventDispatcher.java
index 4f8ec63..be259ec 100644
--- a/services/core/java/com/android/server/wm/PointerEventDispatcher.java
+++ b/services/core/java/com/android/server/wm/PointerEventDispatcher.java
@@ -80,7 +80,7 @@
     public void unregisterInputEventListener(PointerEventListener listener) {
         synchronized (mListeners) {
             if (!mListeners.contains(listener)) {
-                throw new IllegalStateException("registerInputEventListener: " + listener +
+                throw new IllegalStateException("unregisterInputEventListener: " + listener +
                         " not registered.");
             }
             mListeners.remove(listener);
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index 609302c..39d1062 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -79,8 +79,6 @@
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_PLACING_SURFACES;
 import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
-import static com.android.server.wm.WindowSurfacePlacer.SET_UPDATE_ROTATION;
-import static com.android.server.wm.WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING;
 
 import static java.lang.Integer.MAX_VALUE;
 
@@ -655,9 +653,6 @@
         final int count = mChildren.size();
         for (int i = 0; i < count; ++i) {
             final int pendingChanges = mChildren.get(i).pendingLayoutChanges;
-            if ((pendingChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
-                animator.mBulkUpdateParams |= SET_WALLPAPER_ACTION_PENDING;
-            }
             if (pendingChanges != 0) {
                 hasChanges = true;
             }
@@ -858,7 +853,8 @@
 
         // Post these on a handler such that we don't call into power manager service while
         // holding the window manager lock to avoid lock contention with power manager lock.
-        mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, mDisplayBrightnessOverrides)
+        // Send a copy of the brightness overrides as they may be cleared before being sent out.
+        mHandler.obtainMessage(SET_SCREEN_BRIGHTNESS_OVERRIDE, mDisplayBrightnessOverrides.clone())
                 .sendToTarget();
         mHandler.obtainMessage(SET_USER_ACTIVITY_TIMEOUT, mUserActivityTimeout).sendToTarget();
 
@@ -1024,18 +1020,6 @@
         return changed;
     }
 
-    boolean copyAnimToLayoutParams() {
-        boolean doRequest = false;
-
-        final int bulkUpdateParams = mWmService.mAnimator.mBulkUpdateParams;
-        if ((bulkUpdateParams & SET_UPDATE_ROTATION) != 0) {
-            mUpdateRotation = true;
-            doRequest = true;
-        }
-
-        return doRequest;
-    }
-
     private final class MyHandler extends Handler {
 
         public MyHandler(Looper looper) {
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index 3ed16db..c5b47f9 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -738,12 +738,18 @@
     }
 
     @Override
-    public void updateAnimatingTypes(IWindow window, @InsetsType int animatingTypes) {
+    public void updateAnimatingTypes(IWindow window, @InsetsType int animatingTypes,
+            @Nullable ImeTracker.Token statsToken) {
         synchronized (mService.mGlobalLock) {
             final WindowState win = mService.windowForClientLocked(this, window,
                     false /* throwOnError */);
             if (win != null) {
-                win.setAnimatingTypes(animatingTypes);
+                ImeTracker.forLogging().onProgress(statsToken,
+                        ImeTracker.PHASE_WM_UPDATE_ANIMATING_TYPES);
+                win.setAnimatingTypes(animatingTypes, statsToken);
+            } else {
+                ImeTracker.forLogging().onFailed(statsToken,
+                        ImeTracker.PHASE_WM_UPDATE_ANIMATING_TYPES);
             }
         }
     }
@@ -910,10 +916,16 @@
             int privateFlags, int inputFeatures, int type, IBinder windowToken,
             InputTransferToken inputTransferToken, String inputHandleName,
             InputChannel outInputChannel) {
-        if (hostInputTransferToken == null && !mCanAddInternalSystemWindow) {
-            // Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
-            // embedded windows without providing a host window input token
-            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+        if (!Flags.updateHostInputTransferToken()) {
+            // This is not a valid security check, callers can pass in a bogus token. If the
+            // token is not known to wm, then input APIs is request focus or transferTouchGesture
+            // will fail. Removing this check allows SCVH to be created before associating with a
+            // host window.
+            if (hostInputTransferToken == null && !mCanAddInternalSystemWindow) {
+                // Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
+                // embedded windows without providing a host window input token
+                throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+            }
         }
 
         final long identity = Binder.clearCallingIdentity();
@@ -928,12 +940,14 @@
     }
 
     @Override
-    public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
+    public void updateInputChannel(IBinder channelToken,
+            @Nullable InputTransferToken hostInputTransferToken,
+            int displayId, SurfaceControl surface,
             int flags, int privateFlags, int inputFeatures, Region region) {
         final long identity = Binder.clearCallingIdentity();
         try {
-            mService.updateInputChannel(channelToken, displayId, surface, flags,
-                    mCanAddInternalSystemWindow ? privateFlags : 0, inputFeatures, region);
+            mService.updateInputChannel(channelToken, hostInputTransferToken, displayId, surface,
+                    flags, mCanAddInternalSystemWindow ? privateFlags : 0, inputFeatures, region);
         } finally {
             Binder.restoreCallingIdentity(identity);
         }
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index eafc8be..016ceba 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -24,6 +24,10 @@
 
 import android.annotation.NonNull;
 import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.hardware.HardwareBuffer;
+import android.media.Image;
+import android.media.ImageReader;
 import android.os.Process;
 import android.os.SystemClock;
 import android.os.Trace;
@@ -33,10 +37,12 @@
 
 import com.android.internal.annotations.GuardedBy;
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.policy.TransitionAnimation;
 import com.android.server.LocalServices;
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider;
 import com.android.server.wm.nano.WindowManagerProtos.TaskSnapshotProto;
+import com.android.window.flags.Flags;
 
 import java.io.File;
 import java.io.FileOutputStream;
@@ -400,23 +406,20 @@
                 Slog.e(TAG, "Invalid task snapshot hw buffer, taskId=" + mId);
                 return false;
             }
-            final Bitmap bitmap = Bitmap.wrapHardwareBuffer(
-                    mSnapshot.getHardwareBuffer(), mSnapshot.getColorSpace());
-            if (bitmap == null) {
-                Slog.e(TAG, "Invalid task snapshot hw bitmap");
-                return false;
-            }
 
-            final Bitmap swBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false /* isMutable */);
+            final HardwareBuffer hwBuffer = mSnapshot.getHardwareBuffer();
+            final int width = hwBuffer.getWidth();
+            final int height = hwBuffer.getHeight();
+            final int pixelFormat = hwBuffer.getFormat();
+            final Bitmap swBitmap = !Flags.reduceTaskSnapshotMemoryUsage()
+                    || (pixelFormat != PixelFormat.RGB_565 && pixelFormat != PixelFormat.RGBA_8888)
+                    || !mSnapshot.isRealSnapshot()
+                    || TransitionAnimation.hasProtectedContent(hwBuffer)
+                    ? copyToSwBitmapReadBack()
+                    : copyToSwBitmapDirect(width, height, pixelFormat);
             if (swBitmap == null) {
-                Slog.e(TAG, "Bitmap conversion from (config=" + bitmap.getConfig() + ", isMutable="
-                        + bitmap.isMutable() + ") to (config=ARGB_8888, isMutable=false) failed.");
                 return false;
             }
-            final int width = bitmap.getWidth();
-            final int height = bitmap.getHeight();
-            bitmap.recycle();
-
             final File file = mPersistInfoProvider.getHighResolutionBitmapFile(mId, mUserId);
             try (FileOutputStream fos = new FileOutputStream(file)) {
                 swBitmap.compress(JPEG, COMPRESS_QUALITY, fos);
@@ -448,6 +451,58 @@
             return true;
         }
 
+        private Bitmap copyToSwBitmapReadBack() {
+            final Bitmap bitmap = Bitmap.wrapHardwareBuffer(
+                    mSnapshot.getHardwareBuffer(), mSnapshot.getColorSpace());
+            if (bitmap == null) {
+                Slog.e(TAG, "Invalid task snapshot hw bitmap");
+                return null;
+            }
+
+            final Bitmap swBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, false /* isMutable */);
+            if (swBitmap == null) {
+                Slog.e(TAG, "Bitmap conversion from (config=" + bitmap.getConfig()
+                        + ", isMutable=" + bitmap.isMutable()
+                        + ") to (config=ARGB_8888, isMutable=false) failed.");
+                return null;
+            }
+            bitmap.recycle();
+            return swBitmap;
+        }
+
+        /**
+         * Use ImageReader to create the software bitmap, so SkImage won't create an extra texture.
+         */
+        private Bitmap copyToSwBitmapDirect(int width, int height, int pixelFormat) {
+            try (ImageReader ir = ImageReader.newInstance(width, height,
+                    pixelFormat, 1 /* maxImages */)) {
+                ir.getSurface().attachAndQueueBufferWithColorSpace(mSnapshot.getHardwareBuffer(),
+                        mSnapshot.getColorSpace());
+                try (Image image = ir.acquireLatestImage()) {
+                    if (image == null || image.getPlaneCount() < 1) {
+                        Slog.e(TAG, "Image reader cannot acquire image");
+                        return null;
+                    }
+
+                    final Image.Plane[] planes = image.getPlanes();
+                    if (planes.length != 1) {
+                        Slog.e(TAG, "Image reader cannot get plane");
+                        return null;
+                    }
+                    final Image.Plane plane = planes[0];
+                    final int rowPadding = plane.getRowStride() - plane.getPixelStride()
+                            * image.getWidth();
+                    final Bitmap swBitmap = Bitmap.createBitmap(
+                            image.getWidth() + rowPadding / plane.getPixelStride() /* width */,
+                            image.getHeight() /* height */,
+                            pixelFormat == PixelFormat.RGB_565
+                                    ? Bitmap.Config.RGB_565 : Bitmap.Config.ARGB_8888);
+                    swBitmap.copyPixelsFromBuffer(plane.getBuffer());
+                    return swBitmap;
+                }
+            }
+        }
+
         @Override
         public boolean equals(Object o) {
             if (o == null || getClass() != o.getClass()) return false;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 8587b5a..0531828 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1832,6 +1832,17 @@
                 && supportsMultiWindowInDisplayArea(tda);
     }
 
+    /** Returns true if the task bounds should persist across power cycles. */
+    private static boolean persistTaskBounds(@NonNull WindowConfiguration configuration) {
+        return configuration.getWindowingMode() == WINDOWING_MODE_FREEFORM;
+    }
+
+    /** Returns true if the nested task is allowed to have independent bounds from its parent. */
+    private static boolean allowIndependentBoundsFromParent(
+            @NonNull WindowConfiguration configuration) {
+        return configuration.getWindowingMode() == WINDOWING_MODE_FREEFORM;
+    }
+
     /**
      * Check whether this task can be launched on the specified display.
      *
@@ -1996,11 +2007,11 @@
     private void onConfigurationChangedInner(Configuration newParentConfig) {
         // Check if the new configuration supports persistent bounds (eg. is Freeform) and if so
         // restore the last recorded non-fullscreen bounds.
-        final boolean prevPersistTaskBounds = getWindowConfiguration().persistTaskBounds();
-        boolean nextPersistTaskBounds =
-                getRequestedOverrideConfiguration().windowConfiguration.persistTaskBounds();
+        final boolean prevPersistTaskBounds = persistTaskBounds(getWindowConfiguration());
+        boolean nextPersistTaskBounds = persistTaskBounds(
+                getRequestedOverrideConfiguration().windowConfiguration);
         if (getRequestedOverrideWindowingMode() == WINDOWING_MODE_UNDEFINED) {
-            nextPersistTaskBounds = newParentConfig.windowConfiguration.persistTaskBounds();
+            nextPersistTaskBounds = persistTaskBounds(newParentConfig.windowConfiguration);
         }
         // Only restore to the last non-fullscreen bounds when the requested override bounds
         // have not been explicitly set already.
@@ -2042,7 +2053,7 @@
 
         // If the configuration supports persistent bounds (eg. Freeform), keep track of the
         // current (non-fullscreen) bounds for persistence.
-        if (getWindowConfiguration().persistTaskBounds()) {
+        if (persistTaskBounds(getWindowConfiguration())) {
             final Rect currentBounds = getRequestedOverrideBounds();
             if (!currentBounds.isEmpty()) {
                 setLastNonFullscreenBounds(currentBounds);
@@ -2383,33 +2394,48 @@
     }
 
     void updateOverrideConfigurationFromLaunchBounds() {
-        // If the task is controlled by another organized task, do not set override
-        // configurations and let its parent (organized task) to control it;
         final Task rootTask = getRootTask();
-        boolean shouldInheritBounds = rootTask != this && rootTask.isOrganized();
-        if (DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
-            // Only inherit from organized parent when this task is not organized.
-            shouldInheritBounds &= !isOrganized();
-        }
-        final Rect bounds = shouldInheritBounds ? null : getLaunchBounds();
-        setBounds(bounds);
-    }
-
-    /** Returns the bounds that should be used to launch this task. */
-    Rect getLaunchBounds() {
-        final Task rootTask = getRootTask();
-        if (rootTask == null) {
-            return null;
-        }
-
+        final boolean hasParentTask = rootTask != this;
         final int windowingMode = getWindowingMode();
-        if (!isActivityTypeStandardOrUndefined()
-                || windowingMode == WINDOWING_MODE_FULLSCREEN) {
-            return isResizeable() ? rootTask.getRequestedOverrideBounds() : null;
-        } else if (!getWindowConfiguration().persistTaskBounds()) {
-            return rootTask.getRequestedOverrideBounds();
+        final boolean isNonStandardOrFullscreen = !isActivityTypeStandardOrUndefined()
+                || windowingMode == WINDOWING_MODE_FULLSCREEN;
+        if (!Flags.nestedTasksWithIndependentBounds()
+                && !DesktopExperienceFlags.ENABLE_MULTIPLE_DESKTOPS_BACKEND.isTrue()) {
+            final Rect bounds;
+            if (hasParentTask && rootTask.isOrganized()) {
+                bounds = null;
+            } else if (isNonStandardOrFullscreen) {
+                bounds = isResizeable() ? rootTask.getRequestedOverrideBounds() : null;
+            } else if (!persistTaskBounds(getWindowConfiguration())) {
+                bounds = rootTask.getRequestedOverrideBounds();
+            } else {
+                bounds = mLastNonFullscreenBounds;
+            }
+            setBounds(bounds);
+            return;
         }
-        return mLastNonFullscreenBounds;
+
+        // Non-standard/fullscreen unresizable tasks should always inherit.
+        boolean shouldInheritBounds = isNonStandardOrFullscreen && !isResizeable();
+        // Task itself is not organized (e.g. Home), just inherit from its organized parent.
+        shouldInheritBounds |= hasParentTask && rootTask.isOrganized() && !isOrganized();
+        // Nested tasks should inherit when they're not allowed to have independent bounds, such as
+        // in multi-window split-screen.
+        shouldInheritBounds |= hasParentTask
+                && !(allowIndependentBoundsFromParent(getWindowConfiguration())
+                && persistTaskBounds(getWindowConfiguration()));
+        if (shouldInheritBounds) {
+            setBounds(null);
+            return;
+        }
+        if (!hasParentTask && !persistTaskBounds(getWindowConfiguration())) {
+            // Non-nested, non-persistable tasks such as PIP or multi-window floating windows.
+            return;
+        }
+        // Non-nested, persisted tasks (e.g. top-level freeform) or nested persisted tasks that
+        // allow independent bounds from parent (e.g. nested freeform) should use launch-params
+        // bounds set to |mLastNonFullscreenBounds|.
+        setBounds(mLastNonFullscreenBounds);
     }
 
     void setRootProcess(WindowProcessController proc) {
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 803c21c..65001f4 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -1249,7 +1249,7 @@
                 // Skip dispatching the change for PiP task to avoid its activity drawing for the
                 // intermediate state which will cause flickering. The final PiP bounds in new
                 // rotation will be applied by PipTransition.
-                ar.mDisplayContent.mPinnedTaskController.setEnterPipTransaction(null);
+                ar.mDisplayContent.mPinnedTaskController.setEnterPipWithRotatedTransientLaunch();
             }
             return inPip;
         }
@@ -3191,7 +3191,8 @@
             // Fixed rotation only applies to opening or changing activity.
             return;
         }
-        if (task.inMultiWindowMode() && taskTopRunning.inMultiWindowMode()) {
+        if (!ActivityTaskManagerService.isPip2ExperimentEnabled()
+                && task.inMultiWindowMode() && taskTopRunning.inMultiWindowMode()) {
             // Display won't be rotated for multi window Task, so the fixed rotation won't be
             // applied. This can happen when the windowing mode is changed before the previous
             // fixed rotation is applied. Check both task and activity because the activity keeps
@@ -3400,7 +3401,6 @@
      * Applies the new configuration for the changed displays. Returns the activities that should
      * check whether to deliver the new configuration to clients.
      */
-    @Nullable
     void applyDisplayChangeIfNeeded(@NonNull ArraySet<WindowContainer<?>> activitiesMayChange) {
         for (int i = mParticipants.size() - 1; i >= 0; --i) {
             final WindowContainer<?> wc = mParticipants.valueAt(i);
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 9b3b445..51c3da0 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -1284,13 +1284,14 @@
             // ignore ourself obviously
             if (mPlayingTransitions.get(i) == transition) continue;
             if (getIsIndependent(mPlayingTransitions.get(i), transition)) continue;
-            if (track >= 0) {
+            if (track < 0) {
+                track = mPlayingTransitions.get(i).mAnimationTrack;
+            } else if (track != mPlayingTransitions.get(i).mAnimationTrack) {
                 // At this point, transition overlaps with multiple tracks, so just wait for
                 // everything
                 sync = true;
                 break;
             }
-            track = mPlayingTransitions.get(i).mAnimationTrack;
         }
         if (sync) {
             track = 0;
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index e1553cd..b042e11 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -117,8 +117,11 @@
     private boolean mShouldOffsetWallpaperCenter;
 
     // This is for WallpaperCropper, which has cropping logic for the default display only.
+    // This is lazily initialization by getOrCreateDefaultDisplayInfo. DO NOT use this member
+    // variable directly.
     // TODO(b/400685784) make the WallpaperCropper operate on every display independently
-    private final WallpaperDefaultDisplayInfo mDefaultDisplayInfo;
+    @Nullable
+    private WallpaperDefaultDisplayInfo mDefaultDisplayInfo = null;
 
     private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> {
         final ActivityRecord ar = w.mActivityRecord;
@@ -202,14 +205,12 @@
     WallpaperController(WindowManagerService service, DisplayContent displayContent) {
         mService = service;
         mDisplayContent = displayContent;
-        WindowManager windowManager = service.mContext.getSystemService(WindowManager.class);
         Resources resources = service.mContext.getResources();
         mMinWallpaperScale =
                 resources.getFloat(com.android.internal.R.dimen.config_wallpaperMinScale);
         mMaxWallpaperScale = resources.getFloat(R.dimen.config_wallpaperMaxScale);
         mShouldOffsetWallpaperCenter = resources.getBoolean(
                 com.android.internal.R.bool.config_offsetWallpaperToCenterOfLargestDisplay);
-        mDefaultDisplayInfo = new WallpaperDefaultDisplayInfo(windowManager, resources);
     }
 
     void resetLargestDisplay(Display display) {
@@ -358,8 +359,8 @@
                     wallpaperWin.mRequestedWidth, wallpaperWin.mRequestedHeight);
             SparseArray<Rect> cropHints = token.getCropHints();
             wallpaperFrame = bitmapSize.x <= 0 || bitmapSize.y <= 0 ? wallpaperWin.getFrame()
-                    : WallpaperCropper.getCrop(screenSize, mDefaultDisplayInfo, bitmapSize,
-                            cropHints, wallpaperWin.isRtl());
+                    : WallpaperCropper.getCrop(screenSize, getOrCreateDefaultDisplayInfo(),
+                            bitmapSize, cropHints, wallpaperWin.isRtl());
             int frameWidth = wallpaperFrame.width();
             int frameHeight = wallpaperFrame.height();
             float frameRatio = (float) frameWidth / frameHeight;
@@ -506,6 +507,16 @@
         return changed;
     }
 
+    private WallpaperDefaultDisplayInfo getOrCreateDefaultDisplayInfo() {
+        if (mDefaultDisplayInfo != null) {
+            return mDefaultDisplayInfo;
+        }
+        WindowManager windowManager = mService.mContext.getSystemService(WindowManager.class);
+        Resources resources = mService.mContext.getResources();
+        mDefaultDisplayInfo = new WallpaperDefaultDisplayInfo(windowManager, resources);
+        return mDefaultDisplayInfo;
+    }
+
     /**
      * Get an extra offset if needed ({@link #mShouldOffsetWallpaperCenter} = true, typically on
      * multiple display devices) so that the wallpaper in a smaller display ends up centered at the
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index 80137a2..3f2b40c 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -65,9 +65,6 @@
     /** Time of current animation step. Reset on each iteration */
     long mCurrentTime;
 
-    int mBulkUpdateParams = 0;
-    Object mLastWindowFreezeSource;
-
     private boolean mInitialized = false;
 
     private Choreographer mChoreographer;
@@ -145,7 +142,6 @@
         final int animationFlags = useShellTransition ? CHILDREN : (TRANSITION | CHILDREN);
         boolean rootAnimating = false;
         mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS;
-        mBulkUpdateParams = 0;
         if (DEBUG_WINDOW_TRACE) {
             Slog.i(TAG, "!!! animate: entry time=" + mCurrentTime);
         }
@@ -202,8 +198,7 @@
         }
 
         final boolean hasPendingLayoutChanges = root.hasPendingLayoutChanges(this);
-        final boolean doRequest = mBulkUpdateParams != 0 && root.copyAnimToLayoutParams();
-        if (hasPendingLayoutChanges || doRequest) {
+        if (hasPendingLayoutChanges) {
             mService.mWindowPlacerLocked.requestTraversal();
         }
 
@@ -245,7 +240,6 @@
 
         if (DEBUG_WINDOW_TRACE) {
             Slog.i(TAG, "!!! animate: exit"
-                    + " mBulkUpdateParams=" + Integer.toHexString(mBulkUpdateParams)
                     + " hasPendingLayoutChanges=" + hasPendingLayoutChanges);
         }
     }
@@ -265,17 +259,6 @@
         mRunningExpensiveAnimations = runningExpensiveAnimations;
     }
 
-    private static String bulkUpdateParamsToString(int bulkUpdateParams) {
-        StringBuilder builder = new StringBuilder(128);
-        if ((bulkUpdateParams & WindowSurfacePlacer.SET_UPDATE_ROTATION) != 0) {
-            builder.append(" UPDATE_ROTATION");
-        }
-        if ((bulkUpdateParams & WindowSurfacePlacer.SET_WALLPAPER_ACTION_PENDING) != 0) {
-            builder.append(" SET_WALLPAPER_ACTION_PENDING");
-        }
-        return builder.toString();
-    }
-
     public void dumpLocked(PrintWriter pw, String prefix, boolean dumpAll) {
         final String subPrefix = "  " + prefix;
 
@@ -292,11 +275,6 @@
             pw.print(prefix); pw.print("mCurrentTime=");
                     pw.println(TimeUtils.formatUptime(mCurrentTime));
         }
-        if (mBulkUpdateParams != 0) {
-            pw.print(prefix); pw.print("mBulkUpdateParams=0x");
-                    pw.print(Integer.toHexString(mBulkUpdateParams));
-                    pw.println(bulkUpdateParamsToString(mBulkUpdateParams));
-        }
     }
 
     void scheduleAnimation() {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index c078d67b..fb38c58 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -198,6 +198,8 @@
 import android.graphics.Region;
 import android.hardware.configstore.V1_0.OptionalBool;
 import android.hardware.configstore.V1_1.ISurfaceFlingerConfigs;
+import android.hardware.devicestate.DeviceState;
+import android.hardware.devicestate.DeviceStateManager;
 import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerInternal;
 import android.hardware.input.InputSettings;
@@ -1032,6 +1034,21 @@
     PowerManager mPowerManager;
     PowerManagerInternal mPowerManagerInternal;
 
+    private DeviceStateManager mDeviceStateManager;
+    private DeviceStateCallback mDeviceStateCallback;
+    private class DeviceStateCallback implements DeviceStateManager.DeviceStateCallback {
+        private DeviceState mCurrentDeviceState;
+        @Override
+        public void onDeviceStateChanged(@NonNull DeviceState state) {
+            mCurrentDeviceState = state;
+        }
+
+        boolean isInRearDisplayOuterDefaultState() {
+            return mCurrentDeviceState != null && mCurrentDeviceState
+                    .hasProperties(DeviceState.PROPERTY_FEATURE_REAR_DISPLAY_OUTER_DEFAULT);
+        }
+    }
+
     private float mWindowAnimationScaleSetting = 1.0f;
     private float mTransitionAnimationScaleSetting = 1.0f;
     private float mAnimatorDurationScaleSetting = 1.0f;
@@ -1317,6 +1334,10 @@
         mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
         mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
 
+        mDeviceStateManager = context.getSystemService(DeviceStateManager.class);
+        mDeviceStateCallback = new DeviceStateCallback();
+        mDeviceStateManager.registerCallback(new HandlerExecutor(mH), mDeviceStateCallback);
+
         if (mPowerManagerInternal != null) {
             mPowerManagerInternal.registerLowPowerModeObserver(
                     new PowerManagerInternal.LowPowerModeListener() {
@@ -2132,7 +2153,6 @@
         }
 
         final DisplayContent dc = win.getDisplayContent();
-        dc.getDisplayRotation().markForSeamlessRotation(win, false /* seamlesslyRotated */);
 
         win.resetAppOpsState();
 
@@ -4734,7 +4754,8 @@
 
     @EnforcePermission(android.Manifest.permission.MANAGE_APP_TOKENS)
     @Override
-    public void updateDisplayWindowAnimatingTypes(int displayId, @InsetsType int animatingTypes) {
+    public void updateDisplayWindowAnimatingTypes(int displayId, @InsetsType int animatingTypes,
+            @Nullable ImeTracker.Token statsToken) {
         updateDisplayWindowAnimatingTypes_enforcePermission();
         if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) {
             final long origId = Binder.clearCallingIdentity();
@@ -4742,9 +4763,13 @@
                 synchronized (mGlobalLock) {
                     final DisplayContent dc = mRoot.getDisplayContent(displayId);
                     if (dc == null || dc.mRemoteInsetsControlTarget == null) {
+                        ImeTracker.forLogging().onFailed(statsToken,
+                                ImeTracker.PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES);
                         return;
                     }
-                    dc.mRemoteInsetsControlTarget.setAnimatingTypes(animatingTypes);
+                    ImeTracker.forLogging().onProgress(statsToken,
+                            ImeTracker.PHASE_WM_UPDATE_DISPLAY_WINDOW_ANIMATING_TYPES);
+                    dc.mRemoteInsetsControlTarget.setAnimatingTypes(animatingTypes, statsToken);
                 }
             } finally {
                 Binder.restoreCallingIdentity(origId);
@@ -7594,6 +7619,26 @@
     }
 
     @Override
+    public boolean isEligibleForDesktopMode(int displayId) {
+        if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "isEligibleForDesktopMode()")) {
+            throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
+        }
+
+        synchronized (mGlobalLock) {
+            final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+            if (displayContent == null) {
+                ProtoLog.e(WM_ERROR, "Attempted to check isEligibleForDesktopMode() "
+                        + "for a display that does not exist: %d", displayId);
+                return false;
+            }
+            if (!displayContent.isSystemDecorationsSupported()) {
+                return false;
+            }
+            return displayContent.isDefaultDisplay || displayContent.allowContentModeSwitch();
+        }
+    }
+
+    @Override
     public void setShouldShowSystemDecors(int displayId, boolean shouldShow) {
         if (!checkCallingPermission(INTERNAL_SYSTEM_WINDOW, "setShouldShowSystemDecors()")) {
             throw new SecurityException("Requires INTERNAL_SYSTEM_WINDOW permission");
@@ -8950,6 +8995,17 @@
             }
         }
 
+        if (mDeviceStateCallback.isInRearDisplayOuterDefaultState()) {
+            final Display[] rearDisplays = mDisplayManager
+                    .getDisplays(DisplayManager.DISPLAY_CATEGORY_REAR);
+            if (rearDisplays.length > 0 && rearDisplays[0].getDisplayId() == t.getDisplayId()) {
+                // Do not change display focus to the inner display if we're in this mode. Note that
+                // in this mode, the inner display is configured as a rear display.
+                Slog.w(TAG, "Ignoring focus change because device is in RDM.");
+                return;
+            }
+        }
+
         clearPointerDownOutsideFocusRunnable();
 
         final InputTarget focusedInputTarget = mFocusedInputTarget;
@@ -9322,10 +9378,12 @@
 
     /**
      * Updates the flags on an existing surface's input channel. This assumes the surface provided
-     * is the one associated with the provided input-channel. If this isn't the case, behavior
-     * is undefined.
+     * is the one associated with the provided input-channel. If this isn't the case, behavior is
+     * undefined.
      */
-    void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
+    void updateInputChannel(IBinder channelToken,
+            @Nullable InputTransferToken hostInputTransferToken, int displayId,
+            SurfaceControl surface,
             int flags, int privateFlags, int inputFeatures, Region region) {
         final InputApplicationHandle applicationHandle;
         final String name;
@@ -9339,6 +9397,11 @@
             name = win.toString();
             applicationHandle = win.getApplicationHandle();
             win.setIsFocusable((flags & FLAG_NOT_FOCUSABLE) == 0);
+            if (Flags.updateHostInputTransferToken()) {
+                WindowState hostWindowState = hostInputTransferToken != null
+                        ? mInputToWindowMap.get(hostInputTransferToken.getToken()) : null;
+                win.updateHost(hostWindowState);
+            }
         }
 
         updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 6c3d516..c19fa8c 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -473,35 +473,6 @@
         transition.setAllReady();
     }
 
-    // TODO(b/365884835): remove this method and callers.
-    @Override
-    public int startLegacyTransition(int type, @NonNull RemoteAnimationAdapter adapter,
-            @NonNull IWindowContainerTransactionCallback callback,
-            @NonNull WindowContainerTransaction t) {
-        enforceTaskPermission("startLegacyTransition()");
-        final CallerInfo caller = new CallerInfo();
-        final long ident = Binder.clearCallingIdentity();
-        int syncId;
-        try {
-            synchronized (mGlobalLock) {
-                if (type < 0) {
-                    throw new IllegalArgumentException("Can't create transition with no type");
-                }
-                if (mTransitionController.getTransitionPlayer() != null) {
-                    throw new IllegalArgumentException("Can't use legacy transitions in"
-                            + " when shell transitions are enabled.");
-                }
-                syncId = startSyncWithOrganizer(callback);
-                applyTransaction(t, syncId, mService.mChainTracker.startLegacy("legacyTransit"),
-                        caller);
-                setSyncReady(syncId);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(ident);
-        }
-        return syncId;
-    }
-
     @Override
     public void finishTransition(@NonNull IBinder transitionToken,
             @Nullable WindowContainerTransaction t) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index bdd1372..d356128 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -337,6 +337,11 @@
     public static final int ACTIVITY_STATE_FLAG_VISIBLE_MULTI_WINDOW_MODE = 1 << 25;
     public static final int ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER = 0x0000ffff;
 
+    private static final int ACTIVITY_STATE_VISIBLE =
+            com.android.window.flags.Flags.useVisibleRequestedForProcessTracker()
+                    ? ACTIVITY_STATE_FLAG_IS_VISIBLE
+                    : ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE;
+
     /**
      * The state for oom-adjustment calculation. The higher 16 bits are the activity states, and the
      * lower 16 bits are the task layer rank (see {@link Task#mLayerRank}). This field is written by
@@ -1260,8 +1265,7 @@
         int nonOccludedRatio = 0;
         long perceptibleTaskStoppedTimeMillis = Long.MIN_VALUE;
         final boolean wasResumed = hasResumedActivity();
-        final boolean wasAnyVisible = (mActivityStateFlags
-                & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0;
+        final boolean wasAnyVisible = (mActivityStateFlags & ACTIVITY_STATE_VISIBLE) != 0;
         for (int i = mActivities.size() - 1; i >= 0; i--) {
             final ActivityRecord r = mActivities.get(i);
             if (r.isVisible()) {
@@ -1275,8 +1279,9 @@
             if (task.mLayerRank != Task.LAYER_RANK_INVISIBLE) {
                 stateFlags |= ACTIVITY_STATE_FLAG_HAS_ACTIVITY_IN_VISIBLE_TASK;
             }
+            final ActivityRecord.State state = r.getState();
             if (r.isVisibleRequested()) {
-                if (r.isState(RESUMED)) {
+                if (state == RESUMED) {
                     stateFlags |= ACTIVITY_STATE_FLAG_HAS_RESUMED;
                     final int windowingMode = r.getWindowingMode();
                     if (windowingMode == WINDOWING_MODE_MULTI_WINDOW
@@ -1301,13 +1306,21 @@
                 // this process, we'd find out the one with the minimal layer, thus it'll
                 // get a higher adj score.
             } else if (!visible && bestInvisibleState != PAUSING) {
-                if (r.isState(PAUSING, PAUSED)) {
+                if (state == PAUSING) {
                     bestInvisibleState = PAUSING;
-                } else if (r.isState(STOPPING)) {
+                    // Treat PAUSING as visible in case the next activity in the same process has
+                    // not yet been set as visible-requested.
+                    if (com.android.window.flags.Flags.useVisibleRequestedForProcessTracker()
+                            && r.isVisible()) {
+                        stateFlags |= ACTIVITY_STATE_FLAG_IS_VISIBLE;
+                    }
+                } else if (state == PAUSED) {
+                    bestInvisibleState = PAUSED;
+                } else if (state == STOPPING) {
                     bestInvisibleState = STOPPING;
                     // Not "finishing" if any of activity isn't finishing.
                     allStoppingFinishing &= r.finishing;
-                } else if (bestInvisibleState == DESTROYED && r.isState(STOPPED)) {
+                } else if (bestInvisibleState == DESTROYED && state == STOPPED) {
                     if (task.mIsPerceptible) {
                         perceptibleTaskStoppedTimeMillis =
                                 Long.max(r.mStoppedTime, perceptibleTaskStoppedTimeMillis);
@@ -1340,7 +1353,7 @@
         stateFlags |= minTaskLayer & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
         if (visible) {
             stateFlags |= ACTIVITY_STATE_FLAG_IS_VISIBLE;
-        } else if (bestInvisibleState == PAUSING) {
+        } else if (bestInvisibleState == PAUSING || bestInvisibleState == PAUSED) {
             stateFlags |= ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED;
         } else if (bestInvisibleState == STOPPING) {
             stateFlags |= ACTIVITY_STATE_FLAG_IS_STOPPING;
@@ -1351,8 +1364,7 @@
         mActivityStateFlags = stateFlags;
         mPerceptibleTaskStoppedTimeMillis = perceptibleTaskStoppedTimeMillis;
 
-        final boolean anyVisible = (stateFlags
-                & (ACTIVITY_STATE_FLAG_IS_VISIBLE | ACTIVITY_STATE_FLAG_IS_WINDOW_VISIBLE)) != 0;
+        final boolean anyVisible = (stateFlags & ACTIVITY_STATE_VISIBLE) != 0;
         if (!wasAnyVisible && anyVisible) {
             mAtm.mVisibleActivityProcessTracker.onAnyActivityVisible(this);
             mAtm.mWindowManager.onProcessActivityVisibilityChanged(mUid, true /*visible*/);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 4a93904..af52001 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -169,7 +169,6 @@
 import static com.android.server.wm.WindowStateProto.IS_VISIBLE;
 import static com.android.server.wm.WindowStateProto.KEEP_CLEAR_AREAS;
 import static com.android.server.wm.WindowStateProto.MERGED_LOCAL_INSETS_SOURCES;
-import static com.android.server.wm.WindowStateProto.PENDING_SEAMLESS_ROTATION;
 import static com.android.server.wm.WindowStateProto.REMOVED;
 import static com.android.server.wm.WindowStateProto.REMOVE_ON_EXIT;
 import static com.android.server.wm.WindowStateProto.REQUESTED_HEIGHT;
@@ -231,7 +230,6 @@
 import android.view.InsetsSourceControl;
 import android.view.InsetsState;
 import android.view.Surface;
-import android.view.Surface.Rotation;
 import android.view.SurfaceControl;
 import android.view.View;
 import android.view.ViewDebug;
@@ -399,7 +397,6 @@
      * rotation.
      */
     final boolean mForceSeamlesslyRotate;
-    SeamlessRotator mPendingSeamlessRotate;
 
     private RemoteCallbackList<IWindowFocusObserver> mFocusCallbacks;
 
@@ -593,13 +590,6 @@
     /** The time when the window was last requested to redraw for orientation change. */
     private long mOrientationChangeRedrawRequestTime;
 
-    /**
-     * The orientation during the last visible call to relayout. If our
-     * current orientation is different, the window can't be ready
-     * to be shown.
-     */
-    int mLastVisibleLayoutRotation = -1;
-
     /** Is this window now (or just being) removed? */
     boolean mRemoved;
 
@@ -655,15 +645,6 @@
     boolean mIsSurfacePositionPaused;
 
     /**
-     * During seamless rotation we have two phases, first the old window contents
-     * are rotated to look as if they didn't move in the new coordinate system. Then we
-     * have to freeze updates to this layer (to preserve the transformation) until
-     * the resize actually occurs. This is true from when the transformation is set
-     * and false until the transaction to resize is sent.
-     */
-    boolean mSeamlesslyRotated = false;
-
-    /**
      * Whether the IME insets have been consumed. If {@code true}, this window won't be able to
      * receive visible IME insets; {@code false}, otherwise.
      */
@@ -778,11 +759,6 @@
      */
     private boolean mInsetsAnimationRunning;
 
-    private final Consumer<SurfaceControl.Transaction> mSeamlessRotationFinishedConsumer = t -> {
-        finishSeamlessRotation(t);
-        updateSurfacePosition(t);
-    };
-
     private final Consumer<SurfaceControl.Transaction> mSetSurfacePositionConsumer = t -> {
         // Only apply the position to the surface when there's no leash created.
         if (mSurfaceControl != null && mSurfaceControl.isValid() && !mSurfaceAnimator.hasLeash()) {
@@ -845,7 +821,8 @@
     }
 
     @Override
-    public void setAnimatingTypes(@InsetsType int animatingTypes) {
+    public void setAnimatingTypes(@InsetsType int animatingTypes,
+            @Nullable ImeTracker.Token statsToken) {
         if (mAnimatingTypes != animatingTypes) {
             if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
                 Trace.instant(TRACE_TAG_WINDOW_MANAGER,
@@ -859,10 +836,15 @@
             mAnimatingTypes = animatingTypes;
 
             if (android.view.inputmethod.Flags.reportAnimatingInsetsTypes()) {
+                ImeTracker.forLogging().onProgress(statsToken,
+                        ImeTracker.PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED);
                 final InsetsStateController insetsStateController =
                         getDisplayContent().getInsetsStateController();
-                insetsStateController.onAnimatingTypesChanged(this);
+                insetsStateController.onAnimatingTypesChanged(this, statsToken);
             }
+        } else {
+            ImeTracker.forLogging().onFailed(statsToken,
+                    ImeTracker.PHASE_WM_WINDOW_ANIMATING_TYPES_CHANGED);
         }
     }
 
@@ -899,69 +881,6 @@
         return visible && mFrozenInsetsState == null;
     }
 
-    void seamlesslyRotateIfAllowed(Transaction transaction, @Rotation int oldRotation,
-            @Rotation int rotation, boolean requested) {
-        // Invisible windows and the wallpaper do not participate in the seamless rotation animation
-        if (!isVisibleNow() || mIsWallpaper) {
-            return;
-        }
-
-        if (mToken.hasFixedRotationTransform()) {
-            // The transform of its surface is handled by fixed rotation.
-            return;
-        }
-        final Task task = getTask();
-        if (task != null && task.inPinnedWindowingMode()) {
-            // It is handled by PinnedTaskController. Note that the windowing mode of activity
-            // and windows may still be fullscreen.
-            return;
-        }
-
-        if (mPendingSeamlessRotate != null) {
-            oldRotation = mPendingSeamlessRotate.getOldRotation();
-        }
-
-        // Skip performing seamless rotation when the controlled insets is IME with visible state.
-        if (mControllableInsetProvider != null
-                && mControllableInsetProvider.getSource().getType() == WindowInsets.Type.ime()) {
-            return;
-        }
-
-        if (mForceSeamlesslyRotate || requested) {
-            if (mControllableInsetProvider != null) {
-                mControllableInsetProvider.startSeamlessRotation();
-            }
-            mPendingSeamlessRotate = new SeamlessRotator(oldRotation, rotation, getDisplayInfo(),
-                    false /* applyFixedTransformationHint */);
-            // The surface position is going to be unrotated according to the last position.
-            // Make sure the source position is up-to-date.
-            mLastSurfacePosition.set(mSurfacePosition.x, mSurfacePosition.y);
-            mPendingSeamlessRotate.unrotate(transaction, this);
-            getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
-                    true /* seamlesslyRotated */);
-            applyWithNextDraw(mSeamlessRotationFinishedConsumer);
-        }
-    }
-
-    void cancelSeamlessRotation() {
-        finishSeamlessRotation(getPendingTransaction());
-    }
-
-    void finishSeamlessRotation(SurfaceControl.Transaction t) {
-        if (mPendingSeamlessRotate == null) {
-            return;
-        }
-
-        mPendingSeamlessRotate.finish(t, this);
-        mPendingSeamlessRotate = null;
-
-        getDisplayContent().getDisplayRotation().markForSeamlessRotation(this,
-            false /* seamlesslyRotated */);
-        if (mControllableInsetProvider != null) {
-            mControllableInsetProvider.finishSeamlessRotation();
-        }
-    }
-
     List<Rect> getSystemGestureExclusion() {
         return mExclusionRects;
     }
@@ -2176,8 +2095,7 @@
                 && (mAttrs.privateFlags & PRIVATE_FLAG_NO_MOVE_ANIMATION) == 0
                 && !isDragResizing()
                 && hasMovementAnimation
-                && !mWinAnimator.mLastHidden
-                && !mSeamlesslyRotated;
+                && !mWinAnimator.mLastHidden;
     }
 
     /**
@@ -3998,7 +3916,6 @@
         proto.write(REMOVED, mRemoved);
         proto.write(IS_ON_SCREEN, isOnScreen());
         proto.write(IS_VISIBLE, isVisible);
-        proto.write(PENDING_SEAMLESS_ROTATION, mPendingSeamlessRotate != null);
         proto.write(FORCE_SEAMLESS_ROTATION, mForceSeamlesslyRotate);
         proto.write(HAS_COMPAT_SCALE, hasCompatScale());
         proto.write(GLOBAL_SCALE, mGlobalScale);
@@ -4144,14 +4061,6 @@
                     + " mDestroying=" + mDestroying
                     + " mRemoved=" + mRemoved);
         }
-        pw.print(prefix + "mForceSeamlesslyRotate=" + mForceSeamlesslyRotate
-                + " seamlesslyRotate: pending=");
-        if (mPendingSeamlessRotate != null) {
-            mPendingSeamlessRotate.dump(pw);
-        } else {
-            pw.print("null");
-        }
-        pw.println();
 
         if (mXOffset != 0 || mYOffset != 0) {
             pw.println(prefix + "mXOffset=" + mXOffset + " mYOffset=" + mYOffset);
@@ -4883,8 +4792,6 @@
             mWinAnimator.mEnterAnimationPending = true;
         }
 
-        mLastVisibleLayoutRotation = getDisplayContent().getRotation();
-
         mWinAnimator.mEnteringAnimation = true;
 
         Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "prepareToDisplay");
@@ -5282,9 +5189,8 @@
 
         final AsyncRotationController asyncRotationController =
                 mDisplayContent.getAsyncRotationController();
-        if ((asyncRotationController != null
-                && asyncRotationController.hasSeamlessOperation(mToken))
-                || mPendingSeamlessRotate != null) {
+        if (asyncRotationController != null
+                && asyncRotationController.hasSeamlessOperation(mToken)) {
             // Freeze position while un-rotating the window, so its surface remains at the position
             // corresponding to the original rotation.
             return;
diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
index a34b511..4fb74ef 100644
--- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
+++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java
@@ -42,9 +42,6 @@
     /** Only do a maximum of 6 repeated layouts. After that quit */
     private int mLayoutRepeatCount;
 
-    static final int SET_UPDATE_ROTATION                = 1 << 0;
-    static final int SET_WALLPAPER_ACTION_PENDING       = 1 << 1;
-
     private boolean mTraversalScheduled;
     private int mDeferDepth = 0;
     /** The number of layout requests when deferring. */
diff --git a/services/core/jni/Android.bp b/services/core/jni/Android.bp
index 66d04df..adfabe1 100644
--- a/services/core/jni/Android.bp
+++ b/services/core/jni/Android.bp
@@ -169,7 +169,7 @@
         "android.hardware.broadcastradio@1.1",
         "android.hardware.contexthub@1.0",
         "android.hardware.common.fmq-V1-ndk",
-        "android.hardware.gnss-V3-cpp",
+        "android.hardware.gnss-V5-cpp",
         "android.hardware.gnss@1.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
@@ -204,6 +204,7 @@
         "android.system.suspend.control-V1-cpp",
         "android.system.suspend.control.internal-cpp",
         "android.system.suspend-V1-ndk",
+        "android_location_flags_c_lib",
         "server_configurable_flags",
         "service.incremental",
     ],
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index e32ce52..ec8794f 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -671,9 +671,13 @@
         return;
     }
 
-    // TODO(b/383092013): Add topology validation
     const DisplayTopologyGraph displayTopology =
             android_hardware_display_DisplayTopologyGraph_toNative(env, topologyGraph);
+    if (input_flags::enable_display_topology_validation() && !displayTopology.isValid()) {
+        LOG(ERROR) << "Ignoring Invalid DisplayTopology";
+        return;
+    }
+
     mInputManager->getDispatcher().setDisplayTopology(displayTopology);
     mInputManager->getChoreographer().setDisplayTopology(displayTopology);
 }
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index 9c033e2..93f6e95 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -36,6 +36,7 @@
 #include <android/hardware/gnss/BnGnssMeasurementCallback.h>
 #include <android/hardware/gnss/BnGnssPowerIndicationCallback.h>
 #include <android/hardware/gnss/BnGnssPsdsCallback.h>
+#include <android_location_flags.h>
 #include <binder/IServiceManager.h>
 #include <nativehelper/JNIHelp.h>
 #include <pthread.h>
@@ -53,6 +54,8 @@
 #include "gnss/Gnss.h"
 #include "gnss/GnssAntennaInfo.h"
 #include "gnss/GnssAntennaInfoCallback.h"
+#include "gnss/GnssAssistance.h"
+#include "gnss/GnssAssistanceCallback.h"
 #include "gnss/GnssBatching.h"
 #include "gnss/GnssConfiguration.h"
 #include "gnss/GnssDebug.h"
@@ -114,6 +117,7 @@
 using android::hardware::gnss::GnssPowerStats;
 using android::hardware::gnss::IGnssPowerIndication;
 using android::hardware::gnss::IGnssPowerIndicationCallback;
+using android::hardware::gnss::gnss_assistance::IGnssAssistanceCallback;
 
 using IGnssAidl = android::hardware::gnss::IGnss;
 using IGnssBatchingAidl = android::hardware::gnss::IGnssBatching;
@@ -140,6 +144,9 @@
 std::unique_ptr<android::gnss::GnssVisibilityControlInterface> gnssVisibilityControlIface = nullptr;
 std::unique_ptr<android::gnss::MeasurementCorrectionsInterface> gnssMeasurementCorrectionsIface =
         nullptr;
+std::unique_ptr<android::gnss::GnssAssistanceInterface> gnssAssistanceIface = nullptr;
+
+namespace location_flags = android::location::flags;
 
 namespace android {
 
@@ -229,6 +236,9 @@
     gnss::GnssVisibilityControl_class_init_once(env, clazz);
     gnss::MeasurementCorrections_class_init_once(env, clazz);
     gnss::MeasurementCorrectionsCallback_class_init_once(env, clazz);
+    if (location_flags::gnss_assistance_interface_jni()) {
+        gnss::GnssAssistance_class_init_once(env, clazz);
+    }
     gnss::Utils_class_init_once(env);
 }
 
@@ -266,7 +276,9 @@
     gnssBatchingIface = gnssHal->getGnssBatchingInterface();
     gnssVisibilityControlIface = gnssHal->getGnssVisibilityControlInterface();
     gnssPowerIndicationIface = gnssHal->getGnssPowerIndicationInterface();
-
+    if (location_flags::gnss_assistance_interface_jni()) {
+        gnssAssistanceIface = gnssHal->getGnssAssistanceInterface();
+    }
     if (mCallbacksObj) {
         ALOGE("Callbacks already initialized");
     } else {
@@ -355,13 +367,22 @@
     // Set IGnssPowerIndication.hal callback.
     if (gnssPowerIndicationIface != nullptr) {
         sp<IGnssPowerIndicationCallback> gnssPowerIndicationCallback =
-                new GnssPowerIndicationCallback();
+                sp<GnssPowerIndicationCallback>::make();
         auto status = gnssPowerIndicationIface->setCallback(gnssPowerIndicationCallback);
         if (!checkAidlStatus(status, "IGnssPowerIndication setCallback() failed.")) {
             gnssPowerIndicationIface = nullptr;
         }
     }
 
+    // Set IGnssAssistance callback.
+    if (gnssAssistanceIface != nullptr) {
+        sp<IGnssAssistanceCallback> gnssAssistanceCallback =
+                sp<gnss::GnssAssistanceCallback>::make();
+        if (!gnssAssistanceIface->setCallback(gnssAssistanceCallback)) {
+            ALOGI("IGnssAssistanceInterface setCallback() failed");
+        }
+    }
+
     return JNI_TRUE;
 }
 
@@ -493,6 +514,15 @@
     gnssPsdsIface->injectPsdsData(data, length, psdsType);
 }
 
+static void android_location_gnss_hal_GnssNative_inject_gnss_assistance(JNIEnv* env, jclass,
+                                                                        jobject gnssAssistanceObj) {
+    if (gnssAssistanceIface == nullptr) {
+        ALOGE("%s: IGnssAssistance interface not available.", __func__);
+        return;
+    }
+    gnssAssistanceIface->injectGnssAssistance(env, gnssAssistanceObj);
+}
+
 static void android_location_GnssNetworkConnectivityHandler_agps_data_conn_open(
         JNIEnv* env, jobject /* obj */, jlong networkHandle, jstring apn, jint apnIpType) {
     if (apn == nullptr) {
@@ -937,6 +967,8 @@
         {"native_stop_nmea_message_collection", "()Z",
          reinterpret_cast<void*>(
                  android_location_gnss_hal_GnssNative_stop_nmea_message_collection)},
+        {"native_inject_gnss_assistance", "(Landroid/location/GnssAssistance;)V",
+         reinterpret_cast<void*>(android_location_gnss_hal_GnssNative_inject_gnss_assistance)},
 };
 
 static const JNINativeMethod sBatchingMethods[] = {
diff --git a/services/core/jni/com_android_server_sensor_SensorService.cpp b/services/core/jni/com_android_server_sensor_SensorService.cpp
index eb729de..0bee718 100644
--- a/services/core/jni/com_android_server_sensor_SensorService.cpp
+++ b/services/core/jni/com_android_server_sensor_SensorService.cpp
@@ -60,6 +60,8 @@
     void unregisterRuntimeSensor(jint handle);
     jboolean sendRuntimeSensorEvent(JNIEnv* env, jint handle, jint type, jlong timestamp,
                                     jfloatArray values);
+    jboolean sendRuntimeSensorAdditionalInfo(JNIEnv* env, jint handle, jint type, jint serial,
+                                             jlong timestamp, jfloatArray values);
 
 private:
     sp<SensorService> mService;
@@ -172,9 +174,9 @@
 
     sensors_event_t event{
             .version = sizeof(sensors_event_t),
-            .timestamp = timestamp,
             .sensor = handle,
             .type = type,
+            .timestamp = timestamp,
     };
 
     int valuesLength = env->GetArrayLength(values);
@@ -234,6 +236,42 @@
     return err == OK;
 }
 
+jboolean NativeSensorService::sendRuntimeSensorAdditionalInfo(JNIEnv* env, jint handle, jint type,
+                                                              jint serial, jlong timestamp,
+                                                              jfloatArray values) {
+    if (mService == nullptr) {
+        ALOGD("Dropping sendRuntimeSensorAdditionalInfo, sensor service not available.");
+        return false;
+    }
+
+    sensors_event_t event{
+            .version = sizeof(sensors_event_t),
+            .sensor = handle,
+            .type = SENSOR_TYPE_ADDITIONAL_INFO,
+            .timestamp = timestamp,
+            .additional_info =
+                    (additional_info_event_t){
+                            .type = type,
+                            .serial = serial,
+                    },
+    };
+
+    if (values != nullptr) {
+        int valuesLength = env->GetArrayLength(values);
+        if (valuesLength > 14) {
+            ALOGD("Dropping sendRuntimeSensorAdditionalInfo, number of values exceeds maximum.");
+            return false;
+        }
+        if (valuesLength > 0) {
+            jfloat* sensorValues = env->GetFloatArrayElements(values, nullptr);
+            memcpy(event.additional_info.data_float, sensorValues, valuesLength * sizeof(float));
+        }
+    }
+
+    status_t err = mService->sendRuntimeSensorEvent(event);
+    return err == OK;
+}
+
 NativeSensorService::ProximityActiveListenerDelegate::ProximityActiveListenerDelegate(
         JNIEnv* env, jobject listener)
       : mListener(env->NewGlobalRef(listener)) {}
@@ -326,6 +364,13 @@
     return service->sendRuntimeSensorEvent(env, handle, type, timestamp, values);
 }
 
+static jboolean sendRuntimeSensorAdditionalInfoNative(JNIEnv* env, jclass, jlong ptr, jint handle,
+                                                      jint type, jint serial, jlong timestamp,
+                                                      jfloatArray values) {
+    auto* service = reinterpret_cast<NativeSensorService*>(ptr);
+    return service->sendRuntimeSensorAdditionalInfo(env, handle, type, serial, timestamp, values);
+}
+
 static const JNINativeMethod methods[] = {
         {"startSensorServiceNative", "(L" PROXIMITY_ACTIVE_CLASS ";)J",
          reinterpret_cast<void*>(startSensorServiceNative)},
@@ -340,6 +385,8 @@
          reinterpret_cast<void*>(unregisterRuntimeSensorNative)},
         {"sendRuntimeSensorEventNative", "(JIIJ[F)Z",
          reinterpret_cast<void*>(sendRuntimeSensorEventNative)},
+        {"sendRuntimeSensorAdditionalInfoNative", "(JIIIJ[F)Z",
+         reinterpret_cast<void*>(sendRuntimeSensorAdditionalInfoNative)},
 };
 
 int register_android_server_sensor_SensorService(JavaVM* vm, JNIEnv* env) {
diff --git a/services/core/jni/gnss/Android.bp b/services/core/jni/gnss/Android.bp
index e72259f..562e82f 100644
--- a/services/core/jni/gnss/Android.bp
+++ b/services/core/jni/gnss/Android.bp
@@ -17,7 +17,6 @@
         "-Werror",
         "-Wno-unused-parameter",
         "-Wthread-safety",
-
         "-DEGL_EGLEXT_PROTOTYPES",
         "-DGL_GLEXT_PROTOTYPES",
     ],
@@ -41,6 +40,8 @@
         "GnssMeasurementCallback.cpp",
         "GnssNavigationMessage.cpp",
         "GnssNavigationMessageCallback.cpp",
+        "GnssAssistance.cpp",
+        "GnssAssistanceCallback.cpp",
         "GnssPsds.cpp",
         "GnssPsdsCallback.cpp",
         "GnssVisibilityControl.cpp",
@@ -61,7 +62,7 @@
         "libnativehelper",
         "libhardware_legacy",
         "libutils",
-        "android.hardware.gnss-V3-cpp",
+        "android.hardware.gnss-V5-cpp",
         "android.hardware.gnss@1.0",
         "android.hardware.gnss@1.1",
         "android.hardware.gnss@2.0",
diff --git a/services/core/jni/gnss/Gnss.cpp b/services/core/jni/gnss/Gnss.cpp
index da8928b5..a3fd9aa 100644
--- a/services/core/jni/gnss/Gnss.cpp
+++ b/services/core/jni/gnss/Gnss.cpp
@@ -765,4 +765,15 @@
     return nullptr;
 }
 
+std::unique_ptr<GnssAssistanceInterface> GnssHal::getGnssAssistanceInterface() {
+    if (gnssHalAidl != nullptr) {
+        sp<hardware::gnss::gnss_assistance::IGnssAssistanceInterface> gnssAssistance;
+        auto status = gnssHalAidl->getExtensionGnssAssistanceInterface(&gnssAssistance);
+        if (checkAidlStatus(status, "Unable to get a handle to GnssAssistance")) {
+            return std::make_unique<GnssAssistanceInterface>(gnssAssistance);
+        }
+    }
+    return nullptr;
+}
+
 } // namespace android::gnss
diff --git a/services/core/jni/gnss/Gnss.h b/services/core/jni/gnss/Gnss.h
index 458da8a..2b6b751 100644
--- a/services/core/jni/gnss/Gnss.h
+++ b/services/core/jni/gnss/Gnss.h
@@ -34,6 +34,7 @@
 #include "AGnss.h"
 #include "AGnssRil.h"
 #include "GnssAntennaInfo.h"
+#include "GnssAssistance.h"
 #include "GnssBatching.h"
 #include "GnssCallback.h"
 #include "GnssConfiguration.h"
@@ -115,6 +116,7 @@
     std::unique_ptr<GnssVisibilityControlInterface> getGnssVisibilityControlInterface();
     std::unique_ptr<GnssAntennaInfoInterface> getGnssAntennaInfoInterface();
     std::unique_ptr<GnssPsdsInterface> getGnssPsdsInterface();
+    std::unique_ptr<GnssAssistanceInterface> getGnssAssistanceInterface();
 
     sp<hardware::gnss::IGnssPowerIndication> getGnssPowerIndicationInterface();
     sp<hardware::gnss::V1_0::IGnssNi> getGnssNiInterface();
diff --git a/services/core/jni/gnss/GnssAssistance.cpp b/services/core/jni/gnss/GnssAssistance.cpp
new file mode 100644
index 0000000..fff396e
--- /dev/null
+++ b/services/core/jni/gnss/GnssAssistance.cpp
@@ -0,0 +1,2047 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// Define LOG_TAG before <log/log.h> to overwrite the default value.
+
+#define LOG_TAG "GnssAssistanceJni"
+
+#include "GnssAssistance.h"
+
+#include <utils/String16.h>
+
+#include "GnssAssistanceCallback.h"
+#include "Utils.h"
+
+namespace android::gnss {
+
+using GnssConstellationType = android::hardware::gnss::GnssConstellationType;
+using GnssCorrectionComponent = android::hardware::gnss::gnss_assistance::GnssCorrectionComponent;
+using GnssInterval =
+        android::hardware::gnss::gnss_assistance::GnssCorrectionComponent::GnssInterval;
+using GnssSatelliteAlmanac =
+        android::hardware::gnss::gnss_assistance::GnssAlmanac::GnssSatelliteAlmanac;
+using IonosphericCorrection = android::hardware::gnss::gnss_assistance::IonosphericCorrection;
+using PseudorangeCorrection =
+        android::hardware::gnss::gnss_assistance::GnssCorrectionComponent::PseudorangeCorrection;
+using GalileoSatelliteClockModel = android::hardware::gnss::gnss_assistance::
+        GalileoSatelliteEphemeris::GalileoSatelliteClockModel;
+using GalileoSvHealth =
+        android::hardware::gnss::gnss_assistance::GalileoSatelliteEphemeris::GalileoSvHealth;
+using GlonassSatelliteAlmanac =
+        android::hardware::gnss::gnss_assistance::GlonassAlmanac::GlonassSatelliteAlmanac;
+using GlonassSatelliteClockModel = android::hardware::gnss::gnss_assistance::
+        GlonassSatelliteEphemeris::GlonassSatelliteClockModel;
+using GlonassSatelliteOrbitModel = android::hardware::gnss::gnss_assistance::
+        GlonassSatelliteEphemeris::GlonassSatelliteOrbitModel;
+using GnssSignalType = hardware::gnss::GnssSignalType;
+using GnssConstellationType = hardware::gnss::GnssConstellationType;
+using BeidouB1CSatelliteOrbitType =
+        android::hardware::gnss::gnss_assistance::AuxiliaryInformation::BeidouB1CSatelliteOrbitType;
+using QzssSatelliteEphemeris = android::hardware::gnss::gnss_assistance::QzssSatelliteEphemeris;
+
+// Implementation of GnssAssistance (AIDL HAL)
+
+namespace {
+jmethodID method_gnssAssistanceGetGpsAssistance;
+jmethodID method_gnssAssistanceGetGlonassAssistance;
+jmethodID method_gnssAssistanceGetGalileoAssistance;
+jmethodID method_gnssAssistanceGetBeidouAssistance;
+jmethodID method_gnssAssistanceGetQzssAssistance;
+
+jmethodID method_listSize;
+jmethodID method_listGet;
+
+jmethodID method_gnssAlmanacGetIssueDateMillis;
+jmethodID method_gnssAlmanacGetIoda;
+jmethodID method_gnssAlmanacGetWeekNumber;
+jmethodID method_gnssAlmanacGetToaSeconds;
+jmethodID method_gnssAlmanacGetSatelliteAlmanacs;
+jmethodID method_gnssAlmanacIsCompleteAlmanacProvided;
+jmethodID method_satelliteAlmanacGetSvid;
+jmethodID method_satelliteAlmanacGetSvHealth;
+jmethodID method_satelliteAlmanacGetAf0;
+jmethodID method_satelliteAlmanacGetAf1;
+jmethodID method_satelliteAlmanacGetEccentricity;
+jmethodID method_satelliteAlmanacGetInclination;
+jmethodID method_satelliteAlmanacGetM0;
+jmethodID method_satelliteAlmanacGetOmega;
+jmethodID method_satelliteAlmanacGetOmega0;
+jmethodID method_satelliteAlmanacGetOmegaDot;
+jmethodID method_satelliteAlmanacGetRootA;
+
+jmethodID method_satelliteEphemerisTimeGetIode;
+jmethodID method_satelliteEphemerisTimeGetToeSeconds;
+jmethodID method_satelliteEphemerisTimeGetWeekNumber;
+
+jmethodID method_keplerianOrbitModelGetDeltaN;
+jmethodID method_keplerianOrbitModelGetEccentricity;
+jmethodID method_keplerianOrbitModelGetI0;
+jmethodID method_keplerianOrbitModelGetIDot;
+jmethodID method_keplerianOrbitModelGetM0;
+jmethodID method_keplerianOrbitModelGetOmega;
+jmethodID method_keplerianOrbitModelGetOmega0;
+jmethodID method_keplerianOrbitModelGetOmegaDot;
+jmethodID method_keplerianOrbitModelGetRootA;
+jmethodID method_keplerianOrbitModelGetSecondOrderHarmonicPerturbation;
+jmethodID method_secondOrderHarmonicPerturbationGetCic;
+jmethodID method_secondOrderHarmonicPerturbationGetCis;
+jmethodID method_secondOrderHarmonicPerturbationGetCrc;
+jmethodID method_secondOrderHarmonicPerturbationGetCrs;
+jmethodID method_secondOrderHarmonicPerturbationGetCuc;
+jmethodID method_secondOrderHarmonicPerturbationGetCus;
+
+jmethodID method_klobucharIonosphericModelGetAlpha0;
+jmethodID method_klobucharIonosphericModelGetAlpha1;
+jmethodID method_klobucharIonosphericModelGetAlpha2;
+jmethodID method_klobucharIonosphericModelGetAlpha3;
+jmethodID method_klobucharIonosphericModelGetBeta0;
+jmethodID method_klobucharIonosphericModelGetBeta1;
+jmethodID method_klobucharIonosphericModelGetBeta2;
+jmethodID method_klobucharIonosphericModelGetBeta3;
+
+jmethodID method_utcModelGetA0;
+jmethodID method_utcModelGetA1;
+jmethodID method_utcModelGetTimeOfWeek;
+jmethodID method_utcModelGetWeekNumber;
+
+jmethodID method_leapSecondsModelGetDayNumberLeapSecondsFuture;
+jmethodID method_leapSecondsModelGetLeapSeconds;
+jmethodID method_leapSecondsModelGetLeapSecondsFuture;
+jmethodID method_leapSecondsModelGetWeekNumberLeapSecondsFuture;
+
+jmethodID method_timeModelsGetTimeOfWeek;
+jmethodID method_timeModelsGetToGnss;
+jmethodID method_timeModelsGetWeekNumber;
+jmethodID method_timeModelsGetA0;
+jmethodID method_timeModelsGetA1;
+
+jmethodID method_realTimeIntegrityModelGetBadSvid;
+jmethodID method_realTimeIntegrityModelGetBadSignalTypes;
+jmethodID method_realTimeIntegrityModelGetStartDateSeconds;
+jmethodID method_realTimeIntegrityModelGetEndDateSeconds;
+jmethodID method_realTimeIntegrityModelGetPublishDateSeconds;
+jmethodID method_realTimeIntegrityModelGetAdvisoryNumber;
+jmethodID method_realTimeIntegrityModelGetAdvisoryType;
+
+jmethodID method_gnssSignalTypeGetConstellationType;
+jmethodID method_gnssSignalTypeGetCarrierFrequencyHz;
+jmethodID method_gnssSignalTypeGetCodeType;
+
+jmethodID method_auxiliaryInformationGetSvid;
+jmethodID method_auxiliaryInformationGetAvailableSignalTypes;
+jmethodID method_auxiliaryInformationGetFrequencyChannelNumber;
+jmethodID method_auxiliaryInformationGetSatType;
+
+jmethodID method_satelliteCorrectionGetSvid;
+jmethodID method_satelliteCorrectionGetIonosphericCorrections;
+jmethodID method_ionosphericCorrectionGetCarrierFrequencyHz;
+jmethodID method_ionosphericCorrectionGetIonosphericCorrection;
+jmethodID method_gnssCorrectionComponentGetPseudorangeCorrection;
+jmethodID method_gnssCorrectionComponentGetSourceKey;
+jmethodID method_gnssCorrectionComponentGetValidityInterval;
+jmethodID method_pseudorangeCorrectionGetCorrectionMeters;
+jmethodID method_pseudorangeCorrectionGetCorrectionUncertaintyMeters;
+jmethodID method_pseudorangeCorrectionGetCorrectionRateMetersPerSecond;
+jmethodID method_gnssIntervalGetStartMillisSinceGpsEpoch;
+jmethodID method_gnssIntervalGetEndMillisSinceGpsEpoch;
+
+jmethodID method_gpsAssistanceGetAlmanac;
+jmethodID method_gpsAssistanceGetIonosphericModel;
+jmethodID method_gpsAssistanceGetUtcModel;
+jmethodID method_gpsAssistanceGetLeapSecondsModel;
+jmethodID method_gpsAssistanceGetTimeModels;
+jmethodID method_gpsAssistanceGetSatelliteEphemeris;
+jmethodID method_gpsAssistanceGetRealTimeIntegrityModels;
+jmethodID method_gpsAssistanceGetSatelliteCorrections;
+jmethodID method_gpsSatelliteEphemerisGetSvid;
+jmethodID method_gpsSatelliteEphemerisGetGpsL2Params;
+jmethodID method_gpsSatelliteEphemerisGetSatelliteClockModel;
+jmethodID method_gpsSatelliteEphemerisGetSatelliteOrbitModel;
+jmethodID method_gpsSatelliteEphemerisGetSatelliteHealth;
+jmethodID method_gpsSatelliteEphemerisGetSatelliteEphemerisTime;
+jmethodID method_gpsL2ParamsGetL2Code;
+jmethodID method_gpsL2ParamsGetL2Flag;
+jmethodID method_gpsSatelliteClockModelGetAf0;
+jmethodID method_gpsSatelliteClockModelGetAf1;
+jmethodID method_gpsSatelliteClockModelGetAf2;
+jmethodID method_gpsSatelliteClockModelGetTgd;
+jmethodID method_gpsSatelliteClockModelGetIodc;
+jmethodID method_gpsSatelliteClockModelGetTimeOfClockSeconds;
+jmethodID method_gpsSatelliteHealthGetFitInt;
+jmethodID method_gpsSatelliteHealthGetSvAccur;
+jmethodID method_gpsSatelliteHealthGetSvHealth;
+
+jmethodID method_beidouAssistanceGetAlmanac;
+jmethodID method_beidouAssistanceGetIonosphericModel;
+jmethodID method_beidouAssistanceGetUtcModel;
+jmethodID method_beidouAssistanceGetLeapSecondsModel;
+jmethodID method_beidouAssistanceGetTimeModels;
+jmethodID method_beidouAssistanceGetSatelliteEphemeris;
+jmethodID method_beidouAssistanceGetSatelliteCorrections;
+jmethodID method_beidouAssistanceGetRealTimeIntegrityModels;
+jmethodID method_beidouSatelliteEphemerisGetSvid;
+jmethodID method_beidouSatelliteEphemerisGetSatelliteClockModel;
+jmethodID method_beidouSatelliteEphemerisGetSatelliteOrbitModel;
+jmethodID method_beidouSatelliteEphemerisGetSatelliteHealth;
+jmethodID method_beidouSatelliteEphemerisGetSatelliteEphemerisTime;
+jmethodID method_beidouSatelliteClockModelGetAf0;
+jmethodID method_beidouSatelliteClockModelGetAf1;
+jmethodID method_beidouSatelliteClockModelGetAf2;
+jmethodID method_beidouSatelliteClockModelGetAodc;
+jmethodID method_beidouSatelliteClockModelGetTgd1;
+jmethodID method_beidouSatelliteClockModelGetTgd2;
+jmethodID method_beidouSatelliteClockModelGetTimeOfClockSeconds;
+jmethodID method_beidouSatelliteHealthGetSatH1;
+jmethodID method_beidouSatelliteHealthGetSvAccur;
+jmethodID method_beidouSatelliteEphemerisTimeGetIode;
+jmethodID method_beidouSatelliteEphemerisTimeGetBeidouWeekNumber;
+jmethodID method_beidouSatelliteEphemerisTimeGetToeSeconds;
+
+jmethodID method_galileoAssistanceGetAlmanac;
+jmethodID method_galileoAssistanceGetIonosphericModel;
+jmethodID method_galileoAssistanceGetUtcModel;
+jmethodID method_galileoAssistanceGetLeapSecondsModel;
+jmethodID method_galileoAssistanceGetTimeModels;
+jmethodID method_galileoAssistanceGetSatelliteEphemeris;
+jmethodID method_galileoAssistanceGetSatelliteCorrections;
+jmethodID method_galileoAssistanceGetRealTimeIntegrityModels;
+jmethodID method_galileoSatelliteEphemerisGetSvid;
+jmethodID method_galileoSatelliteEphemerisGetSatelliteClockModels;
+jmethodID method_galileoSatelliteEphemerisGetSatelliteOrbitModel;
+jmethodID method_galileoSatelliteEphemerisGetSatelliteHealth;
+jmethodID method_galileoSatelliteEphemerisGetSatelliteEphemerisTime;
+jmethodID method_galileoSatelliteClockModelGetAf0;
+jmethodID method_galileoSatelliteClockModelGetAf1;
+jmethodID method_galileoSatelliteClockModelGetAf2;
+jmethodID method_galileoSatelliteClockModelGetBgdSeconds;
+jmethodID method_galileoSatelliteClockModelGetSatelliteClockType;
+jmethodID method_galileoSatelliteClockModelGetSisaMeters;
+jmethodID method_galileoSatelliteClockModelGetTimeOfClockSeconds;
+jmethodID method_galileoSvHealthGetDataValidityStatusE1b;
+jmethodID method_galileoSvHealthGetDataValidityStatusE5a;
+jmethodID method_galileoSvHealthGetDataValidityStatusE5b;
+jmethodID method_galileoSvHealthGetSignalHealthStatusE1b;
+jmethodID method_galileoSvHealthGetSignalHealthStatusE5a;
+jmethodID method_galileoSvHealthGetSignalHealthStatusE5b;
+jmethodID method_galileoIonosphericModelGetAi0;
+jmethodID method_galileoIonosphericModelGetAi1;
+jmethodID method_galileoIonosphericModelGetAi2;
+
+jmethodID method_glonassAssistanceGetAlmanac;
+jmethodID method_glonassAssistanceGetUtcModel;
+jmethodID method_glonassAssistanceGetTimeModels;
+jmethodID method_glonassAssistanceGetSatelliteEphemeris;
+jmethodID method_glonassAssistanceGetSatelliteCorrections;
+jmethodID method_glonassAlmanacGetIssueDateMillis;
+jmethodID method_glonassAlmanacGetSatelliteAlmanacs;
+jmethodID method_glonassSatelliteAlmanacGetDeltaI;
+jmethodID method_glonassSatelliteAlmanacGetDeltaT;
+jmethodID method_glonassSatelliteAlmanacGetDeltaTDot;
+jmethodID method_glonassSatelliteAlmanacGetEccentricity;
+jmethodID method_glonassSatelliteAlmanacGetFrequencyChannelNumber;
+jmethodID method_glonassSatelliteAlmanacGetLambda;
+jmethodID method_glonassSatelliteAlmanacGetOmega;
+jmethodID method_glonassSatelliteAlmanacGetSlotNumber;
+jmethodID method_glonassSatelliteAlmanacGetHealthState;
+jmethodID method_glonassSatelliteAlmanacGetTLambda;
+jmethodID method_glonassSatelliteAlmanacGetTau;
+jmethodID method_glonassSatelliteAlmanacGetIsGlonassM;
+jmethodID method_glonassSatelliteAlmanacGetCalendarDayNumber;
+jmethodID method_glonassSatelliteEphemerisGetAgeInDays;
+jmethodID method_glonassSatelliteEphemerisGetSatelliteClockModel;
+jmethodID method_glonassSatelliteEphemerisGetSatelliteOrbitModel;
+jmethodID method_glonassSatelliteEphemerisGetHealthState;
+jmethodID method_glonassSatelliteEphemerisGetSlotNumber;
+jmethodID method_glonassSatelliteEphemerisGetFrameTimeSeconds;
+jmethodID method_glonassSatelliteEphemerisGetUpdateIntervalMinutes;
+jmethodID method_glonassSatelliteEphemerisGetIsGlonassM;
+jmethodID method_glonassSatelliteEphemerisGetIsUpdateIntervalOdd;
+
+jmethodID method_glonassSatelliteOrbitModelGetX;
+jmethodID method_glonassSatelliteOrbitModelGetY;
+jmethodID method_glonassSatelliteOrbitModelGetZ;
+jmethodID method_glonassSatelliteOrbitModelGetXAccel;
+jmethodID method_glonassSatelliteOrbitModelGetYAccel;
+jmethodID method_glonassSatelliteOrbitModelGetZAccel;
+jmethodID method_glonassSatelliteOrbitModelGetXDot;
+jmethodID method_glonassSatelliteOrbitModelGetYDot;
+jmethodID method_glonassSatelliteOrbitModelGetZDot;
+jmethodID method_glonassSatelliteClockModelGetClockBias;
+jmethodID method_glonassSatelliteClockModelGetFrequencyBias;
+jmethodID method_glonassSatelliteClockModelGetFrequencyChannelNumber;
+jmethodID method_glonassSatelliteClockModelGetTimeOfClockSeconds;
+
+jmethodID method_qzssAssistanceGetAlmanac;
+jmethodID method_qzssAssistanceGetIonosphericModel;
+jmethodID method_qzssAssistanceGetUtcModel;
+jmethodID method_qzssAssistanceGetLeapSecondsModel;
+jmethodID method_qzssAssistanceGetTimeModels;
+jmethodID method_qzssAssistanceGetSatelliteEphemeris;
+jmethodID method_qzssAssistanceGetSatelliteCorrections;
+jmethodID method_qzssAssistanceGetRealTimeIntegrityModels;
+jmethodID method_qzssSatelliteEphemerisGetSvid;
+jmethodID method_qzssSatelliteEphemerisGetGpsL2Params;
+jmethodID method_qzssSatelliteEphemerisGetSatelliteClockModel;
+jmethodID method_qzssSatelliteEphemerisGetSatelliteOrbitModel;
+jmethodID method_qzssSatelliteEphemerisGetSatelliteHealth;
+jmethodID method_qzssSatelliteEphemerisGetSatelliteEphemerisTime;
+jmethodID method_qzssSatelliteClockModelGetAf0;
+jmethodID method_qzssSatelliteClockModelGetAf1;
+jmethodID method_qzssSatelliteClockModelGetAf2;
+jmethodID method_qzssSatelliteClockModelGetAodc;
+jmethodID method_qzssSatelliteClockModelGetTgd1;
+jmethodID method_qzssSatelliteClockModelGetTgd2;
+jmethodID method_qzssSatelliteClockModelGetTimeOfClockSeconds;
+} // namespace
+
+void GnssAssistance_class_init_once(JNIEnv* env, jclass clazz) {
+    // Get the methods of GnssAssistance class.
+    jclass gnssAssistanceClass = env->FindClass("android/location/GnssAssistance");
+
+    method_gnssAssistanceGetGpsAssistance =
+            env->GetMethodID(gnssAssistanceClass, "getGpsAssistance",
+                             "()Landroid/location/GpsAssistance;");
+    method_gnssAssistanceGetGlonassAssistance =
+            env->GetMethodID(gnssAssistanceClass, "getGlonassAssistance",
+                             "()Landroid/location/GlonassAssistance;");
+    method_gnssAssistanceGetGalileoAssistance =
+            env->GetMethodID(gnssAssistanceClass, "getGalileoAssistance",
+                             "()Landroid/location/GalileoAssistance;");
+    method_gnssAssistanceGetBeidouAssistance =
+            env->GetMethodID(gnssAssistanceClass, "getBeidouAssistance",
+                             "()Landroid/location/BeidouAssistance;");
+    method_gnssAssistanceGetQzssAssistance =
+            env->GetMethodID(gnssAssistanceClass, "getQzssAssistance",
+                             "()Landroid/location/QzssAssistance;");
+
+    // Get the methods of List class.
+    jclass listClass = env->FindClass("java/util/List");
+
+    method_listSize = env->GetMethodID(listClass, "size", "()I");
+    method_listGet = env->GetMethodID(listClass, "get", "(I)Ljava/lang/Object;");
+
+    // Get the methods of GnssAlmanac class.
+    jclass gnssAlmanacClass = env->FindClass("android/location/GnssAlmanac");
+
+    method_gnssAlmanacGetIssueDateMillis =
+            env->GetMethodID(gnssAlmanacClass, "getIssueDateMillis", "()J");
+    method_gnssAlmanacGetIoda = env->GetMethodID(gnssAlmanacClass, "getIoda", "()I");
+    method_gnssAlmanacGetWeekNumber = env->GetMethodID(gnssAlmanacClass, "getWeekNumber", "()I");
+    method_gnssAlmanacGetToaSeconds = env->GetMethodID(gnssAlmanacClass, "getToaSeconds", "()I");
+    method_gnssAlmanacGetSatelliteAlmanacs =
+            env->GetMethodID(gnssAlmanacClass, "getGnssSatelliteAlmanacs", "()Ljava/util/List;");
+    method_gnssAlmanacIsCompleteAlmanacProvided =
+            env->GetMethodID(gnssAlmanacClass, "isCompleteAlmanacProvided", "()Z");
+
+    // Get the methods of SatelliteAlmanac class.
+    jclass satelliteAlmanacClass =
+            env->FindClass("android/location/GnssAlmanac$GnssSatelliteAlmanac");
+
+    method_satelliteAlmanacGetSvid = env->GetMethodID(satelliteAlmanacClass, "getSvid", "()I");
+    method_satelliteAlmanacGetSvHealth =
+            env->GetMethodID(satelliteAlmanacClass, "getSvHealth", "()I");
+    method_satelliteAlmanacGetAf0 = env->GetMethodID(satelliteAlmanacClass, "getAf0", "()D");
+    method_satelliteAlmanacGetAf1 = env->GetMethodID(satelliteAlmanacClass, "getAf1", "()D");
+    method_satelliteAlmanacGetEccentricity =
+            env->GetMethodID(satelliteAlmanacClass, "getEccentricity", "()D");
+    method_satelliteAlmanacGetInclination =
+            env->GetMethodID(satelliteAlmanacClass, "getInclination", "()D");
+    method_satelliteAlmanacGetM0 = env->GetMethodID(satelliteAlmanacClass, "getM0", "()D");
+    method_satelliteAlmanacGetOmega = env->GetMethodID(satelliteAlmanacClass, "getOmega", "()D");
+    method_satelliteAlmanacGetOmega0 = env->GetMethodID(satelliteAlmanacClass, "getOmega0", "()D");
+    method_satelliteAlmanacGetOmegaDot =
+            env->GetMethodID(satelliteAlmanacClass, "getOmegaDot", "()D");
+    method_satelliteAlmanacGetRootA = env->GetMethodID(satelliteAlmanacClass, "getRootA", "()D");
+
+    // Get the mothods of SatelliteEphemerisTime class.
+    jclass satelliteEphemerisTimeClass = env->FindClass("android/location/SatelliteEphemerisTime");
+
+    method_satelliteEphemerisTimeGetIode =
+            env->GetMethodID(satelliteEphemerisTimeClass, "getIode", "()I");
+    method_satelliteEphemerisTimeGetToeSeconds =
+            env->GetMethodID(satelliteEphemerisTimeClass, "getToeSeconds", "()I");
+    method_satelliteEphemerisTimeGetWeekNumber =
+            env->GetMethodID(satelliteEphemerisTimeClass, "getWeekNumber", "()I");
+
+    // Get the mothods of KeplerianOrbitModel class.
+    jclass keplerianOrbitModelClass = env->FindClass("android/location/KeplerianOrbitModel");
+
+    method_keplerianOrbitModelGetDeltaN =
+            env->GetMethodID(keplerianOrbitModelClass, "getDeltaN", "()D");
+    method_keplerianOrbitModelGetEccentricity =
+            env->GetMethodID(keplerianOrbitModelClass, "getEccentricity", "()D");
+    method_keplerianOrbitModelGetI0 = env->GetMethodID(keplerianOrbitModelClass, "getI0", "()D");
+    method_keplerianOrbitModelGetIDot =
+            env->GetMethodID(keplerianOrbitModelClass, "getIDot", "()D");
+    method_keplerianOrbitModelGetM0 = env->GetMethodID(keplerianOrbitModelClass, "getM0", "()D");
+    method_keplerianOrbitModelGetOmega =
+            env->GetMethodID(keplerianOrbitModelClass, "getOmega", "()D");
+    method_keplerianOrbitModelGetOmega0 =
+            env->GetMethodID(keplerianOrbitModelClass, "getOmega0", "()D");
+    method_keplerianOrbitModelGetOmegaDot =
+            env->GetMethodID(keplerianOrbitModelClass, "getOmegaDot", "()D");
+    method_keplerianOrbitModelGetRootA =
+            env->GetMethodID(keplerianOrbitModelClass, "getRootA", "()D");
+    method_keplerianOrbitModelGetSecondOrderHarmonicPerturbation =
+            env->GetMethodID(keplerianOrbitModelClass, "getSecondOrderHarmonicPerturbation",
+                             "()Landroid/location/"
+                             "KeplerianOrbitModel$SecondOrderHarmonicPerturbation;");
+
+    // Get the methods of SecondOrderHarmonicPerturbation class.
+    jclass secondOrderHarmonicPerturbationClass =
+            env->FindClass("android/location/KeplerianOrbitModel$SecondOrderHarmonicPerturbation");
+
+    method_secondOrderHarmonicPerturbationGetCic =
+            env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCic", "()D");
+    method_secondOrderHarmonicPerturbationGetCis =
+            env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCis", "()D");
+    method_secondOrderHarmonicPerturbationGetCrc =
+            env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCrc", "()D");
+    method_secondOrderHarmonicPerturbationGetCrs =
+            env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCrs", "()D");
+    method_secondOrderHarmonicPerturbationGetCuc =
+            env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCuc", "()D");
+    method_secondOrderHarmonicPerturbationGetCus =
+            env->GetMethodID(secondOrderHarmonicPerturbationClass, "getCus", "()D");
+
+    // Get the methods of KlobucharIonosphericModel class.
+    jclass klobucharIonosphericModelClass =
+            env->FindClass("android/location/KlobucharIonosphericModel");
+
+    method_klobucharIonosphericModelGetAlpha0 =
+            env->GetMethodID(klobucharIonosphericModelClass, "getAlpha0", "()D");
+    method_klobucharIonosphericModelGetAlpha1 =
+            env->GetMethodID(klobucharIonosphericModelClass, "getAlpha1", "()D");
+    method_klobucharIonosphericModelGetAlpha2 =
+            env->GetMethodID(klobucharIonosphericModelClass, "getAlpha2", "()D");
+    method_klobucharIonosphericModelGetAlpha3 =
+            env->GetMethodID(klobucharIonosphericModelClass, "getAlpha3", "()D");
+    method_klobucharIonosphericModelGetBeta0 =
+            env->GetMethodID(klobucharIonosphericModelClass, "getBeta0", "()D");
+    method_klobucharIonosphericModelGetBeta1 =
+            env->GetMethodID(klobucharIonosphericModelClass, "getBeta1", "()D");
+    method_klobucharIonosphericModelGetBeta2 =
+            env->GetMethodID(klobucharIonosphericModelClass, "getBeta2", "()D");
+    method_klobucharIonosphericModelGetBeta3 =
+            env->GetMethodID(klobucharIonosphericModelClass, "getBeta3", "()D");
+
+    // Get the methods of UtcModel class.
+    jclass utcModelClass = env->FindClass("android/location/UtcModel");
+
+    method_utcModelGetA0 = env->GetMethodID(utcModelClass, "getA0", "()D");
+    method_utcModelGetA1 = env->GetMethodID(utcModelClass, "getA1", "()D");
+    method_utcModelGetTimeOfWeek = env->GetMethodID(utcModelClass, "getTimeOfWeek", "()I");
+    method_utcModelGetWeekNumber = env->GetMethodID(utcModelClass, "getWeekNumber", "()I");
+
+    // Get the methods of LeapSecondsModel class.
+    jclass leapSecondsModelClass = env->FindClass("android/location/LeapSecondsModel");
+
+    method_leapSecondsModelGetDayNumberLeapSecondsFuture =
+            env->GetMethodID(leapSecondsModelClass, "getDayNumberLeapSecondsFuture", "()I");
+    method_leapSecondsModelGetLeapSeconds =
+            env->GetMethodID(leapSecondsModelClass, "getLeapSeconds", "()I");
+    method_leapSecondsModelGetLeapSecondsFuture =
+            env->GetMethodID(leapSecondsModelClass, "getLeapSecondsFuture", "()I");
+    method_leapSecondsModelGetWeekNumberLeapSecondsFuture =
+            env->GetMethodID(leapSecondsModelClass, "getWeekNumberLeapSecondsFuture", "()I");
+
+    // Get the methods of TimeModel class.
+    jclass timeModelsClass = env->FindClass("android/location/TimeModel");
+
+    method_timeModelsGetTimeOfWeek = env->GetMethodID(timeModelsClass, "getTimeOfWeek", "()I");
+    method_timeModelsGetToGnss = env->GetMethodID(timeModelsClass, "getToGnss", "()I");
+    method_timeModelsGetWeekNumber = env->GetMethodID(timeModelsClass, "getWeekNumber", "()I");
+    method_timeModelsGetA0 = env->GetMethodID(timeModelsClass, "getA0", "()D");
+    method_timeModelsGetA1 = env->GetMethodID(timeModelsClass, "getA1", "()D");
+
+    // Get the methods of AuxiliaryInformation class.
+    jclass auxiliaryInformationClass = env->FindClass("android/location/AuxiliaryInformation");
+
+    method_auxiliaryInformationGetSvid =
+            env->GetMethodID(auxiliaryInformationClass, "getSvid", "()I");
+    method_auxiliaryInformationGetAvailableSignalTypes =
+            env->GetMethodID(auxiliaryInformationClass, "getAvailableSignalTypes",
+                             "()Ljava/util/List;");
+    method_auxiliaryInformationGetFrequencyChannelNumber =
+            env->GetMethodID(auxiliaryInformationClass, "getFrequencyChannelNumber", "()I");
+    method_auxiliaryInformationGetSatType =
+            env->GetMethodID(auxiliaryInformationClass, "getSatType", "()I");
+
+    // Get the methods of RealTimeIntegrityModel
+    jclass realTimeIntegrityModelClass = env->FindClass("android/location/RealTimeIntegrityModel");
+
+    method_realTimeIntegrityModelGetBadSvid =
+            env->GetMethodID(realTimeIntegrityModelClass, "getBadSvid", "()I");
+    method_realTimeIntegrityModelGetBadSignalTypes =
+            env->GetMethodID(realTimeIntegrityModelClass, "getBadSignalTypes",
+                             "()Ljava/util/List;");
+    method_realTimeIntegrityModelGetStartDateSeconds =
+            env->GetMethodID(realTimeIntegrityModelClass, "getStartDateSeconds", "()J");
+    method_realTimeIntegrityModelGetEndDateSeconds =
+            env->GetMethodID(realTimeIntegrityModelClass, "getEndDateSeconds", "()J");
+    method_realTimeIntegrityModelGetPublishDateSeconds =
+            env->GetMethodID(realTimeIntegrityModelClass, "getPublishDateSeconds", "()J");
+    method_realTimeIntegrityModelGetAdvisoryNumber =
+            env->GetMethodID(realTimeIntegrityModelClass, "getAdvisoryNumber",
+                             "()Ljava/lang/String;");
+    method_realTimeIntegrityModelGetAdvisoryType =
+            env->GetMethodID(realTimeIntegrityModelClass, "getAdvisoryType",
+                             "()Ljava/lang/String;");
+
+    // Get the methods of GnssSignalType class.
+    jclass gnssSignalTypeClass = env->FindClass("android/location/GnssSignalType");
+
+    method_gnssSignalTypeGetConstellationType =
+            env->GetMethodID(gnssSignalTypeClass, "getConstellationType", "()I");
+    method_gnssSignalTypeGetCarrierFrequencyHz =
+            env->GetMethodID(gnssSignalTypeClass, "getCarrierFrequencyHz", "()D");
+    method_gnssSignalTypeGetCodeType =
+            env->GetMethodID(gnssSignalTypeClass, "getCodeType", "()Ljava/lang/String;");
+
+    // Get the methods of SatelliteCorrection class.
+    jclass satelliteCorrectionClass =
+            env->FindClass("android/location/GnssAssistance$GnssSatelliteCorrections");
+
+    method_satelliteCorrectionGetSvid =
+            env->GetMethodID(satelliteCorrectionClass, "getSvid", "()I");
+    method_satelliteCorrectionGetIonosphericCorrections =
+            env->GetMethodID(satelliteCorrectionClass, "getIonosphericCorrections",
+                             "()Ljava/util/List;");
+
+    // Get the methods of IonosphericCorrection class.
+    jclass ionosphericCorrectionClass = env->FindClass("android/location/IonosphericCorrection");
+
+    method_ionosphericCorrectionGetCarrierFrequencyHz =
+            env->GetMethodID(ionosphericCorrectionClass, "getCarrierFrequencyHz", "()J");
+    method_ionosphericCorrectionGetIonosphericCorrection =
+            env->GetMethodID(ionosphericCorrectionClass, "getIonosphericCorrection",
+                             "()Landroid/location/GnssCorrectionComponent;");
+
+    // Get the methods of GnssCorrectionComponent class.
+    jclass gnssCorrectionComponentClass =
+            env->FindClass("android/location/GnssCorrectionComponent");
+
+    method_gnssCorrectionComponentGetPseudorangeCorrection =
+            env->GetMethodID(gnssCorrectionComponentClass, "getPseudorangeCorrection",
+                             "()Landroid/location/GnssCorrectionComponent$PseudorangeCorrection;");
+    method_gnssCorrectionComponentGetSourceKey =
+            env->GetMethodID(gnssCorrectionComponentClass, "getSourceKey", "()Ljava/lang/String;");
+    method_gnssCorrectionComponentGetValidityInterval =
+            env->GetMethodID(gnssCorrectionComponentClass, "getValidityInterval",
+                             "()Landroid/location/GnssCorrectionComponent$GnssInterval;");
+
+    // Get the methods of PseudorangeCorrection class.
+    jclass pseudorangeCorrectionClass =
+            env->FindClass("android/location/GnssCorrectionComponent$PseudorangeCorrection");
+
+    method_pseudorangeCorrectionGetCorrectionMeters =
+            env->GetMethodID(pseudorangeCorrectionClass, "getCorrectionMeters", "()D");
+    method_pseudorangeCorrectionGetCorrectionRateMetersPerSecond =
+            env->GetMethodID(pseudorangeCorrectionClass, "getCorrectionRateMetersPerSecond", "()D");
+    method_pseudorangeCorrectionGetCorrectionUncertaintyMeters =
+            env->GetMethodID(pseudorangeCorrectionClass, "getCorrectionUncertaintyMeters", "()D");
+
+    // Get the methods of GnssInterval class.
+    jclass gnssIntervalClass =
+            env->FindClass("android/location/GnssCorrectionComponent$GnssInterval");
+
+    method_gnssIntervalGetStartMillisSinceGpsEpoch =
+            env->GetMethodID(gnssIntervalClass, "getStartMillisSinceGpsEpoch", "()J");
+    method_gnssIntervalGetEndMillisSinceGpsEpoch =
+            env->GetMethodID(gnssIntervalClass, "getEndMillisSinceGpsEpoch", "()J");
+
+    // Get the methods of GpsAssistance class.
+    jclass gpsAssistanceClass = env->FindClass("android/location/GpsAssistance");
+
+    method_gpsAssistanceGetAlmanac =
+            env->GetMethodID(gpsAssistanceClass, "getAlmanac", "()Landroid/location/GnssAlmanac;");
+    method_gpsAssistanceGetIonosphericModel =
+            env->GetMethodID(gpsAssistanceClass, "getIonosphericModel",
+                             "()Landroid/location/KlobucharIonosphericModel;");
+    method_gpsAssistanceGetUtcModel =
+            env->GetMethodID(gpsAssistanceClass, "getUtcModel", "()Landroid/location/UtcModel;");
+    method_gpsAssistanceGetLeapSecondsModel =
+            env->GetMethodID(gpsAssistanceClass, "getLeapSecondsModel",
+                             "()Landroid/location/LeapSecondsModel;");
+    method_gpsAssistanceGetTimeModels =
+            env->GetMethodID(gpsAssistanceClass, "getTimeModels", "()Ljava/util/List;");
+    method_gpsAssistanceGetSatelliteEphemeris =
+            env->GetMethodID(gpsAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;");
+    method_gpsAssistanceGetRealTimeIntegrityModels =
+            env->GetMethodID(gpsAssistanceClass, "getRealTimeIntegrityModels",
+                             "()Ljava/util/List;");
+    method_gpsAssistanceGetSatelliteCorrections =
+            env->GetMethodID(gpsAssistanceClass, "getSatelliteCorrections", "()Ljava/util/List;");
+
+    // Get the methods of GpsSatelliteEphemeris class.
+    jclass gpsSatelliteEphemerisClass = env->FindClass("android/location/GpsSatelliteEphemeris");
+
+    method_gpsSatelliteEphemerisGetSvid =
+            env->GetMethodID(gpsSatelliteEphemerisClass, "getSvid", "()I");
+    method_gpsSatelliteEphemerisGetGpsL2Params =
+            env->GetMethodID(gpsSatelliteEphemerisClass, "getGpsL2Params",
+                             "()Landroid/location/GpsSatelliteEphemeris$GpsL2Params;");
+    method_gpsSatelliteEphemerisGetSatelliteClockModel =
+            env->GetMethodID(gpsSatelliteEphemerisClass, "getSatelliteClockModel",
+                             "()Landroid/location/GpsSatelliteEphemeris$GpsSatelliteClockModel;");
+    method_gpsSatelliteEphemerisGetSatelliteOrbitModel =
+            env->GetMethodID(gpsSatelliteEphemerisClass, "getSatelliteOrbitModel",
+                             "()Landroid/location/KeplerianOrbitModel;");
+    method_gpsSatelliteEphemerisGetSatelliteHealth =
+            env->GetMethodID(gpsSatelliteEphemerisClass, "getSatelliteHealth",
+                             "()Landroid/location/GpsSatelliteEphemeris$GpsSatelliteHealth;");
+    method_gpsSatelliteEphemerisGetSatelliteEphemerisTime =
+            env->GetMethodID(gpsSatelliteEphemerisClass, "getSatelliteEphemerisTime",
+                             "()Landroid/location/SatelliteEphemerisTime;");
+
+    // Get the methods of GpsL2Params class.
+    jclass gpsL2ParamsClass = env->FindClass("android/location/GpsSatelliteEphemeris$GpsL2Params");
+    method_gpsL2ParamsGetL2Code = env->GetMethodID(gpsL2ParamsClass, "getL2Code", "()I");
+    method_gpsL2ParamsGetL2Flag = env->GetMethodID(gpsL2ParamsClass, "getL2Flag", "()I");
+
+    // Get the methods of GpsSatelliteClockModel class.
+    jclass gpsSatelliteClockModelClass =
+            env->FindClass("android/location/GpsSatelliteEphemeris$GpsSatelliteClockModel");
+    method_gpsSatelliteClockModelGetAf0 =
+            env->GetMethodID(gpsSatelliteClockModelClass, "getAf0", "()D");
+    method_gpsSatelliteClockModelGetAf1 =
+            env->GetMethodID(gpsSatelliteClockModelClass, "getAf1", "()D");
+    method_gpsSatelliteClockModelGetAf2 =
+            env->GetMethodID(gpsSatelliteClockModelClass, "getAf2", "()D");
+    method_gpsSatelliteClockModelGetTgd =
+            env->GetMethodID(gpsSatelliteClockModelClass, "getTgd", "()D");
+    method_gpsSatelliteClockModelGetIodc =
+            env->GetMethodID(gpsSatelliteClockModelClass, "getIodc", "()I");
+    method_gpsSatelliteClockModelGetTimeOfClockSeconds =
+            env->GetMethodID(gpsSatelliteClockModelClass, "getTimeOfClockSeconds", "()J");
+
+    // Get the methods of GpsSatelliteHealth class.
+    jclass gpsSatelliteHealthClass =
+            env->FindClass("android/location/GpsSatelliteEphemeris$GpsSatelliteHealth");
+    method_gpsSatelliteHealthGetFitInt =
+            env->GetMethodID(gpsSatelliteHealthClass, "getFitInt", "()D");
+    method_gpsSatelliteHealthGetSvAccur =
+            env->GetMethodID(gpsSatelliteHealthClass, "getSvAccur", "()D");
+    method_gpsSatelliteHealthGetSvHealth =
+            env->GetMethodID(gpsSatelliteHealthClass, "getSvHealth", "()I");
+
+    // Get the methods of BeidouAssistance class.
+    jclass beidouAssistanceClass = env->FindClass("android/location/BeidouAssistance");
+    method_beidouAssistanceGetAlmanac = env->GetMethodID(beidouAssistanceClass, "getAlmanac",
+                                                         "()Landroid/location/GnssAlmanac;");
+    method_beidouAssistanceGetIonosphericModel =
+            env->GetMethodID(beidouAssistanceClass, "getIonosphericModel",
+                             "()Landroid/location/KlobucharIonosphericModel;");
+    method_beidouAssistanceGetUtcModel =
+            env->GetMethodID(beidouAssistanceClass, "getUtcModel", "()Landroid/location/UtcModel;");
+    method_beidouAssistanceGetLeapSecondsModel =
+            env->GetMethodID(beidouAssistanceClass, "getLeapSecondsModel",
+                             "()Landroid/location/LeapSecondsModel;");
+    method_beidouAssistanceGetTimeModels =
+            env->GetMethodID(beidouAssistanceClass, "getTimeModels", "()Ljava/util/List;");
+    method_beidouAssistanceGetSatelliteEphemeris =
+            env->GetMethodID(beidouAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;");
+    method_beidouAssistanceGetSatelliteCorrections =
+            env->GetMethodID(beidouAssistanceClass, "getSatelliteCorrections",
+                             "()Ljava/util/List;");
+    method_beidouAssistanceGetRealTimeIntegrityModels =
+            env->GetMethodID(beidouAssistanceClass, "getRealTimeIntegrityModels",
+                             "()Ljava/util/List;");
+
+    // Get the methods of BeidouSatelliteEphemeris class.
+    jclass beidouSatelliteEphemerisClass =
+            env->FindClass("android/location/BeidouSatelliteEphemeris");
+    method_beidouSatelliteEphemerisGetSvid =
+            env->GetMethodID(beidouSatelliteEphemerisClass, "getSvid", "()I");
+    method_beidouSatelliteEphemerisGetSatelliteClockModel =
+            env->GetMethodID(beidouSatelliteEphemerisClass, "getSatelliteClockModel",
+                             "()Landroid/location/"
+                             "BeidouSatelliteEphemeris$BeidouSatelliteClockModel;");
+    method_beidouSatelliteEphemerisGetSatelliteOrbitModel =
+            env->GetMethodID(beidouSatelliteEphemerisClass, "getSatelliteOrbitModel",
+                             "()Landroid/location/KeplerianOrbitModel;");
+    method_beidouSatelliteEphemerisGetSatelliteHealth =
+            env->GetMethodID(beidouSatelliteEphemerisClass, "getSatelliteHealth",
+                             "()Landroid/location/BeidouSatelliteEphemeris$BeidouSatelliteHealth;");
+    method_beidouSatelliteEphemerisGetSatelliteEphemerisTime =
+            env->GetMethodID(beidouSatelliteEphemerisClass, "getSatelliteEphemerisTime",
+                             "()Landroid/location/"
+                             "BeidouSatelliteEphemeris$BeidouSatelliteEphemerisTime;");
+
+    // Get the methods of BeidouSatelliteClockModel
+    jclass beidouSatelliteClockModelClass =
+            env->FindClass("android/location/BeidouSatelliteEphemeris$BeidouSatelliteClockModel");
+    method_beidouSatelliteClockModelGetAf0 =
+            env->GetMethodID(beidouSatelliteClockModelClass, "getAf0", "()D");
+    method_beidouSatelliteClockModelGetAf1 =
+            env->GetMethodID(beidouSatelliteClockModelClass, "getAf1", "()D");
+    method_beidouSatelliteClockModelGetAf2 =
+            env->GetMethodID(beidouSatelliteClockModelClass, "getAf2", "()D");
+    method_beidouSatelliteClockModelGetAodc =
+            env->GetMethodID(beidouSatelliteClockModelClass, "getAodc", "()I");
+    method_beidouSatelliteClockModelGetTgd1 =
+            env->GetMethodID(beidouSatelliteClockModelClass, "getTgd1", "()D");
+    method_beidouSatelliteClockModelGetTgd2 =
+            env->GetMethodID(beidouSatelliteClockModelClass, "getTgd2", "()D");
+    method_beidouSatelliteClockModelGetTimeOfClockSeconds =
+            env->GetMethodID(beidouSatelliteClockModelClass, "getTimeOfClockSeconds", "()J");
+
+    // Get the methods of BeidouSatelliteHealth
+    jclass beidouSatelliteHealthClass =
+            env->FindClass("android/location/BeidouSatelliteEphemeris$BeidouSatelliteHealth");
+    method_beidouSatelliteHealthGetSatH1 =
+            env->GetMethodID(beidouSatelliteHealthClass, "getSatH1", "()I");
+    method_beidouSatelliteHealthGetSvAccur =
+            env->GetMethodID(beidouSatelliteHealthClass, "getSvAccur", "()D");
+
+    // Get the methods of BeidouSatelliteEphemerisTime
+    jclass beidouSatelliteEphemerisTimeClass = env->FindClass(
+            "android/location/BeidouSatelliteEphemeris$BeidouSatelliteEphemerisTime");
+    method_beidouSatelliteEphemerisTimeGetIode =
+            env->GetMethodID(beidouSatelliteEphemerisTimeClass, "getIode", "()I");
+    method_beidouSatelliteEphemerisTimeGetBeidouWeekNumber =
+            env->GetMethodID(beidouSatelliteEphemerisTimeClass, "getBeidouWeekNumber", "()I");
+    method_beidouSatelliteEphemerisTimeGetToeSeconds =
+            env->GetMethodID(beidouSatelliteEphemerisTimeClass, "getToeSeconds", "()I");
+
+    // Get the methods of GalileoAssistance class.
+    jclass galileoAssistanceClass = env->FindClass("android/location/GalileoAssistance");
+    method_galileoAssistanceGetAlmanac = env->GetMethodID(galileoAssistanceClass, "getAlmanac",
+                                                          "()Landroid/location/GnssAlmanac;");
+    method_galileoAssistanceGetIonosphericModel =
+            env->GetMethodID(galileoAssistanceClass, "getIonosphericModel",
+                             "()Landroid/location/KlobucharIonosphericModel;");
+    method_galileoAssistanceGetUtcModel = env->GetMethodID(galileoAssistanceClass, "getUtcModel",
+                                                           "()Landroid/location/UtcModel;");
+    method_galileoAssistanceGetLeapSecondsModel =
+            env->GetMethodID(galileoAssistanceClass, "getLeapSecondsModel",
+                             "()Landroid/location/LeapSecondsModel;");
+    method_galileoAssistanceGetTimeModels =
+            env->GetMethodID(galileoAssistanceClass, "getTimeModels", "()Ljava/util/List;");
+    method_galileoAssistanceGetSatelliteEphemeris =
+            env->GetMethodID(galileoAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;");
+    method_galileoAssistanceGetSatelliteCorrections =
+            env->GetMethodID(galileoAssistanceClass, "getSatelliteCorrections",
+                             "()Ljava/util/List;");
+    method_galileoAssistanceGetRealTimeIntegrityModels =
+            env->GetMethodID(galileoAssistanceClass, "getRealTimeIntegrityModels",
+                             "()Ljava/util/List;");
+
+    // Get the methods of GalileoSatelliteEphemeris class
+    jclass galileoSatelliteEphemerisClass =
+            env->FindClass("android/location/GalileoSatelliteEphemeris");
+    method_galileoSatelliteEphemerisGetSatelliteClockModels =
+            env->GetMethodID(galileoSatelliteEphemerisClass, "getSatelliteClockModels",
+                             "()Ljava/util/List;");
+    method_galileoSatelliteEphemerisGetSvid =
+            env->GetMethodID(galileoSatelliteEphemerisClass, "getSvid", "()I");
+    method_galileoSatelliteEphemerisGetSatelliteEphemerisTime =
+            env->GetMethodID(galileoSatelliteEphemerisClass, "getSatelliteEphemerisTime",
+                             "()Landroid/location/SatelliteEphemerisTime;");
+    method_galileoSatelliteEphemerisGetSatelliteHealth =
+            env->GetMethodID(galileoSatelliteEphemerisClass, "getSatelliteHealth",
+                             "()Landroid/location/GalileoSatelliteEphemeris$GalileoSvHealth;");
+    method_galileoSatelliteEphemerisGetSatelliteOrbitModel =
+            env->GetMethodID(galileoSatelliteEphemerisClass, "getSatelliteOrbitModel",
+                             "()Landroid/location/KeplerianOrbitModel;");
+
+    // Get the methods of GalileoSatelliteClockModel class.
+    jclass galileoSatelliteClockModelClass =
+            env->FindClass("android/location/GalileoSatelliteEphemeris$GalileoSatelliteClockModel");
+    method_galileoSatelliteClockModelGetAf0 =
+            env->GetMethodID(galileoSatelliteClockModelClass, "getAf0", "()D");
+    method_galileoSatelliteClockModelGetAf1 =
+            env->GetMethodID(galileoSatelliteClockModelClass, "getAf1", "()D");
+    method_galileoSatelliteClockModelGetAf2 =
+            env->GetMethodID(galileoSatelliteClockModelClass, "getAf2", "()D");
+    method_galileoSatelliteClockModelGetBgdSeconds =
+            env->GetMethodID(galileoSatelliteClockModelClass, "getBgdSeconds", "()D");
+    method_galileoSatelliteClockModelGetSatelliteClockType =
+            env->GetMethodID(galileoSatelliteClockModelClass, "getSatelliteClockType", "()I");
+    method_galileoSatelliteClockModelGetSisaMeters =
+            env->GetMethodID(galileoSatelliteClockModelClass, "getSisaMeters", "()D");
+    method_galileoSatelliteClockModelGetTimeOfClockSeconds =
+            env->GetMethodID(galileoSatelliteClockModelClass, "getTimeOfClockSeconds", "()J");
+
+    // Get the methods of GalileoSvHealth class.
+    jclass galileoSvHealthClass =
+            env->FindClass("android/location/GalileoSatelliteEphemeris$GalileoSvHealth");
+    method_galileoSvHealthGetDataValidityStatusE1b =
+            env->GetMethodID(galileoSvHealthClass, "getDataValidityStatusE1b", "()I");
+    method_galileoSvHealthGetDataValidityStatusE5a =
+            env->GetMethodID(galileoSvHealthClass, "getDataValidityStatusE5a", "()I");
+    method_galileoSvHealthGetDataValidityStatusE5b =
+            env->GetMethodID(galileoSvHealthClass, "getDataValidityStatusE5b", "()I");
+    method_galileoSvHealthGetSignalHealthStatusE1b =
+            env->GetMethodID(galileoSvHealthClass, "getSignalHealthStatusE1b", "()I");
+    method_galileoSvHealthGetSignalHealthStatusE5a =
+            env->GetMethodID(galileoSvHealthClass, "getSignalHealthStatusE5a", "()I");
+    method_galileoSvHealthGetSignalHealthStatusE5b =
+            env->GetMethodID(galileoSvHealthClass, "getSignalHealthStatusE5b", "()I");
+
+    // Get the methods of GalileoIonosphericModel class.
+    jclass galileoIonosphericModelClass =
+            env->FindClass("android/location/GalileoIonosphericModel");
+    method_galileoIonosphericModelGetAi0 =
+            env->GetMethodID(galileoIonosphericModelClass, "getAi0", "()D");
+    method_galileoIonosphericModelGetAi1 =
+            env->GetMethodID(galileoIonosphericModelClass, "getAi1", "()D");
+    method_galileoIonosphericModelGetAi2 =
+            env->GetMethodID(galileoIonosphericModelClass, "getAi2", "()D");
+
+    // Get the methods of GlonassAssistance class.
+    jclass glonassAssistanceClass = env->FindClass("android/location/GlonassAssistance");
+    method_glonassAssistanceGetAlmanac = env->GetMethodID(glonassAssistanceClass, "getAlmanac",
+                                                          "()Landroid/location/GlonassAlmanac;");
+    method_glonassAssistanceGetUtcModel = env->GetMethodID(glonassAssistanceClass, "getUtcModel",
+                                                           "()Landroid/location/UtcModel;");
+    method_glonassAssistanceGetTimeModels =
+            env->GetMethodID(glonassAssistanceClass, "getTimeModels", "()Ljava/util/List;");
+    method_glonassAssistanceGetSatelliteEphemeris =
+            env->GetMethodID(glonassAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;");
+    method_glonassAssistanceGetSatelliteCorrections =
+            env->GetMethodID(glonassAssistanceClass, "getSatelliteCorrections",
+                             "()Ljava/util/List;");
+
+    // Get the methods of GlonassAlmanac class.
+    jclass glonassAlmanacClass = env->FindClass("android/location/GlonassAlmanac");
+    method_glonassAlmanacGetIssueDateMillis =
+            env->GetMethodID(glonassAlmanacClass, "getIssueDateMillis", "()J");
+    method_glonassAlmanacGetSatelliteAlmanacs =
+            env->GetMethodID(glonassAlmanacClass, "getSatelliteAlmanacs", "()Ljava/util/List;");
+
+    // Get the methods of GlonassSatelliteAlmanac class
+    jclass glonassSatelliteAlmanacClass =
+            env->FindClass("android/location/GlonassAlmanac$GlonassSatelliteAlmanac");
+    method_glonassSatelliteAlmanacGetDeltaI =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getDeltaI", "()D");
+    method_glonassSatelliteAlmanacGetDeltaT =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getDeltaT", "()D");
+    method_glonassSatelliteAlmanacGetDeltaTDot =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getDeltaTDot", "()D");
+    method_glonassSatelliteAlmanacGetEccentricity =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getEccentricity", "()D");
+    method_glonassSatelliteAlmanacGetFrequencyChannelNumber =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getFrequencyChannelNumber", "()I");
+    method_glonassSatelliteAlmanacGetLambda =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getLambda", "()D");
+    method_glonassSatelliteAlmanacGetOmega =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getOmega", "()D");
+    method_glonassSatelliteAlmanacGetSlotNumber =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getSlotNumber", "()I");
+    method_glonassSatelliteAlmanacGetHealthState =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getHealthState", "()I");
+    method_glonassSatelliteAlmanacGetTLambda =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getTLambda", "()D");
+    method_glonassSatelliteAlmanacGetTau =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getTau", "()D");
+    method_glonassSatelliteAlmanacGetCalendarDayNumber =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "getCalendarDayNumber", "()I");
+    method_glonassSatelliteAlmanacGetIsGlonassM =
+            env->GetMethodID(glonassSatelliteAlmanacClass, "isGlonassM", "()Z");
+
+    // Get the methods of GlonassSatelliteEphemeris
+    jclass glonassSatelliteEphemerisClass =
+            env->FindClass("android/location/GlonassSatelliteEphemeris");
+    method_glonassSatelliteEphemerisGetAgeInDays =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "getAgeInDays", "()I");
+    method_glonassSatelliteEphemerisGetFrameTimeSeconds =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "getFrameTimeSeconds", "()D");
+    method_glonassSatelliteEphemerisGetHealthState =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "getHealthState", "()I");
+    method_glonassSatelliteEphemerisGetSlotNumber =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "getSlotNumber", "()I");
+    method_glonassSatelliteEphemerisGetSatelliteClockModel =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "getSatelliteClockModel",
+                             "()Landroid/location/"
+                             "GlonassSatelliteEphemeris$GlonassSatelliteClockModel;");
+    method_glonassSatelliteEphemerisGetSatelliteOrbitModel =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "getSatelliteOrbitModel",
+                             "()Landroid/location/"
+                             "GlonassSatelliteEphemeris$GlonassSatelliteOrbitModel;");
+    method_glonassSatelliteEphemerisGetUpdateIntervalMinutes =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "getUpdateIntervalMinutes", "()I");
+    method_glonassSatelliteEphemerisGetIsGlonassM =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "isGlonassM", "()Z");
+    method_glonassSatelliteEphemerisGetIsUpdateIntervalOdd =
+            env->GetMethodID(glonassSatelliteEphemerisClass, "isUpdateIntervalOdd", "()Z");
+
+    // Get the methods of GlonassSatelliteOrbitModel
+    jclass glonassSatelliteOrbitModelClass =
+            env->FindClass("android/location/GlonassSatelliteEphemeris$GlonassSatelliteOrbitModel");
+    method_glonassSatelliteOrbitModelGetX =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getX", "()D");
+    method_glonassSatelliteOrbitModelGetXAccel =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getXAccel", "()D");
+    method_glonassSatelliteOrbitModelGetXDot =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getXDot", "()D");
+    method_glonassSatelliteOrbitModelGetY =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getY", "()D");
+    method_glonassSatelliteOrbitModelGetYAccel =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getYAccel", "()D");
+    method_glonassSatelliteOrbitModelGetYDot =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getYDot", "()D");
+    method_glonassSatelliteOrbitModelGetZ =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getZ", "()D");
+    method_glonassSatelliteOrbitModelGetZAccel =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getZAccel", "()D");
+    method_glonassSatelliteOrbitModelGetZDot =
+            env->GetMethodID(glonassSatelliteOrbitModelClass, "getZDot", "()D");
+
+    // Get the methods of GlonassSatelliteClockModel
+    jclass glonassSatelliteClockModelClass =
+            env->FindClass("android/location/GlonassSatelliteEphemeris$GlonassSatelliteClockModel");
+    method_glonassSatelliteClockModelGetClockBias =
+            env->GetMethodID(glonassSatelliteClockModelClass, "getClockBias", "()D");
+    method_glonassSatelliteClockModelGetFrequencyBias =
+            env->GetMethodID(glonassSatelliteClockModelClass, "getFrequencyBias", "()D");
+    method_glonassSatelliteClockModelGetFrequencyChannelNumber =
+            env->GetMethodID(glonassSatelliteClockModelClass, "getFrequencyChannelNumber", "()I");
+    method_glonassSatelliteClockModelGetTimeOfClockSeconds =
+            env->GetMethodID(glonassSatelliteClockModelClass, "getTimeOfClockSeconds", "()J");
+
+    // Get the methods of QzssAssistance class.
+    jclass qzssAssistanceClass = env->FindClass("android/location/QzssAssistance");
+    method_qzssAssistanceGetAlmanac =
+            env->GetMethodID(qzssAssistanceClass, "getAlmanac", "()Landroid/location/GnssAlmanac;");
+    method_qzssAssistanceGetIonosphericModel =
+            env->GetMethodID(qzssAssistanceClass, "getIonosphericModel",
+                             "()Landroid/location/KlobucharIonosphericModel;");
+    method_qzssAssistanceGetUtcModel =
+            env->GetMethodID(qzssAssistanceClass, "getUtcModel", "()Landroid/location/UtcModel;");
+    method_qzssAssistanceGetLeapSecondsModel =
+            env->GetMethodID(qzssAssistanceClass, "getLeapSecondsModel",
+                             "()Landroid/location/LeapSecondsModel;");
+    method_qzssAssistanceGetTimeModels =
+            env->GetMethodID(qzssAssistanceClass, "getTimeModels", "()Ljava/util/List;");
+    method_qzssAssistanceGetSatelliteEphemeris =
+            env->GetMethodID(qzssAssistanceClass, "getSatelliteEphemeris", "()Ljava/util/List;");
+    method_qzssAssistanceGetSatelliteCorrections =
+            env->GetMethodID(qzssAssistanceClass, "getSatelliteCorrections", "()Ljava/util/List;");
+
+    // Get the methods of QzssSatelliteEphemeris class.
+    jclass qzssSatelliteEphemerisClass = env->FindClass("android/location/QzssSatelliteEphemeris");
+    method_qzssSatelliteEphemerisGetSvid =
+            env->GetMethodID(qzssSatelliteEphemerisClass, "getSvid", "()I");
+    method_qzssSatelliteEphemerisGetGpsL2Params =
+            env->GetMethodID(qzssSatelliteEphemerisClass, "getGpsL2Params",
+                             "()Landroid/location/GpsSatelliteEphemeris$GpsL2Params;");
+    method_qzssSatelliteEphemerisGetSatelliteEphemerisTime =
+            env->GetMethodID(qzssSatelliteEphemerisClass, "getSatelliteEphemerisTime",
+                             "()Landroid/location/SatelliteEphemerisTime;");
+    method_qzssSatelliteEphemerisGetSatelliteHealth =
+            env->GetMethodID(qzssSatelliteEphemerisClass, "getSatelliteHealth",
+                             "()Landroid/location/GpsSatelliteEphemeris$GpsSatelliteHealth;");
+    method_qzssSatelliteEphemerisGetSatelliteOrbitModel =
+            env->GetMethodID(qzssSatelliteEphemerisClass, "getSatelliteOrbitModel",
+                             "()Landroid/location/KeplerianOrbitModel;");
+}
+
+GnssAssistanceInterface::GnssAssistanceInterface(
+        const sp<IGnssAssistanceInterface>& iGnssAssistance)
+      : mGnssAssistanceInterface(iGnssAssistance) {
+    assert(mGnssAssistanceInterface != nullptr);
+}
+
+jboolean GnssAssistanceInterface::injectGnssAssistance(JNIEnv* env, jobject gnssAssistanceObj) {
+    GnssAssistance gnssAssistance;
+    GnssAssistanceUtil::setGnssAssistance(env, gnssAssistanceObj, gnssAssistance);
+    auto status = mGnssAssistanceInterface->injectGnssAssistance(gnssAssistance);
+    return checkAidlStatus(status, "IGnssAssistanceInterface injectGnssAssistance() failed.");
+}
+
+jboolean GnssAssistanceInterface::setCallback(const sp<IGnssAssistanceCallback>& callback) {
+    auto status = mGnssAssistanceInterface->setCallback(callback);
+    return checkAidlStatus(status, "IGnssAssistanceInterface setCallback() failed.");
+}
+
+void GnssAssistanceUtil::setGnssAssistance(JNIEnv* env, jobject gnssAssistanceObj,
+                                           GnssAssistance& gnssAssistance) {
+    jobject gpsAssistanceObj =
+            env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetGpsAssistance);
+    jobject glonassAssistanceObj =
+            env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetGlonassAssistance);
+    jobject qzssAssistanceObj =
+            env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetQzssAssistance);
+    jobject galileoAssistanceObj =
+            env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetGalileoAssistance);
+    jobject beidouAssistanceObj =
+            env->CallObjectMethod(gnssAssistanceObj, method_gnssAssistanceGetBeidouAssistance);
+    GnssAssistanceUtil::setGpsAssistance(env, gpsAssistanceObj, gnssAssistance.gpsAssistance);
+    GnssAssistanceUtil::setGlonassAssistance(env, glonassAssistanceObj,
+                                             gnssAssistance.glonassAssistance);
+    GnssAssistanceUtil::setQzssAssistance(env, qzssAssistanceObj, gnssAssistance.qzssAssistance);
+    GnssAssistanceUtil::setGalileoAssistance(env, galileoAssistanceObj,
+                                             gnssAssistance.galileoAssistance);
+    GnssAssistanceUtil::setBeidouAssistance(env, beidouAssistanceObj,
+                                            gnssAssistance.beidouAssistance);
+    env->DeleteLocalRef(gpsAssistanceObj);
+    env->DeleteLocalRef(glonassAssistanceObj);
+    env->DeleteLocalRef(qzssAssistanceObj);
+    env->DeleteLocalRef(galileoAssistanceObj);
+    env->DeleteLocalRef(beidouAssistanceObj);
+}
+
+void GnssAssistanceUtil::setQzssAssistance(JNIEnv* env, jobject qzssAssistanceObj,
+                                           QzssAssistance& qzssAssistance) {
+    jobject qzssAlmanacObj =
+            env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetAlmanac);
+    jobject qzssIonosphericModelObj =
+            env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetIonosphericModel);
+    jobject qzssUtcModelObj =
+            env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetUtcModel);
+    jobject qzssLeapSecondsModelObj =
+            env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetLeapSecondsModel);
+    jobject qzssTimeModelsObj =
+            env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetTimeModels);
+    jobject qzssSatelliteEphemerisObj =
+            env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetSatelliteEphemeris);
+    jobject qzssSatelliteCorrectionsObj =
+            env->CallObjectMethod(qzssAssistanceObj, method_qzssAssistanceGetSatelliteCorrections);
+    setGnssAlmanac(env, qzssAlmanacObj, qzssAssistance.almanac);
+    setKlobucharIonosphericModel(env, qzssIonosphericModelObj, qzssAssistance.ionosphericModel);
+    setUtcModel(env, qzssUtcModelObj, qzssAssistance.utcModel);
+    setLeapSecondsModel(env, qzssLeapSecondsModelObj, qzssAssistance.leapSecondsModel);
+    setTimeModels(env, qzssTimeModelsObj, qzssAssistance.timeModels);
+    setGpsOrQzssSatelliteEphemeris<QzssSatelliteEphemeris>(env, qzssSatelliteEphemerisObj,
+                                                           qzssAssistance.satelliteEphemeris);
+    setSatelliteCorrections(env, qzssSatelliteCorrectionsObj, qzssAssistance.satelliteCorrections);
+    env->DeleteLocalRef(qzssAlmanacObj);
+    env->DeleteLocalRef(qzssIonosphericModelObj);
+    env->DeleteLocalRef(qzssUtcModelObj);
+    env->DeleteLocalRef(qzssLeapSecondsModelObj);
+    env->DeleteLocalRef(qzssTimeModelsObj);
+    env->DeleteLocalRef(qzssSatelliteEphemerisObj);
+    env->DeleteLocalRef(qzssSatelliteCorrectionsObj);
+}
+
+void GnssAssistanceUtil::setGlonassAssistance(JNIEnv* env, jobject glonassAssistanceObj,
+                                              GlonassAssistance& galileoAssistance) {
+    jobject glonassAlmanacObj =
+            env->CallObjectMethod(glonassAssistanceObj, method_glonassAssistanceGetAlmanac);
+    jobject utcModelObj =
+            env->CallObjectMethod(glonassAssistanceObj, method_glonassAssistanceGetUtcModel);
+    jobject timeModelsObj =
+            env->CallObjectMethod(glonassAssistanceObj, method_glonassAssistanceGetTimeModels);
+    jobject satelliteEphemerisObj =
+            env->CallObjectMethod(glonassAssistanceObj,
+                                  method_glonassAssistanceGetSatelliteEphemeris);
+    jobject satelliteCorrectionsObj =
+            env->CallObjectMethod(glonassAssistanceObj,
+                                  method_glonassAssistanceGetSatelliteCorrections);
+    setGlonassAlmanac(env, glonassAlmanacObj, galileoAssistance.almanac);
+    setUtcModel(env, utcModelObj, galileoAssistance.utcModel);
+    setTimeModels(env, timeModelsObj, galileoAssistance.timeModels);
+    setGlonassSatelliteEphemeris(env, satelliteEphemerisObj, galileoAssistance.satelliteEphemeris);
+    setSatelliteCorrections(env, satelliteCorrectionsObj, galileoAssistance.satelliteCorrections);
+    env->DeleteLocalRef(glonassAlmanacObj);
+    env->DeleteLocalRef(utcModelObj);
+    env->DeleteLocalRef(timeModelsObj);
+    env->DeleteLocalRef(satelliteEphemerisObj);
+    env->DeleteLocalRef(satelliteCorrectionsObj);
+}
+
+void GnssAssistanceUtil::setGlonassAlmanac(JNIEnv* env, jobject glonassAlmanacObj,
+                                           GlonassAlmanac& glonassAlmanac) {
+    if (glonassAlmanacObj == nullptr) {
+        glonassAlmanac.issueDateMs = -1;
+        return;
+    }
+    jlong issueDateMillis =
+            env->CallLongMethod(glonassAlmanacObj, method_glonassAlmanacGetIssueDateMillis);
+    glonassAlmanac.issueDateMs = issueDateMillis;
+    jobject satelliteAlmanacsObj =
+            env->CallObjectMethod(glonassAlmanacObj, method_glonassAlmanacGetSatelliteAlmanacs);
+    if (satelliteAlmanacsObj == nullptr) return;
+    auto len = env->CallIntMethod(satelliteAlmanacsObj, method_listSize);
+    for (uint16_t i = 0; i < len; ++i) {
+        jobject glonassSatelliteAlmanacObj =
+                env->CallObjectMethod(satelliteAlmanacsObj, method_listGet, i);
+        if (glonassSatelliteAlmanacObj == nullptr) continue;
+        GlonassSatelliteAlmanac glonassSatelliteAlmanac;
+        jdouble deltaI = env->CallDoubleMethod(glonassSatelliteAlmanacObj,
+                                               method_glonassSatelliteAlmanacGetDeltaI);
+        glonassSatelliteAlmanac.deltaI = deltaI;
+        jdouble deltaT = env->CallDoubleMethod(glonassSatelliteAlmanacObj,
+                                               method_glonassSatelliteAlmanacGetDeltaT);
+        glonassSatelliteAlmanac.deltaT = deltaT;
+        jdouble deltaTDot = env->CallDoubleMethod(glonassSatelliteAlmanacObj,
+                                                  method_glonassSatelliteAlmanacGetDeltaTDot);
+        glonassSatelliteAlmanac.deltaTDot = deltaTDot;
+        jdouble eccentricity = env->CallDoubleMethod(glonassSatelliteAlmanacObj,
+                                                     method_glonassSatelliteAlmanacGetEccentricity);
+        glonassSatelliteAlmanac.eccentricity = eccentricity;
+        jint frequencyChannelNumber =
+                env->CallIntMethod(glonassSatelliteAlmanacObj,
+                                   method_glonassSatelliteAlmanacGetFrequencyChannelNumber);
+        glonassSatelliteAlmanac.frequencyChannelNumber =
+                static_cast<int32_t>(frequencyChannelNumber);
+        jdouble lambda = env->CallDoubleMethod(glonassSatelliteAlmanacObj,
+                                               method_glonassSatelliteAlmanacGetLambda);
+        glonassSatelliteAlmanac.lambda = lambda;
+        jdouble omega = env->CallDoubleMethod(glonassSatelliteAlmanacObj,
+                                              method_glonassSatelliteAlmanacGetOmega);
+        glonassSatelliteAlmanac.omega = omega;
+        jint slotNumber = env->CallIntMethod(glonassSatelliteAlmanacObj,
+                                             method_glonassSatelliteAlmanacGetSlotNumber);
+        glonassSatelliteAlmanac.slotNumber = static_cast<int32_t>(slotNumber);
+        jint healthState = env->CallIntMethod(glonassSatelliteAlmanacObj,
+                                              method_glonassSatelliteAlmanacGetHealthState);
+        glonassSatelliteAlmanac.svHealth = static_cast<int32_t>(healthState);
+        jdouble tLambda = env->CallDoubleMethod(glonassSatelliteAlmanacObj,
+                                                method_glonassSatelliteAlmanacGetTLambda);
+        glonassSatelliteAlmanac.tLambda = tLambda;
+        jdouble tau = env->CallDoubleMethod(glonassSatelliteAlmanacObj,
+                                            method_glonassSatelliteAlmanacGetTau);
+        glonassSatelliteAlmanac.tau = tau;
+        jboolean isGlonassM = env->CallBooleanMethod(glonassSatelliteAlmanacObj,
+                                                     method_glonassSatelliteAlmanacGetIsGlonassM);
+        glonassSatelliteAlmanac.isGlonassM = isGlonassM;
+        jint calendarDayNumber =
+                env->CallIntMethod(glonassSatelliteAlmanacObj,
+                                   method_glonassSatelliteAlmanacGetCalendarDayNumber);
+        glonassSatelliteAlmanac.calendarDayNumber = static_cast<int32_t>(calendarDayNumber);
+        glonassAlmanac.satelliteAlmanacs.push_back(glonassSatelliteAlmanac);
+        env->DeleteLocalRef(glonassSatelliteAlmanacObj);
+    }
+    env->DeleteLocalRef(satelliteAlmanacsObj);
+}
+
+void GnssAssistanceUtil::setGlonassSatelliteEphemeris(
+        JNIEnv* env, jobject glonassSatelliteEphemerisListObj,
+        std::vector<GlonassSatelliteEphemeris>& glonassSatelliteEphemerisList) {
+    if (glonassSatelliteEphemerisListObj == nullptr) return;
+    auto len = env->CallIntMethod(glonassSatelliteEphemerisListObj, method_listSize);
+    for (uint16_t i = 0; i < len; ++i) {
+        jobject glonassSatelliteEphemerisObj =
+                env->CallObjectMethod(glonassSatelliteEphemerisListObj, method_listGet, i);
+        if (glonassSatelliteEphemerisObj == nullptr) continue;
+        GlonassSatelliteEphemeris glonassSatelliteEphemeris;
+        jdouble ageInDays = env->CallDoubleMethod(glonassSatelliteEphemerisObj,
+                                                  method_glonassSatelliteEphemerisGetAgeInDays);
+        glonassSatelliteEphemeris.ageInDays = ageInDays;
+
+        // Set the GlonassSatelliteClockModel.
+        jobject glonassSatelliteClockModelObj =
+                env->CallObjectMethod(glonassSatelliteEphemerisObj,
+                                      method_glonassSatelliteEphemerisGetSatelliteClockModel);
+        GlonassSatelliteClockModel glonassSatelliteClockModel;
+        jdouble clockBias = env->CallDoubleMethod(glonassSatelliteClockModelObj,
+                                                  method_glonassSatelliteClockModelGetClockBias);
+        glonassSatelliteClockModel.clockBias = clockBias;
+        jdouble frequencyBias =
+                env->CallDoubleMethod(glonassSatelliteClockModelObj,
+                                      method_glonassSatelliteClockModelGetFrequencyBias);
+        glonassSatelliteClockModel.frequencyBias = frequencyBias;
+        jint frequencyChannelNumber =
+                env->CallIntMethod(glonassSatelliteClockModelObj,
+                                   method_glonassSatelliteClockModelGetFrequencyChannelNumber);
+        glonassSatelliteClockModel.frequencyChannelNumber =
+                static_cast<int32_t>(frequencyChannelNumber);
+        jdouble timeOfClockSeconds =
+                env->CallDoubleMethod(glonassSatelliteClockModelObj,
+                                      method_glonassSatelliteClockModelGetTimeOfClockSeconds);
+        glonassSatelliteClockModel.timeOfClockSeconds = timeOfClockSeconds;
+        glonassSatelliteEphemeris.satelliteClockModel = glonassSatelliteClockModel;
+        env->DeleteLocalRef(glonassSatelliteClockModelObj);
+
+        // Set the GlonassSatelliteOrbitModel.
+        jobject glonassSatelliteOrbitModelObj =
+                env->CallObjectMethod(glonassSatelliteEphemerisObj,
+                                      method_glonassSatelliteEphemerisGetSatelliteOrbitModel);
+        GlonassSatelliteOrbitModel glonassSatelliteOrbitModel;
+        jdouble x = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                          method_glonassSatelliteOrbitModelGetX);
+        glonassSatelliteOrbitModel.x = x;
+        jdouble y = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                          method_glonassSatelliteOrbitModelGetY);
+        glonassSatelliteOrbitModel.y = y;
+        jdouble z = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                          method_glonassSatelliteOrbitModelGetZ);
+        glonassSatelliteOrbitModel.z = z;
+        jdouble xAccel = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                               method_glonassSatelliteOrbitModelGetXAccel);
+        glonassSatelliteOrbitModel.xAccel = xAccel;
+        jdouble yAccel = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                               method_glonassSatelliteOrbitModelGetYAccel);
+        glonassSatelliteOrbitModel.yAccel = yAccel;
+        jdouble zAccel = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                               method_glonassSatelliteOrbitModelGetZAccel);
+        glonassSatelliteOrbitModel.zAccel = zAccel;
+        jdouble xDot = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                             method_glonassSatelliteOrbitModelGetXDot);
+        glonassSatelliteOrbitModel.xDot = xDot;
+        jdouble yDot = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                             method_glonassSatelliteOrbitModelGetYDot);
+        glonassSatelliteOrbitModel.yDot = yDot;
+        jdouble zDot = env->CallDoubleMethod(glonassSatelliteOrbitModelObj,
+                                             method_glonassSatelliteOrbitModelGetZDot);
+        glonassSatelliteOrbitModel.zDot = zDot;
+        glonassSatelliteEphemeris.satelliteOrbitModel = glonassSatelliteOrbitModel;
+        env->DeleteLocalRef(glonassSatelliteOrbitModelObj);
+
+        jint healthState = env->CallIntMethod(glonassSatelliteEphemerisObj,
+                                              method_glonassSatelliteEphemerisGetHealthState);
+        glonassSatelliteEphemeris.svHealth = static_cast<int32_t>(healthState);
+        jint slotNumber = env->CallIntMethod(glonassSatelliteEphemerisObj,
+                                             method_glonassSatelliteEphemerisGetSlotNumber);
+        glonassSatelliteEphemeris.slotNumber = static_cast<int32_t>(slotNumber);
+        jdouble frameTimeSeconds =
+                env->CallDoubleMethod(glonassSatelliteEphemerisObj,
+                                      method_glonassSatelliteEphemerisGetFrameTimeSeconds);
+        glonassSatelliteEphemeris.frameTimeSeconds = frameTimeSeconds;
+        jint updateIntervalMinutes =
+                env->CallIntMethod(glonassSatelliteEphemerisObj,
+                                   method_glonassSatelliteEphemerisGetUpdateIntervalMinutes);
+        glonassSatelliteEphemeris.updateIntervalMinutes =
+                static_cast<int32_t>(updateIntervalMinutes);
+        jboolean isGlonassM = env->CallBooleanMethod(glonassSatelliteEphemerisObj,
+                                                     method_glonassSatelliteEphemerisGetIsGlonassM);
+        glonassSatelliteEphemeris.isGlonassM = isGlonassM;
+        jboolean isUpdateIntervalOdd =
+                env->CallBooleanMethod(glonassSatelliteEphemerisObj,
+                                       method_glonassSatelliteEphemerisGetIsUpdateIntervalOdd);
+        glonassSatelliteEphemeris.isOddUpdateInterval = isUpdateIntervalOdd;
+        glonassSatelliteEphemerisList.push_back(glonassSatelliteEphemeris);
+        env->DeleteLocalRef(glonassSatelliteEphemerisObj);
+    }
+}
+
+void GnssAssistanceUtil::setGalileoAssistance(JNIEnv* env, jobject galileoAssistanceObj,
+                                              GalileoAssistance& galileoAssistance) {
+    jobject galileoAlmanacObj =
+            env->CallObjectMethod(galileoAssistanceObj, method_galileoAssistanceGetAlmanac);
+    jobject ionosphericModelObj =
+            env->CallObjectMethod(galileoAssistanceObj,
+                                  method_galileoAssistanceGetIonosphericModel);
+    jobject utcModelObj =
+            env->CallObjectMethod(galileoAssistanceObj, method_galileoAssistanceGetUtcModel);
+    jobject leapSecondsModelObj =
+            env->CallObjectMethod(galileoAssistanceObj,
+                                  method_galileoAssistanceGetLeapSecondsModel);
+    jobject timeModelsObj =
+            env->CallObjectMethod(galileoAssistanceObj, method_galileoAssistanceGetTimeModels);
+    jobject satelliteEphemerisObj =
+            env->CallObjectMethod(galileoAssistanceObj,
+                                  method_galileoAssistanceGetSatelliteEphemeris);
+    jobject realTimeIntegrityModelsObj =
+            env->CallObjectMethod(galileoAssistanceObj,
+                                  method_galileoAssistanceGetRealTimeIntegrityModels);
+    jobject satelliteCorrectionsObj =
+            env->CallObjectMethod(galileoAssistanceObj,
+                                  method_galileoAssistanceGetSatelliteCorrections);
+    setGnssAlmanac(env, galileoAlmanacObj, galileoAssistance.almanac);
+    setGaliloKlobucharIonosphericModel(env, ionosphericModelObj,
+                                       galileoAssistance.ionosphericModel);
+    setUtcModel(env, utcModelObj, galileoAssistance.utcModel);
+    setLeapSecondsModel(env, leapSecondsModelObj, galileoAssistance.leapSecondsModel);
+    setTimeModels(env, timeModelsObj, galileoAssistance.timeModels);
+    setGalileoSatelliteEphemeris(env, satelliteEphemerisObj, galileoAssistance.satelliteEphemeris);
+    setRealTimeIntegrityModels(env, realTimeIntegrityModelsObj,
+                               galileoAssistance.realTimeIntegrityModels);
+    setSatelliteCorrections(env, satelliteCorrectionsObj, galileoAssistance.satelliteCorrections);
+    env->DeleteLocalRef(galileoAlmanacObj);
+    env->DeleteLocalRef(ionosphericModelObj);
+    env->DeleteLocalRef(utcModelObj);
+    env->DeleteLocalRef(leapSecondsModelObj);
+    env->DeleteLocalRef(timeModelsObj);
+    env->DeleteLocalRef(satelliteEphemerisObj);
+    env->DeleteLocalRef(realTimeIntegrityModelsObj);
+    env->DeleteLocalRef(satelliteCorrectionsObj);
+}
+
+void GnssAssistanceUtil::setGaliloKlobucharIonosphericModel(
+        JNIEnv* env, jobject galileoIonosphericModelObj,
+        GalileoIonosphericModel& ionosphericModel) {
+    if (galileoIonosphericModelObj == nullptr) return;
+    jdouble ai0 =
+            env->CallDoubleMethod(galileoIonosphericModelObj, method_galileoIonosphericModelGetAi0);
+    ionosphericModel.ai0 = ai0;
+    jdouble ai1 =
+            env->CallDoubleMethod(galileoIonosphericModelObj, method_galileoIonosphericModelGetAi1);
+    ionosphericModel.ai1 = ai1;
+    jdouble ai2 =
+            env->CallDoubleMethod(galileoIonosphericModelObj, method_galileoIonosphericModelGetAi2);
+    ionosphericModel.ai2 = ai2;
+}
+
+void GnssAssistanceUtil::setGalileoSatelliteEphemeris(
+        JNIEnv* env, jobject galileoSatelliteEphemerisListObj,
+        std::vector<GalileoSatelliteEphemeris>& galileoSatelliteEphemerisList) {
+    if (galileoSatelliteEphemerisListObj == nullptr) return;
+    auto len = env->CallIntMethod(galileoSatelliteEphemerisListObj, method_listSize);
+    for (uint16_t i = 0; i < len; ++i) {
+        jobject galileoSatelliteEphemerisObj =
+                env->CallObjectMethod(galileoSatelliteEphemerisListObj, method_listGet, i);
+        GalileoSatelliteEphemeris galileoSatelliteEphemeris;
+        GalileoSvHealth galileoSvHealth;
+        // Set the svid of the satellite.
+        jint svid = env->CallLongMethod(galileoSatelliteEphemerisObj,
+                                        method_galileoSatelliteEphemerisGetSvid);
+        galileoSatelliteEphemeris.svid = svid;
+
+        // Set the satellite clock models.
+        jobject galileoSatelliteClockModelListObj =
+                env->CallObjectMethod(galileoSatelliteEphemerisObj,
+                                      method_galileoSatelliteEphemerisGetSatelliteClockModels);
+        auto size = env->CallIntMethod(galileoSatelliteClockModelListObj, method_listSize);
+        for (uint16_t j = 0; j < size; ++j) {
+            jobject galileoSatelliteClockModelObj =
+                    env->CallObjectMethod(galileoSatelliteClockModelListObj, method_listGet, j);
+            if (galileoSatelliteClockModelObj == nullptr) continue;
+            GalileoSatelliteClockModel galileoSatelliteClockModel;
+            jdouble af0 = env->CallDoubleMethod(galileoSatelliteClockModelObj,
+                                                method_galileoSatelliteClockModelGetAf0);
+            galileoSatelliteClockModel.af0 = af0;
+            jdouble af1 = env->CallDoubleMethod(galileoSatelliteClockModelObj,
+                                                method_galileoSatelliteClockModelGetAf1);
+            galileoSatelliteClockModel.af1 = af1;
+            jdouble af2 = env->CallDoubleMethod(galileoSatelliteClockModelObj,
+                                                method_galileoSatelliteClockModelGetAf2);
+            galileoSatelliteClockModel.af2 = af2;
+            jdouble bgdSeconds =
+                    env->CallDoubleMethod(galileoSatelliteClockModelObj,
+                                          method_galileoSatelliteClockModelGetBgdSeconds);
+            galileoSatelliteClockModel.bgdSeconds = bgdSeconds;
+            jint satelliteClockType =
+                    env->CallIntMethod(galileoSatelliteClockModelObj,
+                                       method_galileoSatelliteClockModelGetSatelliteClockType);
+            galileoSatelliteClockModel.satelliteClockType =
+                    static_cast<GalileoSatelliteClockModel::SatelliteClockType>(satelliteClockType);
+            jdouble sisaMeters =
+                    env->CallDoubleMethod(galileoSatelliteClockModelObj,
+                                          method_galileoSatelliteClockModelGetSisaMeters);
+            galileoSatelliteClockModel.sisaMeters = sisaMeters;
+            jdouble timeOfClockSeconds =
+                    env->CallDoubleMethod(galileoSatelliteClockModelObj,
+                                          method_galileoSatelliteClockModelGetTimeOfClockSeconds);
+            galileoSatelliteClockModel.timeOfClockSeconds = timeOfClockSeconds;
+            galileoSatelliteEphemeris.satelliteClockModel.push_back(galileoSatelliteClockModel);
+            env->DeleteLocalRef(galileoSatelliteClockModelObj);
+        }
+        env->DeleteLocalRef(galileoSatelliteClockModelListObj);
+
+        // Set the satelliteOrbitModel of the satellite.
+        jobject satelliteOrbitModelObj =
+                env->CallObjectMethod(galileoSatelliteEphemerisObj,
+                                      method_galileoSatelliteEphemerisGetSatelliteOrbitModel);
+        GnssAssistanceUtil::setKeplerianOrbitModel(env, satelliteOrbitModelObj,
+                                                   galileoSatelliteEphemeris.satelliteOrbitModel);
+        env->DeleteLocalRef(satelliteOrbitModelObj);
+
+        // Set the satellite health of the satellite clock model.
+        jobject galileoSvHealthObj =
+                env->CallObjectMethod(galileoSatelliteEphemerisObj,
+                                      method_galileoSatelliteEphemerisGetSatelliteHealth);
+        jint dataValidityStatusE1b =
+                env->CallIntMethod(galileoSvHealthObj,
+                                   method_galileoSvHealthGetDataValidityStatusE1b);
+        galileoSvHealth.dataValidityStatusE1b =
+                static_cast<GalileoSvHealth::GalileoHealthDataVaidityType>(dataValidityStatusE1b);
+        jint dataValidityStatusE5a =
+                env->CallIntMethod(galileoSvHealthObj,
+                                   method_galileoSvHealthGetDataValidityStatusE5a);
+        galileoSvHealth.dataValidityStatusE5a =
+                static_cast<GalileoSvHealth::GalileoHealthDataVaidityType>(dataValidityStatusE5a);
+        jint dataValidityStatusE5b =
+                env->CallIntMethod(galileoSvHealthObj,
+                                   method_galileoSvHealthGetDataValidityStatusE5b);
+        galileoSvHealth.dataValidityStatusE5b =
+                static_cast<GalileoSvHealth::GalileoHealthDataVaidityType>(dataValidityStatusE5b);
+        jint signalHealthStatusE1b =
+                env->CallIntMethod(galileoSvHealthObj,
+                                   method_galileoSvHealthGetSignalHealthStatusE1b);
+        galileoSvHealth.signalHealthStatusE1b =
+                static_cast<GalileoSvHealth::GalileoHealthStatusType>(signalHealthStatusE1b);
+        jint signalHealthStatusE5a =
+                env->CallIntMethod(galileoSvHealthObj,
+                                   method_galileoSvHealthGetSignalHealthStatusE5a);
+        galileoSvHealth.signalHealthStatusE5a =
+                static_cast<GalileoSvHealth::GalileoHealthStatusType>(signalHealthStatusE5a);
+        jint signalHealthStatusE5b =
+                env->CallIntMethod(galileoSvHealthObj,
+                                   method_galileoSvHealthGetSignalHealthStatusE5b);
+        galileoSvHealth.signalHealthStatusE5b =
+                static_cast<GalileoSvHealth::GalileoHealthStatusType>(signalHealthStatusE5b);
+        galileoSatelliteEphemeris.svHealth = galileoSvHealth;
+        env->DeleteLocalRef(galileoSvHealthObj);
+
+        // Set the satelliteEphemerisTime of the satellite.
+        jobject satelliteEphemerisTimeObj =
+                env->CallObjectMethod(galileoSatelliteEphemerisObj,
+                                      method_galileoSatelliteEphemerisGetSatelliteEphemerisTime);
+        GnssAssistanceUtil::setSatelliteEphemerisTime(env, satelliteEphemerisTimeObj,
+                                                      galileoSatelliteEphemeris
+                                                              .satelliteEphemerisTime);
+        env->DeleteLocalRef(satelliteEphemerisTimeObj);
+
+        galileoSatelliteEphemerisList.push_back(galileoSatelliteEphemeris);
+        env->DeleteLocalRef(galileoSatelliteEphemerisObj);
+    }
+}
+
+void GnssAssistanceUtil::setBeidouAssistance(JNIEnv* env, jobject beidouAssistanceObj,
+                                             BeidouAssistance& beidouAssistance) {
+    jobject beidouAlmanacObj =
+            env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetAlmanac);
+    jobject ionosphericModelObj =
+            env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetIonosphericModel);
+    jobject utcModelObj =
+            env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetUtcModel);
+    jobject leapSecondsModelObj =
+            env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetLeapSecondsModel);
+    jobject timeModelsObj =
+            env->CallObjectMethod(beidouAssistanceObj, method_beidouAssistanceGetTimeModels);
+    jobject satelliteEphemerisObj =
+            env->CallObjectMethod(beidouAssistanceObj,
+                                  method_beidouAssistanceGetSatelliteEphemeris);
+    jobject realTimeIntegrityModelsObj =
+            env->CallObjectMethod(beidouAssistanceObj,
+                                  method_beidouAssistanceGetRealTimeIntegrityModels);
+    jobject satelliteCorrectionsObj =
+            env->CallObjectMethod(beidouAssistanceObj,
+                                  method_beidouAssistanceGetSatelliteCorrections);
+    setGnssAlmanac(env, beidouAlmanacObj, beidouAssistance.almanac);
+    setKlobucharIonosphericModel(env, ionosphericModelObj, beidouAssistance.ionosphericModel);
+    setUtcModel(env, utcModelObj, beidouAssistance.utcModel);
+    setLeapSecondsModel(env, leapSecondsModelObj, beidouAssistance.leapSecondsModel);
+    setTimeModels(env, timeModelsObj, beidouAssistance.timeModels);
+    setBeidouSatelliteEphemeris(env, satelliteEphemerisObj, beidouAssistance.satelliteEphemeris);
+    setRealTimeIntegrityModels(env, realTimeIntegrityModelsObj,
+                               beidouAssistance.realTimeIntegrityModels);
+    setSatelliteCorrections(env, satelliteCorrectionsObj, beidouAssistance.satelliteCorrections);
+    env->DeleteLocalRef(beidouAlmanacObj);
+    env->DeleteLocalRef(ionosphericModelObj);
+    env->DeleteLocalRef(utcModelObj);
+    env->DeleteLocalRef(leapSecondsModelObj);
+    env->DeleteLocalRef(timeModelsObj);
+    env->DeleteLocalRef(satelliteEphemerisObj);
+    env->DeleteLocalRef(realTimeIntegrityModelsObj);
+    env->DeleteLocalRef(satelliteCorrectionsObj);
+}
+
+void GnssAssistanceUtil::setBeidouSatelliteEphemeris(
+        JNIEnv* env, jobject beidouSatelliteEphemerisListObj,
+        std::vector<BeidouSatelliteEphemeris>& beidouSatelliteEphemerisList) {
+    if (beidouSatelliteEphemerisListObj == nullptr) return;
+    auto len = env->CallIntMethod(beidouSatelliteEphemerisListObj, method_listSize);
+    for (uint16_t i = 0; i < len; ++i) {
+        jobject beidouSatelliteEphemerisObj =
+                env->CallObjectMethod(beidouSatelliteEphemerisListObj, method_listGet, i);
+        if (beidouSatelliteEphemerisObj == nullptr) continue;
+        BeidouSatelliteEphemeris beidouSatelliteEphemeris;
+
+        // Set the svid of the satellite.
+        jint svid = env->CallIntMethod(beidouSatelliteEphemerisObj,
+                                       method_beidouSatelliteEphemerisGetSvid);
+        beidouSatelliteEphemeris.svid = static_cast<int32_t>(svid);
+
+        // Set the satelliteClockModel of the satellite.
+        jobject satelliteClockModelObj =
+                env->CallObjectMethod(beidouSatelliteEphemerisObj,
+                                      method_beidouSatelliteEphemerisGetSatelliteClockModel);
+        jdouble af0 = env->CallDoubleMethod(satelliteClockModelObj,
+                                            method_beidouSatelliteClockModelGetAf0);
+        jdouble af1 = env->CallDoubleMethod(satelliteClockModelObj,
+                                            method_beidouSatelliteClockModelGetAf1);
+        jdouble af2 = env->CallDoubleMethod(satelliteClockModelObj,
+                                            method_beidouSatelliteClockModelGetAf2);
+        jdouble tgd1 = env->CallDoubleMethod(satelliteClockModelObj,
+                                             method_beidouSatelliteClockModelGetTgd1);
+        jdouble tgd2 = env->CallDoubleMethod(satelliteClockModelObj,
+                                             method_beidouSatelliteClockModelGetTgd2);
+        jdouble aodc = env->CallDoubleMethod(satelliteClockModelObj,
+                                             method_beidouSatelliteClockModelGetAodc);
+        jlong timeOfClockSeconds =
+                env->CallLongMethod(satelliteClockModelObj,
+                                    method_beidouSatelliteClockModelGetTimeOfClockSeconds);
+        beidouSatelliteEphemeris.satelliteClockModel.af0 = af0;
+        beidouSatelliteEphemeris.satelliteClockModel.af1 = af1;
+        beidouSatelliteEphemeris.satelliteClockModel.af2 = af2;
+        beidouSatelliteEphemeris.satelliteClockModel.tgd1 = tgd1;
+        beidouSatelliteEphemeris.satelliteClockModel.tgd2 = tgd2;
+        beidouSatelliteEphemeris.satelliteClockModel.aodc = aodc;
+        beidouSatelliteEphemeris.satelliteClockModel.timeOfClockSeconds = timeOfClockSeconds;
+        env->DeleteLocalRef(satelliteClockModelObj);
+
+        // Set the satelliteOrbitModel of the satellite.
+        jobject satelliteOrbitModelObj =
+                env->CallObjectMethod(beidouSatelliteEphemerisObj,
+                                      method_beidouSatelliteEphemerisGetSatelliteOrbitModel);
+        GnssAssistanceUtil::setKeplerianOrbitModel(env, satelliteOrbitModelObj,
+                                                   beidouSatelliteEphemeris.satelliteOrbitModel);
+        env->DeleteLocalRef(satelliteOrbitModelObj);
+
+        // Set the satelliteHealth of the satellite.
+        jobject satelliteHealthObj =
+                env->CallObjectMethod(beidouSatelliteEphemerisObj,
+                                      method_beidouSatelliteEphemerisGetSatelliteHealth);
+        jint satH1 = env->CallIntMethod(satelliteHealthObj, method_beidouSatelliteHealthGetSatH1);
+        jint svAccur =
+                env->CallIntMethod(satelliteHealthObj, method_beidouSatelliteHealthGetSvAccur);
+        beidouSatelliteEphemeris.satelliteHealth.satH1 = static_cast<int32_t>(satH1);
+        beidouSatelliteEphemeris.satelliteHealth.svAccur = static_cast<int32_t>(svAccur);
+        env->DeleteLocalRef(satelliteHealthObj);
+
+        // Set the satelliteEphemerisTime of the satellite.
+        jobject satelliteEphemerisTimeObj =
+                env->CallObjectMethod(beidouSatelliteEphemerisObj,
+                                      method_beidouSatelliteEphemerisGetSatelliteEphemerisTime);
+        jint iode = env->CallIntMethod(satelliteEphemerisTimeObj,
+                                       method_beidouSatelliteEphemerisTimeGetIode);
+        jint beidouWeekNumber =
+                env->CallIntMethod(satelliteEphemerisTimeObj,
+                                   method_beidouSatelliteEphemerisTimeGetBeidouWeekNumber);
+        jint toeSeconds = env->CallDoubleMethod(satelliteEphemerisTimeObj,
+                                                method_beidouSatelliteEphemerisTimeGetToeSeconds);
+        beidouSatelliteEphemeris.satelliteEphemerisTime.aode = static_cast<int32_t>(iode);
+        beidouSatelliteEphemeris.satelliteEphemerisTime.weekNumber =
+                static_cast<int32_t>(beidouWeekNumber);
+        beidouSatelliteEphemeris.satelliteEphemerisTime.toeSeconds =
+                static_cast<int32_t>(toeSeconds);
+        env->DeleteLocalRef(satelliteEphemerisTimeObj);
+
+        beidouSatelliteEphemerisList.push_back(beidouSatelliteEphemeris);
+        env->DeleteLocalRef(beidouSatelliteEphemerisObj);
+    }
+}
+
+void GnssAssistanceUtil::setGpsAssistance(JNIEnv* env, jobject gpsAssistanceObj,
+                                          GpsAssistance& gpsAssistance) {
+    jobject gnssAlmanacObj =
+            env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetAlmanac);
+    jobject ionosphericModelObj =
+            env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetIonosphericModel);
+    jobject utcModelObj = env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetUtcModel);
+    jobject leapSecondsModelObj =
+            env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetLeapSecondsModel);
+    jobject timeModelsObj =
+            env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetTimeModels);
+    jobject satelliteEphemerisObj =
+            env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetSatelliteEphemeris);
+    jobject realTimeIntegrityModelsObj =
+            env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetRealTimeIntegrityModels);
+    jobject satelliteCorrectionsObj =
+            env->CallObjectMethod(gpsAssistanceObj, method_gpsAssistanceGetSatelliteCorrections);
+
+    setGnssAlmanac(env, gnssAlmanacObj, gpsAssistance.almanac);
+    setKlobucharIonosphericModel(env, ionosphericModelObj, gpsAssistance.ionosphericModel);
+    setUtcModel(env, utcModelObj, gpsAssistance.utcModel);
+    setLeapSecondsModel(env, leapSecondsModelObj, gpsAssistance.leapSecondsModel);
+    setTimeModels(env, timeModelsObj, gpsAssistance.timeModels);
+    setGpsOrQzssSatelliteEphemeris<GpsSatelliteEphemeris>(env, satelliteEphemerisObj,
+                                                          gpsAssistance.satelliteEphemeris);
+    setRealTimeIntegrityModels(env, realTimeIntegrityModelsObj,
+                               gpsAssistance.realTimeIntegrityModels);
+    setSatelliteCorrections(env, satelliteCorrectionsObj, gpsAssistance.satelliteCorrections);
+    env->DeleteLocalRef(gnssAlmanacObj);
+    env->DeleteLocalRef(ionosphericModelObj);
+    env->DeleteLocalRef(utcModelObj);
+    env->DeleteLocalRef(leapSecondsModelObj);
+    env->DeleteLocalRef(timeModelsObj);
+    env->DeleteLocalRef(satelliteEphemerisObj);
+    env->DeleteLocalRef(realTimeIntegrityModelsObj);
+    env->DeleteLocalRef(satelliteCorrectionsObj);
+}
+
+/** Set the GPS/QZSS satellite ephemeris list. */
+template <class T>
+void GnssAssistanceUtil::setGpsOrQzssSatelliteEphemeris(JNIEnv* env,
+                                                        jobject satelliteEphemerisListObj,
+                                                        std::vector<T>& satelliteEphemerisList) {
+    if (satelliteEphemerisListObj == nullptr) return;
+    auto len = env->CallIntMethod(satelliteEphemerisListObj, method_listSize);
+    for (uint16_t i = 0; i < len; ++i) {
+        jobject satelliteEphemerisObj =
+                env->CallObjectMethod(satelliteEphemerisListObj, method_listGet, i);
+        if (satelliteEphemerisObj == nullptr) continue;
+        T satelliteEphemeris;
+        // Set the svid of the satellite.
+        jint svid = env->CallIntMethod(satelliteEphemerisObj, method_gpsSatelliteEphemerisGetSvid);
+        satelliteEphemeris.svid = static_cast<int32_t>(svid);
+
+        // Set the gpsL2Params of the satellite.
+        jobject gpsL2ParamsObj = env->CallObjectMethod(satelliteEphemerisObj,
+                                                       method_gpsSatelliteEphemerisGetGpsL2Params);
+        jint l2Code = env->CallIntMethod(gpsL2ParamsObj, method_gpsL2ParamsGetL2Code);
+        jint l2Flag = env->CallIntMethod(gpsL2ParamsObj, method_gpsL2ParamsGetL2Flag);
+        satelliteEphemeris.gpsL2Params.l2Code = static_cast<int32_t>(l2Code);
+        satelliteEphemeris.gpsL2Params.l2Flag = static_cast<int32_t>(l2Flag);
+        env->DeleteLocalRef(gpsL2ParamsObj);
+
+        // Set the satelliteClockModel of the satellite.
+        jobject satelliteClockModelObj =
+                env->CallObjectMethod(satelliteEphemerisObj,
+                                      method_gpsSatelliteEphemerisGetSatelliteClockModel);
+        jdouble af0 =
+                env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetAf0);
+        jdouble af1 =
+                env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetAf1);
+        jdouble af2 =
+                env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetAf2);
+        jdouble tgd =
+                env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetTgd);
+        jint iodc =
+                env->CallDoubleMethod(satelliteClockModelObj, method_gpsSatelliteClockModelGetIodc);
+        jlong timeOfClockSeconds =
+                env->CallLongMethod(satelliteClockModelObj,
+                                    method_gpsSatelliteClockModelGetTimeOfClockSeconds);
+        satelliteEphemeris.satelliteClockModel.af0 = af0;
+        satelliteEphemeris.satelliteClockModel.af1 = af1;
+        satelliteEphemeris.satelliteClockModel.af2 = af2;
+        satelliteEphemeris.satelliteClockModel.tgd = tgd;
+        satelliteEphemeris.satelliteClockModel.iodc = static_cast<int32_t>(iodc);
+        satelliteEphemeris.satelliteClockModel.timeOfClockSeconds = timeOfClockSeconds;
+        env->DeleteLocalRef(satelliteClockModelObj);
+
+        // Set the satelliteOrbitModel of the satellite.
+        jobject satelliteOrbitModelObj =
+                env->CallObjectMethod(satelliteEphemerisObj,
+                                      method_gpsSatelliteEphemerisGetSatelliteOrbitModel);
+        GnssAssistanceUtil::setKeplerianOrbitModel(env, satelliteOrbitModelObj,
+                                                   satelliteEphemeris.satelliteOrbitModel);
+        env->DeleteLocalRef(satelliteOrbitModelObj);
+
+        // Set the satelliteHealth of the satellite.
+        jobject satelliteHealthObj =
+                env->CallObjectMethod(satelliteEphemerisObj,
+                                      method_gpsSatelliteEphemerisGetSatelliteHealth);
+        jint svHealth =
+                env->CallIntMethod(satelliteHealthObj, method_gpsSatelliteHealthGetSvHealth);
+        jdouble svAccur =
+                env->CallDoubleMethod(satelliteHealthObj, method_gpsSatelliteHealthGetSvAccur);
+        jdouble fitInt = env->CallIntMethod(satelliteHealthObj, method_gpsSatelliteHealthGetFitInt);
+        satelliteEphemeris.satelliteHealth.svHealth = static_cast<int32_t>(svHealth);
+        satelliteEphemeris.satelliteHealth.svAccur = svAccur;
+        satelliteEphemeris.satelliteHealth.fitInt = fitInt;
+        env->DeleteLocalRef(satelliteHealthObj);
+
+        // Set the satelliteEphemerisTime of the satellite.
+        jobject satelliteEphemerisTimeObj =
+                env->CallObjectMethod(satelliteEphemerisObj,
+                                      method_gpsSatelliteEphemerisGetSatelliteEphemerisTime);
+        GnssAssistanceUtil::setSatelliteEphemerisTime(env, satelliteEphemerisTimeObj,
+                                                      satelliteEphemeris.satelliteEphemerisTime);
+        env->DeleteLocalRef(satelliteEphemerisTimeObj);
+
+        satelliteEphemerisList.push_back(satelliteEphemeris);
+        env->DeleteLocalRef(satelliteEphemerisObj);
+    }
+}
+
+void GnssAssistanceUtil::setSatelliteCorrections(
+        JNIEnv* env, jobject satelliteCorrectionsObj,
+        std::vector<GnssSatelliteCorrections>& gnssSatelliteCorrectionsList) {
+    if (satelliteCorrectionsObj == nullptr) return;
+    auto len = env->CallIntMethod(satelliteCorrectionsObj, method_listSize);
+    for (uint16_t i = 0; i < len; ++i) {
+        GnssSatelliteCorrections gnssSatelliteCorrections;
+        jobject satelliteCorrectionObj =
+                env->CallObjectMethod(satelliteCorrectionsObj, method_listGet, i);
+        if (satelliteCorrectionObj == nullptr) continue;
+        jint svid = env->CallIntMethod(satelliteCorrectionObj, method_satelliteCorrectionGetSvid);
+        gnssSatelliteCorrections.svid = svid;
+        jobject ionosphericCorrectionsObj =
+                env->CallObjectMethod(satelliteCorrectionObj,
+                                      method_satelliteCorrectionGetIonosphericCorrections);
+        env->DeleteLocalRef(satelliteCorrectionObj);
+        auto size = env->CallIntMethod(ionosphericCorrectionsObj, method_listSize);
+        for (uint16_t j = 0; j < size; ++j) {
+            jobject ionosphericCorrectionObj =
+                    env->CallObjectMethod(ionosphericCorrectionsObj, method_listGet, j);
+            if (ionosphericCorrectionObj == nullptr) continue;
+            IonosphericCorrection ionosphericCorrection;
+            jlong carrierFrequencyHz =
+                    env->CallLongMethod(ionosphericCorrectionObj,
+                                        method_ionosphericCorrectionGetCarrierFrequencyHz);
+            ionosphericCorrection.carrierFrequencyHz = carrierFrequencyHz;
+
+            jobject gnssCorrectionComponentObj =
+                    env->CallObjectMethod(ionosphericCorrectionObj,
+                                          method_ionosphericCorrectionGetIonosphericCorrection);
+            env->DeleteLocalRef(ionosphericCorrectionObj);
+
+            jstring sourceKey = static_cast<jstring>(
+                    env->CallObjectMethod(gnssCorrectionComponentObj,
+                                          method_gnssCorrectionComponentGetSourceKey));
+            ScopedJniString jniSourceKey{env, sourceKey};
+            ionosphericCorrection.ionosphericCorrectionComponent.sourceKey =
+                    android::String16(jniSourceKey.c_str());
+
+            jobject pseudorangeCorrectionObj =
+                    env->CallObjectMethod(gnssCorrectionComponentObj,
+                                          method_gnssCorrectionComponentGetPseudorangeCorrection);
+            jdouble correctionMeters =
+                    env->CallDoubleMethod(pseudorangeCorrectionObj,
+                                          method_pseudorangeCorrectionGetCorrectionMeters);
+            jdouble correctionUncertaintyMeters = env->CallDoubleMethod(
+                    pseudorangeCorrectionObj,
+                    method_pseudorangeCorrectionGetCorrectionUncertaintyMeters);
+            jdouble correctionRateMetersPerSecond = env->CallDoubleMethod(
+                    pseudorangeCorrectionObj,
+                    method_pseudorangeCorrectionGetCorrectionRateMetersPerSecond);
+            ionosphericCorrection.ionosphericCorrectionComponent.pseudorangeCorrection
+                    .correctionMeters = correctionMeters;
+            ionosphericCorrection.ionosphericCorrectionComponent.pseudorangeCorrection
+                    .correctionUncertaintyMeters = correctionUncertaintyMeters;
+            ionosphericCorrection.ionosphericCorrectionComponent.pseudorangeCorrection
+                    .correctionRateMetersPerSecond = correctionRateMetersPerSecond;
+            env->DeleteLocalRef(pseudorangeCorrectionObj);
+
+            jobject gnssIntervalObj =
+                    env->CallObjectMethod(gnssCorrectionComponentObj,
+                                          method_gnssCorrectionComponentGetValidityInterval);
+            jdouble startMillisSinceGpsEpoch =
+                    env->CallDoubleMethod(gnssIntervalObj,
+                                          method_gnssIntervalGetStartMillisSinceGpsEpoch);
+            jdouble endMillisSinceGpsEpoch =
+                    env->CallDoubleMethod(gnssIntervalObj,
+                                          method_gnssIntervalGetEndMillisSinceGpsEpoch);
+            ionosphericCorrection.ionosphericCorrectionComponent.validityInterval
+                    .startMillisSinceGpsEpoch = startMillisSinceGpsEpoch;
+            ionosphericCorrection.ionosphericCorrectionComponent.validityInterval
+                    .endMillisSinceGpsEpoch = endMillisSinceGpsEpoch;
+            env->DeleteLocalRef(gnssIntervalObj);
+
+            env->DeleteLocalRef(gnssCorrectionComponentObj);
+            gnssSatelliteCorrections.ionosphericCorrections.push_back(ionosphericCorrection);
+        }
+        gnssSatelliteCorrectionsList.push_back(gnssSatelliteCorrections);
+        env->DeleteLocalRef(ionosphericCorrectionsObj);
+    }
+}
+
+void GnssAssistanceUtil::setRealTimeIntegrityModels(
+        JNIEnv* env, jobject realTimeIntegrityModelsObj,
+        std::vector<RealTimeIntegrityModel>& realTimeIntegrityModels) {
+    if (realTimeIntegrityModelsObj == nullptr) return;
+    auto len = env->CallIntMethod(realTimeIntegrityModelsObj, method_listSize);
+    for (uint16_t i = 0; i < len; ++i) {
+        jobject realTimeIntegrityModelObj =
+                env->CallObjectMethod(realTimeIntegrityModelsObj, method_listGet, i);
+        if (realTimeIntegrityModelObj == nullptr) continue;
+        RealTimeIntegrityModel realTimeIntegrityModel;
+        jint badSvid = env->CallIntMethod(realTimeIntegrityModelObj,
+                                          method_realTimeIntegrityModelGetBadSvid);
+        jobject badSignalTypesObj =
+                env->CallObjectMethod(realTimeIntegrityModelObj,
+                                      method_realTimeIntegrityModelGetBadSignalTypes);
+        auto badSignalTypesSize = env->CallIntMethod(badSignalTypesObj, method_listSize);
+        for (uint16_t j = 0; j < badSignalTypesSize; ++j) {
+            GnssSignalType badSignalType;
+            jobject badSignalTypeObj = env->CallObjectMethod(badSignalTypesObj, method_listGet, j);
+            if (badSignalTypeObj != nullptr) {
+                setGnssSignalType(env, badSignalTypeObj, badSignalType);
+                realTimeIntegrityModel.badSignalTypes.push_back(badSignalType);
+                env->DeleteLocalRef(badSignalTypeObj);
+            }
+        }
+
+        jlong startDateSeconds =
+                env->CallLongMethod(realTimeIntegrityModelObj,
+                                    method_realTimeIntegrityModelGetStartDateSeconds);
+        jlong endDateSeconds = env->CallLongMethod(realTimeIntegrityModelObj,
+                                                   method_realTimeIntegrityModelGetEndDateSeconds);
+        jlong publishDateSeconds =
+                env->CallLongMethod(realTimeIntegrityModelObj,
+                                    method_realTimeIntegrityModelGetPublishDateSeconds);
+        jstring advisoryNumber = static_cast<jstring>(
+                env->CallObjectMethod(realTimeIntegrityModelObj,
+                                      method_realTimeIntegrityModelGetAdvisoryNumber));
+        ScopedJniString jniAdvisoryNumber{env, advisoryNumber};
+        jstring advisoryType = static_cast<jstring>(
+                env->CallObjectMethod(realTimeIntegrityModelObj,
+                                      method_realTimeIntegrityModelGetAdvisoryType));
+        ScopedJniString jniAdvisoryType{env, advisoryType};
+
+        realTimeIntegrityModel.badSvid = badSvid;
+        realTimeIntegrityModel.startDateSeconds = startDateSeconds;
+        realTimeIntegrityModel.endDateSeconds = endDateSeconds;
+        realTimeIntegrityModel.publishDateSeconds = publishDateSeconds;
+        realTimeIntegrityModel.advisoryNumber = android::String16(jniAdvisoryNumber.c_str());
+        realTimeIntegrityModel.advisoryType = android::String16(jniAdvisoryType.c_str());
+        realTimeIntegrityModels.push_back(realTimeIntegrityModel);
+        env->DeleteLocalRef(badSignalTypesObj);
+        env->DeleteLocalRef(realTimeIntegrityModelObj);
+    }
+}
+
+void GnssAssistanceUtil::setGnssSignalType(JNIEnv* env, jobject gnssSignalTypeObj,
+                                           GnssSignalType& gnssSignalType) {
+    if (gnssSignalTypeObj == nullptr) {
+        ALOGE("gnssSignalTypeObj is null");
+        return;
+    }
+    jint constellationType =
+            env->CallIntMethod(gnssSignalTypeObj, method_gnssSignalTypeGetConstellationType);
+    jdouble carrierFrequencyHz =
+            env->CallIntMethod(gnssSignalTypeObj, method_gnssSignalTypeGetCarrierFrequencyHz);
+    jstring codeType = static_cast<jstring>(
+            env->CallObjectMethod(gnssSignalTypeObj, method_gnssSignalTypeGetCodeType));
+    ScopedJniString jniCodeType{env, codeType};
+
+    gnssSignalType.constellation = static_cast<GnssConstellationType>(constellationType);
+    gnssSignalType.carrierFrequencyHz = static_cast<int32_t>(carrierFrequencyHz);
+    gnssSignalType.codeType = std::string(jniCodeType.c_str());
+}
+
+void GnssAssistanceUtil::setTimeModels(JNIEnv* env, jobject timeModelsObj,
+                                       std::vector<TimeModel>& timeModels) {
+    if (timeModelsObj == nullptr) return;
+    auto len = env->CallIntMethod(timeModelsObj, method_listSize);
+    for (uint16_t i = 0; i < len; ++i) {
+        jobject timeModelObj = env->CallObjectMethod(timeModelsObj, method_listGet, i);
+        TimeModel timeModel;
+        jint toGnss = env->CallIntMethod(timeModelObj, method_timeModelsGetToGnss);
+        jlong timeOfWeek = env->CallLongMethod(timeModelObj, method_timeModelsGetTimeOfWeek);
+        jint weekNumber = env->CallIntMethod(timeModelObj, method_timeModelsGetWeekNumber);
+        jdouble a0 = env->CallDoubleMethod(timeModelObj, method_timeModelsGetA0);
+        jdouble a1 = env->CallDoubleMethod(timeModelObj, method_timeModelsGetA1);
+        timeModel.toGnss = static_cast<GnssConstellationType>(toGnss);
+        timeModel.timeOfWeek = timeOfWeek;
+        timeModel.weekNumber = static_cast<int32_t>(weekNumber);
+        timeModel.a0 = a0;
+        timeModel.a1 = a1;
+        timeModels.push_back(timeModel);
+        env->DeleteLocalRef(timeModelObj);
+    }
+}
+
+void GnssAssistanceUtil::setLeapSecondsModel(JNIEnv* env, jobject leapSecondsModelObj,
+                                             LeapSecondsModel& leapSecondsModel) {
+    if (leapSecondsModelObj == nullptr) {
+        leapSecondsModel.leapSeconds = -1;
+        return;
+    }
+    jint dayNumberLeapSecondsFuture =
+            env->CallIntMethod(leapSecondsModelObj,
+                               method_leapSecondsModelGetDayNumberLeapSecondsFuture);
+    jint leapSeconds =
+            env->CallIntMethod(leapSecondsModelObj, method_leapSecondsModelGetLeapSeconds);
+    jint leapSecondsFuture =
+            env->CallIntMethod(leapSecondsModelObj, method_leapSecondsModelGetLeapSecondsFuture);
+    jint weekNumberLeapSecondsFuture =
+            env->CallIntMethod(leapSecondsModelObj,
+                               method_leapSecondsModelGetWeekNumberLeapSecondsFuture);
+    leapSecondsModel.dayNumberLeapSecondsFuture = static_cast<int32_t>(dayNumberLeapSecondsFuture);
+    leapSecondsModel.leapSeconds = static_cast<int32_t>(leapSeconds);
+    leapSecondsModel.leapSecondsFuture = static_cast<int32_t>(leapSecondsFuture);
+    leapSecondsModel.weekNumberLeapSecondsFuture =
+            static_cast<int32_t>(weekNumberLeapSecondsFuture);
+}
+
+void GnssAssistanceUtil::setSatelliteEphemerisTime(JNIEnv* env, jobject satelliteEphemerisTimeObj,
+                                                   SatelliteEphemerisTime& satelliteEphemerisTime) {
+    if (satelliteEphemerisTimeObj == nullptr) return;
+    jdouble iode =
+            env->CallDoubleMethod(satelliteEphemerisTimeObj, method_satelliteEphemerisTimeGetIode);
+    jdouble toeSeconds = env->CallDoubleMethod(satelliteEphemerisTimeObj,
+                                               method_satelliteEphemerisTimeGetToeSeconds);
+    jint weekNumber = env->CallIntMethod(satelliteEphemerisTimeObj,
+                                         method_satelliteEphemerisTimeGetWeekNumber);
+    satelliteEphemerisTime.iode = iode;
+    satelliteEphemerisTime.toeSeconds = toeSeconds;
+    satelliteEphemerisTime.weekNumber = weekNumber;
+}
+
+void GnssAssistanceUtil::setKeplerianOrbitModel(JNIEnv* env, jobject keplerianOrbitModelObj,
+                                                KeplerianOrbitModel& keplerianOrbitModel) {
+    if (keplerianOrbitModelObj == nullptr) return;
+    jdouble rootA =
+            env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetRootA);
+    jdouble eccentricity = env->CallDoubleMethod(keplerianOrbitModelObj,
+                                                 method_keplerianOrbitModelGetEccentricity);
+    jdouble m0 = env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetM0);
+    jdouble omega =
+            env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetOmega);
+    jdouble omegaDot =
+            env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetOmegaDot);
+    jdouble deltaN =
+            env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetDeltaN);
+    jdouble iDot = env->CallDoubleMethod(keplerianOrbitModelObj, method_keplerianOrbitModelGetIDot);
+    jobject secondOrderHarmonicPerturbationObj =
+            env->CallObjectMethod(keplerianOrbitModelObj,
+                                  method_keplerianOrbitModelGetSecondOrderHarmonicPerturbation);
+    jdouble cic = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj,
+                                        method_secondOrderHarmonicPerturbationGetCic);
+    jdouble cis = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj,
+                                        method_secondOrderHarmonicPerturbationGetCis);
+    jdouble crs = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj,
+                                        method_secondOrderHarmonicPerturbationGetCrs);
+    jdouble crc = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj,
+                                        method_secondOrderHarmonicPerturbationGetCrc);
+    jdouble cuc = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj,
+                                        method_secondOrderHarmonicPerturbationGetCuc);
+    jdouble cus = env->CallDoubleMethod(secondOrderHarmonicPerturbationObj,
+                                        method_secondOrderHarmonicPerturbationGetCus);
+    keplerianOrbitModel.rootA = rootA;
+    keplerianOrbitModel.eccentricity = eccentricity;
+    keplerianOrbitModel.m0 = m0;
+    keplerianOrbitModel.omega = omega;
+    keplerianOrbitModel.omegaDot = omegaDot;
+    keplerianOrbitModel.deltaN = deltaN;
+    keplerianOrbitModel.iDot = iDot;
+    keplerianOrbitModel.secondOrderHarmonicPerturbation.cic = cic;
+    keplerianOrbitModel.secondOrderHarmonicPerturbation.cis = cis;
+    keplerianOrbitModel.secondOrderHarmonicPerturbation.crs = crs;
+    keplerianOrbitModel.secondOrderHarmonicPerturbation.crc = crc;
+    keplerianOrbitModel.secondOrderHarmonicPerturbation.cuc = cuc;
+    keplerianOrbitModel.secondOrderHarmonicPerturbation.cus = cus;
+    env->DeleteLocalRef(secondOrderHarmonicPerturbationObj);
+}
+
+void GnssAssistanceUtil::setKlobucharIonosphericModel(
+        JNIEnv* env, jobject klobucharIonosphericModelObj,
+        KlobucharIonosphericModel& klobucharIonosphericModel) {
+    if (klobucharIonosphericModelObj == nullptr) return;
+    jdouble alpha0 = env->CallDoubleMethod(klobucharIonosphericModelObj,
+                                           method_klobucharIonosphericModelGetAlpha0);
+    jdouble alpha1 = env->CallDoubleMethod(klobucharIonosphericModelObj,
+                                           method_klobucharIonosphericModelGetAlpha1);
+    jdouble alpha2 = env->CallDoubleMethod(klobucharIonosphericModelObj,
+                                           method_klobucharIonosphericModelGetAlpha2);
+    jdouble alpha3 = env->CallDoubleMethod(klobucharIonosphericModelObj,
+                                           method_klobucharIonosphericModelGetAlpha3);
+    jdouble beta0 = env->CallDoubleMethod(klobucharIonosphericModelObj,
+                                          method_klobucharIonosphericModelGetBeta0);
+    jdouble beta1 = env->CallDoubleMethod(klobucharIonosphericModelObj,
+                                          method_klobucharIonosphericModelGetBeta1);
+    jdouble beta2 = env->CallDoubleMethod(klobucharIonosphericModelObj,
+                                          method_klobucharIonosphericModelGetBeta2);
+    jdouble beta3 = env->CallDoubleMethod(klobucharIonosphericModelObj,
+                                          method_klobucharIonosphericModelGetBeta3);
+    klobucharIonosphericModel.alpha0 = alpha0;
+    klobucharIonosphericModel.alpha1 = alpha1;
+    klobucharIonosphericModel.alpha2 = alpha2;
+    klobucharIonosphericModel.alpha3 = alpha3;
+    klobucharIonosphericModel.beta0 = beta0;
+    klobucharIonosphericModel.beta1 = beta1;
+    klobucharIonosphericModel.beta2 = beta2;
+    klobucharIonosphericModel.beta3 = beta3;
+}
+
+void GnssAssistanceUtil::setUtcModel(JNIEnv* env, jobject utcModelObj, UtcModel& utcModel) {
+    if (utcModelObj == nullptr) {
+        utcModel.weekNumber = -1;
+        return;
+    }
+    jdouble a0 = env->CallDoubleMethod(utcModelObj, method_utcModelGetA0);
+    jdouble a1 = env->CallDoubleMethod(utcModelObj, method_utcModelGetA1);
+    jlong timeOfWeek = env->CallLongMethod(utcModelObj, method_utcModelGetTimeOfWeek);
+    jint weekNumber = env->CallIntMethod(utcModelObj, method_utcModelGetWeekNumber);
+    utcModel.a0 = a0;
+    utcModel.a1 = a1;
+    utcModel.timeOfWeek = timeOfWeek;
+    utcModel.weekNumber = static_cast<int32_t>(weekNumber);
+}
+
+void GnssAssistanceUtil::setGnssAlmanac(JNIEnv* env, jobject gnssAlmanacObj,
+                                        GnssAlmanac& gnssAlmanac) {
+    if (gnssAlmanacObj == nullptr) {
+        gnssAlmanac.weekNumber = -1;
+        return;
+    }
+    jlong issueDateMillis =
+            env->CallLongMethod(gnssAlmanacObj, method_gnssAlmanacGetIssueDateMillis);
+    jint ioda = env->CallIntMethod(gnssAlmanacObj, method_gnssAlmanacGetIoda);
+    jint weekNumber = env->CallIntMethod(gnssAlmanacObj, method_gnssAlmanacGetWeekNumber);
+    jlong toaSeconds = env->CallLongMethod(gnssAlmanacObj, method_gnssAlmanacGetToaSeconds);
+    jboolean isCompleteAlmanacProvided =
+            env->CallBooleanMethod(gnssAlmanacObj, method_gnssAlmanacIsCompleteAlmanacProvided);
+    gnssAlmanac.issueDateMs = issueDateMillis;
+    gnssAlmanac.ioda = ioda;
+    gnssAlmanac.weekNumber = weekNumber;
+    gnssAlmanac.toaSeconds = toaSeconds;
+    gnssAlmanac.isCompleteAlmanacProvided = isCompleteAlmanacProvided;
+
+    jobject satelliteAlmanacsListObj =
+            env->CallObjectMethod(gnssAlmanacObj, method_gnssAlmanacGetSatelliteAlmanacs);
+    auto len = env->CallIntMethod(satelliteAlmanacsListObj, method_listSize);
+    std::vector<GnssSatelliteAlmanac> list(len);
+    for (uint16_t i = 0; i < len; ++i) {
+        jobject gnssSatelliteAlmanacObj =
+                env->CallObjectMethod(satelliteAlmanacsListObj, method_listGet, i);
+        if (gnssSatelliteAlmanacObj == nullptr) continue;
+        GnssSatelliteAlmanac gnssSatelliteAlmanac;
+        jint svid = env->CallIntMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetSvid);
+        jint svHealth =
+                env->CallIntMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetSvHealth);
+        jdouble af0 = env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetAf0);
+        jdouble af1 = env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetAf1);
+        jdouble eccentricity = env->CallDoubleMethod(gnssSatelliteAlmanacObj,
+                                                     method_satelliteAlmanacGetEccentricity);
+        jdouble inclination = env->CallDoubleMethod(gnssSatelliteAlmanacObj,
+                                                    method_satelliteAlmanacGetInclination);
+        jdouble m0 = env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetM0);
+        jdouble omega =
+                env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetOmega);
+        jdouble omega0 =
+                env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetOmega0);
+        jdouble omegaDot =
+                env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetOmegaDot);
+        jdouble rootA =
+                env->CallDoubleMethod(gnssSatelliteAlmanacObj, method_satelliteAlmanacGetRootA);
+        gnssSatelliteAlmanac.svid = static_cast<int32_t>(svid);
+        gnssSatelliteAlmanac.svHealth = static_cast<int32_t>(svHealth);
+        gnssSatelliteAlmanac.af0 = af0;
+        gnssSatelliteAlmanac.af1 = af1;
+        gnssSatelliteAlmanac.eccentricity = eccentricity;
+        gnssSatelliteAlmanac.inclination = inclination;
+        gnssSatelliteAlmanac.m0 = m0;
+        gnssSatelliteAlmanac.omega = omega;
+        gnssSatelliteAlmanac.omega0 = omega0;
+        gnssSatelliteAlmanac.omegaDot = omegaDot;
+        gnssSatelliteAlmanac.rootA = rootA;
+        list.at(i) = gnssSatelliteAlmanac;
+        env->DeleteLocalRef(gnssSatelliteAlmanacObj);
+    }
+    gnssAlmanac.satelliteAlmanacs = list;
+    env->DeleteLocalRef(satelliteAlmanacsListObj);
+}
+
+void GnssAssistanceUtil::setAuxiliaryInformation(JNIEnv* env, jobject auxiliaryInformationObj,
+                                                 AuxiliaryInformation& auxiliaryInformation) {
+    if (auxiliaryInformationObj == nullptr) {
+        auxiliaryInformation.svid = -1;
+        return;
+    }
+    jint svid = env->CallIntMethod(auxiliaryInformationObj, method_auxiliaryInformationGetSvid);
+    jobject availableSignalTypesObj =
+            env->CallObjectMethod(auxiliaryInformationObj,
+                                  method_auxiliaryInformationGetAvailableSignalTypes);
+    auto size = env->CallIntMethod(availableSignalTypesObj, method_listSize);
+    std::vector<GnssSignalType> availableSignalTypes(size);
+    for (uint16_t i = 0; i < size; ++i) {
+        jobject availableSignalTypeObj =
+                env->CallObjectMethod(availableSignalTypesObj, method_listGet, i);
+        GnssSignalType availableSignalType;
+        setGnssSignalType(env, availableSignalTypeObj, availableSignalType);
+        availableSignalTypes.at(i) = availableSignalType;
+        env->DeleteLocalRef(availableSignalTypeObj);
+    }
+    jint frequencyChannelNumber =
+            env->CallIntMethod(auxiliaryInformationObj,
+                               method_auxiliaryInformationGetFrequencyChannelNumber);
+    jint satType =
+            env->CallIntMethod(auxiliaryInformationObj, method_auxiliaryInformationGetSatType);
+    auxiliaryInformation.svid = static_cast<int32_t>(svid);
+    auxiliaryInformation.availableSignalTypes = availableSignalTypes;
+    auxiliaryInformation.frequencyChannelNumber = static_cast<int32_t>(frequencyChannelNumber);
+    auxiliaryInformation.satType = static_cast<BeidouB1CSatelliteOrbitType>(satType);
+    env->DeleteLocalRef(availableSignalTypesObj);
+}
+
+} // namespace android::gnss
diff --git a/services/core/jni/gnss/GnssAssistance.h b/services/core/jni/gnss/GnssAssistance.h
new file mode 100644
index 0000000..ee97e19
--- /dev/null
+++ b/services/core/jni/gnss/GnssAssistance.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_SERVER_GNSSASSITANCE_H
+#define _ANDROID_SERVER_GNSSASSITANCE_H
+
+#include <sys/stat.h>
+#pragma once
+
+#ifndef LOG_TAG
+#error LOG_TAG must be defined before including this file.
+#endif
+
+#include <android/hardware/gnss/gnss_assistance/BnGnssAssistanceInterface.h>
+#include <log/log.h>
+
+#include "GnssAssistanceCallback.h"
+#include "jni.h"
+
+namespace android::gnss {
+
+using IGnssAssistanceInterface = android::hardware::gnss::gnss_assistance::IGnssAssistanceInterface;
+using IGnssAssistanceCallback = android::hardware::gnss::gnss_assistance::IGnssAssistanceCallback;
+using BeidouAssistance = android::hardware::gnss::gnss_assistance::GnssAssistance::BeidouAssistance;
+using BeidouSatelliteEphemeris = android::hardware::gnss::gnss_assistance::BeidouSatelliteEphemeris;
+using GalileoAssistance =
+        android::hardware::gnss::gnss_assistance::GnssAssistance::GalileoAssistance;
+using GalileoSatelliteEphemeris =
+        android::hardware::gnss::gnss_assistance::GalileoSatelliteEphemeris;
+using GalileoIonosphericModel = android::hardware::gnss::gnss_assistance::GalileoIonosphericModel;
+using GlonassAssistance =
+        android::hardware::gnss::gnss_assistance::GnssAssistance::GlonassAssistance;
+using GlonassAlmanac = android::hardware::gnss::gnss_assistance::GlonassAlmanac;
+using GlonassSatelliteEphemeris =
+        android::hardware::gnss::gnss_assistance::GlonassSatelliteEphemeris;
+using GnssAssistance = android::hardware::gnss::gnss_assistance::GnssAssistance;
+using GnssSignalType = android::hardware::gnss::GnssSignalType;
+using GpsAssistance = android::hardware::gnss::gnss_assistance::GnssAssistance::GpsAssistance;
+using QzssAssistance = android::hardware::gnss::gnss_assistance::GnssAssistance::QzssAssistance;
+using GnssAlmanac = android::hardware::gnss::gnss_assistance::GnssAlmanac;
+using GnssSatelliteCorrections =
+        android::hardware::gnss::gnss_assistance::GnssAssistance::GnssSatelliteCorrections;
+using GpsSatelliteEphemeris = android::hardware::gnss::gnss_assistance::GpsSatelliteEphemeris;
+using SatelliteEphemerisTime = android::hardware::gnss::gnss_assistance::SatelliteEphemerisTime;
+using UtcModel = android::hardware::gnss::gnss_assistance::UtcModel;
+using LeapSecondsModel = android::hardware::gnss::gnss_assistance::LeapSecondsModel;
+using KeplerianOrbitModel = android::hardware::gnss::gnss_assistance::KeplerianOrbitModel;
+using KlobucharIonosphericModel =
+        android::hardware::gnss::gnss_assistance::KlobucharIonosphericModel;
+using TimeModel = android::hardware::gnss::gnss_assistance::TimeModel;
+using RealTimeIntegrityModel = android::hardware::gnss::gnss_assistance::RealTimeIntegrityModel;
+using AuxiliaryInformation = android::hardware::gnss::gnss_assistance::AuxiliaryInformation;
+
+void GnssAssistance_class_init_once(JNIEnv* env, jclass clazz);
+
+class GnssAssistanceInterface {
+public:
+    GnssAssistanceInterface(const sp<IGnssAssistanceInterface>& iGnssAssistance);
+    jboolean injectGnssAssistance(JNIEnv* env, jobject gnssAssistanceObj);
+    jboolean setCallback(const sp<IGnssAssistanceCallback>& callback);
+
+private:
+    const sp<IGnssAssistanceInterface> mGnssAssistanceInterface;
+};
+
+struct GnssAssistanceUtil {
+    static void setGlonassAssistance(JNIEnv* env, jobject glonassAssistanceObj,
+                                     GlonassAssistance& galileoAssistance);
+    static void setGlonassSatelliteEphemeris(
+            JNIEnv* env, jobject glonassSatelliteEphemerisObj,
+            std::vector<GlonassSatelliteEphemeris>& glonassSatelliteEphemerisList);
+    static void setGlonassAlmanac(JNIEnv* env, jobject glonassAlmanacObj,
+                                  GlonassAlmanac& glonassAlmanac);
+    static void setBeidouAssistance(JNIEnv* env, jobject beidouAssistanceObj,
+                                    BeidouAssistance& beidouAssistance);
+    static void setBeidouSatelliteEphemeris(
+            JNIEnv* env, jobject beidouSatelliteEphemerisObj,
+            std::vector<BeidouSatelliteEphemeris>& beidouSatelliteEphemerisList);
+    static void setGalileoAssistance(JNIEnv* env, jobject galileoAssistanceObj,
+                                     GalileoAssistance& galileoAssistance);
+    static void setGalileoSatelliteEphemeris(
+            JNIEnv* env, jobject galileoSatelliteEphemerisObj,
+            std::vector<GalileoSatelliteEphemeris>& galileoSatelliteEphemerisList);
+    static void setGaliloKlobucharIonosphericModel(JNIEnv* env, jobject galileoIonosphericModelObj,
+                                                   GalileoIonosphericModel& ionosphericModel);
+    static void setGnssAssistance(JNIEnv* env, jobject gnssAssistanceObj,
+                                  GnssAssistance& gnssAssistance);
+    static void setGpsAssistance(JNIEnv* env, jobject gpsAssistanceObj,
+                                 GpsAssistance& gpsAssistance);
+    template <class T>
+    static void setGpsOrQzssSatelliteEphemeris(JNIEnv* env, jobject satelliteEphemerisObj,
+                                               std::vector<T>& satelliteEphemeris);
+    static void setQzssAssistance(JNIEnv* env, jobject qzssAssistanceObj,
+                                  QzssAssistance& qzssAssistance);
+    static void setGnssAlmanac(JNIEnv* env, jobject gnssAlmanacObj, GnssAlmanac& gnssAlmanac);
+    static void setGnssSignalType(JNIEnv* env, jobject gnssSignalTypeObj,
+                                  GnssSignalType& gnssSignalType);
+    static void setKeplerianOrbitModel(JNIEnv* env, jobject keplerianOrbitModelObj,
+                                       KeplerianOrbitModel& keplerianOrbitModel);
+    static void setKlobucharIonosphericModel(JNIEnv* env, jobject klobucharIonosphericModelObj,
+                                             KlobucharIonosphericModel& klobucharIonosphericModel);
+    static void setTimeModels(JNIEnv* env, jobject timeModelsObj,
+                              std::vector<TimeModel>& timeModels);
+    static void setLeapSecondsModel(JNIEnv* env, jobject leapSecondsModelObj,
+                                    LeapSecondsModel& leapSecondsModel);
+    static void setRealTimeIntegrityModels(
+            JNIEnv* env, jobject realTimeIntegrityModelsObj,
+            std::vector<RealTimeIntegrityModel>& realTimeIntegrityModels);
+
+    static void setSatelliteEphemerisTime(JNIEnv* env, jobject satelliteEphemerisTimeObj,
+                                          SatelliteEphemerisTime& satelliteEphemerisTime);
+    static void setUtcModel(JNIEnv* env, jobject utcModelObj, UtcModel& utcModel);
+    static void setSatelliteCorrections(
+            JNIEnv* env, jobject satelliteCorrectionsObj,
+            std::vector<GnssSatelliteCorrections>& satelliteCorrections);
+    static void setAuxiliaryInformation(JNIEnv* env, jobject auxiliaryInformationObj,
+                                        AuxiliaryInformation& auxiliaryInformation);
+};
+
+} // namespace android::gnss
+
+#endif // _ANDROID_SERVER_GNSSASSITANCE__H
diff --git a/services/core/jni/gnss/GnssAssistanceCallback.cpp b/services/core/jni/gnss/GnssAssistanceCallback.cpp
new file mode 100644
index 0000000..dbb27d7
--- /dev/null
+++ b/services/core/jni/gnss/GnssAssistanceCallback.cpp
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "GnssAssistanceCbJni"
+
+#include "GnssAssistanceCallback.h"
+
+#include "Utils.h"
+
+namespace {
+jmethodID method_gnssAssistanceInjectRequest;
+} // anonymous namespace
+
+namespace android::gnss {
+
+using binder::Status;
+using hardware::Return;
+using hardware::Void;
+
+void GnssAssistanceCallback_class_init_once(JNIEnv* env, jclass clazz) {
+    method_gnssAssistanceInjectRequest =
+            env->GetStaticMethodID(clazz, "gnssAssistanceInjectRequest", "()V");
+}
+
+// Implementation of android::hardware::gnss::gnss_assistance::GnssAssistanceCallback.
+
+Status GnssAssistanceCallback::injectRequestCb() {
+    ALOGD("%s.", __func__);
+    JNIEnv* env = getJniEnv();
+    env->CallVoidMethod(mCallbacksObj, method_gnssAssistanceInjectRequest);
+    checkAndClearExceptionFromCallback(env, __FUNCTION__);
+    return Status::ok();
+}
+
+} // namespace android::gnss
diff --git a/services/core/jni/gnss/GnssAssistanceCallback.h b/services/core/jni/gnss/GnssAssistanceCallback.h
new file mode 100644
index 0000000..4c8c5fc
--- /dev/null
+++ b/services/core/jni/gnss/GnssAssistanceCallback.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _ANDROID_SERVER_GNSS_GNSSASSITANCECALLBACK_H
+#define _ANDROID_SERVER_GNSS_GNSSASSITANCECALLBACK_H
+
+#pragma once
+
+#ifndef LOG_TAG
+#error LOG_TAG must be defined before including this file.
+#endif
+
+#include <android/hardware/gnss/gnss_assistance/BnGnssAssistanceCallback.h>
+#include <log/log.h>
+
+#include "Utils.h"
+#include "jni.h"
+
+namespace android::gnss {
+
+void GnssAssistanceCallback_class_init_once(JNIEnv* env, jclass clazz);
+
+/*
+ * GnssAssistanceCallback class implements the callback methods required by the
+ * android::hardware::gnss::gnss_assistance::IGnssAssistanceCallback interface.
+ */
+class GnssAssistanceCallback : public hardware::gnss::gnss_assistance::BnGnssAssistanceCallback {
+public:
+    GnssAssistanceCallback() {}
+    binder::Status injectRequestCb() override;
+};
+
+} // namespace android::gnss
+
+#endif // _ANDROID_SERVER_GNSS_GNSSASSITANCECALLBACK_H
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index 42e457c..bc5c427 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -51,7 +51,6 @@
 import android.credentials.PrepareGetCredentialResponseInternal;
 import android.credentials.RegisterCredentialDescriptionRequest;
 import android.credentials.UnregisterCredentialDescriptionRequest;
-import android.credentials.flags.Flags;
 import android.os.Binder;
 import android.os.CancellationSignal;
 import android.os.IBinder;
@@ -538,34 +537,31 @@
 
             final int userId = UserHandle.getCallingUserId();
             final int callingUid = Binder.getCallingUid();
-            if (Flags.safeguardCandidateCredentialsApiCaller()) {
-                try {
-                    String credentialManagerAutofillCompName = mContext.getResources().getString(
-                            R.string.config_defaultCredentialManagerAutofillService);
-                    ComponentName componentName = ComponentName.unflattenFromString(
-                            credentialManagerAutofillCompName);
-                    if (componentName == null) {
-                        throw new SecurityException(
-                                "Credential Autofill service does not exist on this device.");
-                    }
-                    PackageManager pm = mContext.createContextAsUser(
-                            UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
-                    String callingProcessPackage = pm.getNameForUid(callingUid);
-                    if (callingProcessPackage == null) {
-                        throw new SecurityException(
-                                "Couldn't determine the identity of the caller.");
-                    }
-                    if (!Objects.equals(componentName.getPackageName(), callingProcessPackage)) {
-                        throw new SecurityException(callingProcessPackage
-                                + " is not the device's credential autofill package.");
-                    }
-                } catch (Resources.NotFoundException e) {
+            try {
+                String credentialManagerAutofillCompName = mContext.getResources().getString(
+                        R.string.config_defaultCredentialManagerAutofillService);
+                ComponentName componentName = ComponentName.unflattenFromString(
+                        credentialManagerAutofillCompName);
+                if (componentName == null) {
                     throw new SecurityException(
                             "Credential Autofill service does not exist on this device.");
                 }
+                PackageManager pm = mContext.createContextAsUser(
+                        UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager();
+                String callingProcessPackage = pm.getNameForUid(callingUid);
+                if (callingProcessPackage == null) {
+                    throw new SecurityException(
+                            "Couldn't determine the identity of the caller.");
+                }
+                if (!Objects.equals(componentName.getPackageName(), callingProcessPackage)) {
+                    throw new SecurityException(callingProcessPackage
+                            + " is not the device's credential autofill package.");
+                }
+            } catch (Resources.NotFoundException e) {
+                throw new SecurityException(
+                        "Credential Autofill service does not exist on this device.");
             }
 
-
             // New request session, scoped for this request only.
             final GetCandidateRequestSession session =
                     new GetCandidateRequestSession(
diff --git a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
index f6b107b..d60807c 100644
--- a/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/PrepareGetRequestSession.java
@@ -62,6 +62,8 @@
                         Collectors.toSet())).size(); // Dedupe type strings
         mRequestSessionMetric.collectGetFlowInitialMetricInfo(request);
         mPrepareGetCredentialCallback = prepareGetCredentialCallback;
+
+        Slog.i(TAG, "PrepareGetRequestSession constructed.");
     }
 
     @Override
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 51ed6bb..f055feb 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -276,6 +276,7 @@
 import static com.android.server.SystemTimeZone.TIME_ZONE_CONFIDENCE_HIGH;
 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
 import static com.android.server.devicepolicy.DevicePolicyEngine.DEFAULT_POLICY_SIZE_LIMIT;
+import static com.android.server.devicepolicy.DevicePolicyEngine.SYSTEM_SUPERVISION_ROLE;
 import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE;
 import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__COPE;
 import static com.android.server.devicepolicy.DevicePolicyStatsLog.DEVICE_POLICY_MANAGEMENT_MODE__MANAGEMENT_MODE__DEVICE_OWNER;
@@ -16296,6 +16297,13 @@
         return null;
     }
 
+    /**
+     * When multiple admins enforce a policy, this method returns an admin according to this order:
+     * 1. Supervision
+     * 2. DPC
+     *
+     * Otherwise, it returns any other admin.
+     */
     private android.app.admin.EnforcingAdmin getEnforcingAdminInternal(int userId,
             String identifier) {
         Objects.requireNonNull(identifier);
@@ -16304,16 +16312,22 @@
         if (admins.isEmpty()) {
             return null;
         }
-
-        final EnforcingAdmin admin;
         if (admins.size() == 1) {
-            admin = admins.iterator().next();
-        } else {
-            Optional<EnforcingAdmin> dpc = admins.stream()
-                    .filter(a -> a.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)).findFirst();
-            admin = dpc.orElseGet(() -> admins.stream().findFirst().get());
+            return admins.iterator().next().getParcelableAdmin();
         }
-        return admin == null ? null : admin.getParcelableAdmin();
+        Optional<EnforcingAdmin> supervision = admins.stream()
+                .filter(a -> a.hasAuthority(
+                        EnforcingAdmin.getRoleAuthorityOf(SYSTEM_SUPERVISION_ROLE)))
+                .findFirst();
+        if (supervision.isPresent()) {
+            return supervision.get().getParcelableAdmin();
+        }
+        Optional<EnforcingAdmin> dpc = admins.stream()
+                .filter(a -> a.hasAuthority(EnforcingAdmin.DPC_AUTHORITY)).findFirst();
+        if (dpc.isPresent()) {
+            return dpc.get().getParcelableAdmin();
+        }
+        return admins.iterator().next().getParcelableAdmin();
     }
 
     private <V> Set<EnforcingAdmin> getEnforcingAdminsForIdentifier(int userId, String identifier) {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
index 543e32f..9ff6eb6 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/PolicyDefinition.java
@@ -34,6 +34,7 @@
 import android.app.admin.PolicyKey;
 import android.app.admin.PolicyValue;
 import android.app.admin.UserRestrictionPolicyKey;
+import android.app.admin.flags.Flags;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.IntentFilter;
@@ -282,7 +283,9 @@
 
     static PolicyDefinition<Set<String>> PERMITTED_INPUT_METHODS = new PolicyDefinition<>(
             new NoArgsPolicyKey(DevicePolicyIdentifiers.PERMITTED_INPUT_METHODS_POLICY),
-            new MostRecent<>(),
+            (Flags.usePolicyIntersectionForPermittedInputMethods()
+                ? new StringSetIntersection()
+                : new MostRecent<>()),
             POLICY_FLAG_LOCAL_ONLY_POLICY | POLICY_FLAG_INHERITABLE,
             PolicyEnforcerCallbacks::noOp,
             new PackageSetPolicySerializer());
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/StringSetIntersection.java b/services/devicepolicy/java/com/android/server/devicepolicy/StringSetIntersection.java
new file mode 100644
index 0000000..bc075b02
--- /dev/null
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/StringSetIntersection.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2025 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES 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.devicepolicy;
+
+import android.annotation.NonNull;
+import android.app.admin.PolicyValue;
+import android.app.admin.PackageSetPolicyValue;
+
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.Objects;
+import java.util.Set;
+
+final class StringSetIntersection extends ResolutionMechanism<Set<String>> {
+
+    @Override
+    PolicyValue<Set<String>> resolve(
+            @NonNull LinkedHashMap<EnforcingAdmin, PolicyValue<Set<String>>> adminPolicies) {
+        Objects.requireNonNull(adminPolicies);
+        Set<String> intersectionOfPolicies = null;
+        for (PolicyValue<Set<String>> policy : adminPolicies.values()) {
+            if (intersectionOfPolicies == null) {
+                intersectionOfPolicies = new HashSet<>(policy.getValue());
+            } else {
+                intersectionOfPolicies.retainAll(policy.getValue());
+            }
+        }
+        if (intersectionOfPolicies == null) {
+            return null;
+        }
+        // Note that the resulting set below may be empty, but that's fine:
+        // particular policy should decide what is the meaning of an empty set.
+        return new PackageSetPolicyValue(intersectionOfPolicies);
+    }
+
+    @Override
+    android.app.admin.StringSetIntersection getParcelableResolutionMechanism() {
+        return new android.app.admin.StringSetIntersection();
+    }
+
+    @Override
+    public String toString() {
+        return "StringSetIntersection {}";
+    }
+}
diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java b/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java
index de78271..69e856d 100644
--- a/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java
+++ b/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java
@@ -325,7 +325,8 @@
             }
 
             if (newState != INVALID_DEVICE_STATE_IDENTIFIER && newState != mLastReportedState) {
-                if (Trace.isTagEnabled(TRACE_TAG_SYSTEM_SERVER)) {
+                if (mLastHingeAngleSensorEvent != null
+                        && Trace.isTagEnabled(TRACE_TAG_SYSTEM_SERVER)) {
                     Trace.instant(TRACE_TAG_SYSTEM_SERVER,
                             "[Device state changed] Last hinge sensor event timestamp: "
                                     + mLastHingeAngleSensorEvent.timestamp);
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
index 6adb01c..e898c833 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/UserDataRepositoryTest.java
@@ -18,7 +18,6 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.view.WindowManager;
 
 import androidx.annotation.NonNull;
@@ -28,7 +27,6 @@
 
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
@@ -42,10 +40,6 @@
 
     private static final int ANY_USER_ID = 1;
 
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true).build();
-
     @Mock
     private InputMethodManagerService mMockInputMethodManagerService;
 
diff --git a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
index 9117cc8..a38ecc8 100644
--- a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
+++ b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
@@ -3186,6 +3186,32 @@
         assertEquals(profile, ikev2VpnProfile.toVpnProfile());
     }
 
+    @Test
+    public void testStartAlwaysOnVpnOnSafeMode() throws Exception {
+        final Vpn vpn = createVpn(PRIMARY_USER.id);
+        setMockedUsers(PRIMARY_USER);
+
+        // UID checks must return a different UID; otherwise it'll be treated as already prepared.
+        final int uid = Process.myUid() + 1;
+        when(mPackageManager.getPackageUidAsUser(eq(TEST_VPN_PKG), anyInt()))
+                .thenReturn(uid);
+        when(mVpnProfileStore.get(vpn.getProfileNameForPackage(TEST_VPN_PKG)))
+                .thenReturn(mVpnProfile.encode());
+
+        setAndVerifyAlwaysOnPackage(vpn, uid, false);
+        assertTrue(vpn.startAlwaysOnVpn());
+        assertEquals(TEST_VPN_PKG, vpn.getAlwaysOnPackage());
+
+        // Simulate safe mode and restart the always-on VPN to verify the always-on package is not
+        // reset.
+        doReturn(null).when(mVpnProfileStore).get(vpn.getProfileNameForPackage(TEST_VPN_PKG));
+        doReturn(null).when(mPackageManager).queryIntentServicesAsUser(
+                any(), any(), eq(PRIMARY_USER.id));
+        doReturn(true).when(mPackageManager).isSafeMode();
+        assertFalse(vpn.startAlwaysOnVpn());
+        assertEquals(TEST_VPN_PKG, vpn.getAlwaysOnPackage());
+    }
+
     // Make it public and un-final so as to spy it
     public class TestDeps extends Vpn.Dependencies {
         TestDeps() {}
diff --git a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java
index 29f0722..fecbc7c8 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/DisplayPowerProximityStateControllerTest.java
@@ -25,7 +25,7 @@
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.hardware.Sensor;
@@ -396,7 +396,7 @@
         assertTrue(mDisplayPowerProximityStateController.isProximitySensorEnabled());
         assertFalse(mDisplayPowerProximityStateController.shouldIgnoreProximityUntilChanged());
         assertFalse(mDisplayPowerProximityStateController.isScreenOffBecauseOfProximity());
-        verifyZeroInteractions(mWakelockController);
+        verifyNoMoreInteractions(mWakelockController);
     }
 
     private void setScreenOffBecauseOfPositiveProximityState() {
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 f8b4113..b8a5f34 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -234,6 +234,7 @@
 
         doReturn(true).when(mFlags).isDisplayOffloadEnabled();
         doReturn(true).when(mFlags).isEvenDimmerEnabled();
+        doReturn(true).when(mFlags).isDisplayContentModeManagementEnabled();
         initDisplayOffloadSession();
     }
 
@@ -1468,6 +1469,103 @@
         assertFalse(mDisplayOffloadSession.isActive());
     }
 
+    @Test
+    public void testAllowsContentSwitch_firstDisplay() throws Exception {
+        // Set up a first display
+        setUpDisplay(new FakeDisplay(PORT_A));
+        updateAvailableDisplays();
+        mAdapter.registerLocked();
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+        // The first display should be allowed to use the content mode switch
+        DisplayDevice firstDisplayDevice = mListener.addedDisplays.get(0);
+        assertTrue((firstDisplayDevice.getDisplayDeviceInfoLocked().flags
+                & DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH) != 0);
+    }
+
+    @Test
+    public void testAllowsContentSwitch_secondaryDisplayPublicAndNotShouldShowOwnContent()
+            throws Exception {
+        // Set up a first display and a secondary display
+        setUpDisplay(new FakeDisplay(PORT_A));
+        setUpDisplay(new FakeDisplay(PORT_B));
+        updateAvailableDisplays();
+
+        // Set the secondary display to be a public display
+        doReturn(new int[0]).when(mMockedResources)
+                .getIntArray(com.android.internal.R.array.config_localPrivateDisplayPorts);
+        // Disable FLAG_OWN_CONTENT_ONLY for the secondary display
+        doReturn(true).when(mMockedResources)
+                .getBoolean(com.android.internal.R.bool.config_localDisplaysMirrorContent);
+        mAdapter.registerLocked();
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+        // This secondary display should be allowed to use the content mode switch
+        DisplayDevice secondaryDisplayDevice = mListener.addedDisplays.get(1);
+        assertTrue((secondaryDisplayDevice.getDisplayDeviceInfoLocked().flags
+                & DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH) != 0);
+    }
+
+    @Test
+    public void testAllowsContentSwitch_privateDisplay() throws Exception {
+        // Set up a first display and a secondary display
+        setUpDisplay(new FakeDisplay(PORT_A));
+        setUpDisplay(new FakeDisplay(PORT_B));
+        updateAvailableDisplays();
+
+        // Set the secondary display to be a private display
+        doReturn(new int[]{ PORT_B }).when(mMockedResources)
+                .getIntArray(com.android.internal.R.array.config_localPrivateDisplayPorts);
+        mAdapter.registerLocked();
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+        // The private display should not be allowed to use the content mode switch
+        DisplayDevice secondaryDisplayDevice = mListener.addedDisplays.get(1);
+        assertTrue((secondaryDisplayDevice.getDisplayDeviceInfoLocked().flags
+                & DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH) == 0);
+    }
+
+    @Test
+    public void testAllowsContentSwitch_ownContentOnlyDisplay() throws Exception {
+        // Set up a first display and a secondary display
+        setUpDisplay(new FakeDisplay(PORT_A));
+        setUpDisplay(new FakeDisplay(PORT_B));
+        updateAvailableDisplays();
+
+        // Enable FLAG_OWN_CONTENT_ONLY for the secondary display
+        doReturn(false).when(mMockedResources)
+                .getBoolean(com.android.internal.R.bool.config_localDisplaysMirrorContent);
+        mAdapter.registerLocked();
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+        // The secondary display with FLAG_OWN_CONTENT_ONLY enabled should not be allowed to use the
+        // content mode switch
+        DisplayDevice secondaryDisplayDevice = mListener.addedDisplays.get(1);
+        assertTrue((secondaryDisplayDevice.getDisplayDeviceInfoLocked().flags
+                & DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH) == 0);
+    }
+
+    @Test
+    public void testAllowsContentSwitch_flagShouldShowSystemDecorations() throws Exception {
+        // Set up a display
+        FakeDisplay display = new FakeDisplay(PORT_A);
+        setUpDisplay(display);
+        updateAvailableDisplays();
+
+        mAdapter.registerLocked();
+        waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
+
+        // Display with FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS enabled should not be allowed to use the
+        // content mode switch
+        DisplayDevice displayDevice = mListener.addedDisplays.get(0);
+        int flags = displayDevice.getDisplayDeviceInfoLocked().flags;
+        boolean allowsContentModeSwitch =
+                ((flags & DisplayDeviceInfo.FLAG_ALLOWS_CONTENT_MODE_SWITCH) != 0);
+        boolean shouldShowSystemDecorations =
+                ((flags & DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0);
+        assertFalse(allowsContentModeSwitch && shouldShowSystemDecorations);
+    }
+
     private void initDisplayOffloadSession() {
         when(mDisplayOffloader.startOffload()).thenReturn(true);
         when(mDisplayOffloader.allowAutoBrightnessInDoze()).thenReturn(true);
diff --git a/services/tests/displayservicetests/src/com/android/server/display/WakelockControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/WakelockControllerTest.java
index 019b70e..f067fa1 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/WakelockControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/WakelockControllerTest.java
@@ -21,7 +21,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.hardware.display.DisplayManagerInternal;
 
@@ -210,7 +210,7 @@
 
         // Validate one suspend blocker was released
         assertFalse(mWakelockController.isProximityPositiveAcquired());
-        verifyZeroInteractions(mDisplayPowerCallbacks);
+        verifyNoMoreInteractions(mDisplayPowerCallbacks);
     }
 
     @Test
@@ -238,7 +238,7 @@
 
         // Validate one suspend blocker was released
         assertFalse(mWakelockController.isProximityNegativeAcquired());
-        verifyZeroInteractions(mDisplayPowerCallbacks);
+        verifyNoMoreInteractions(mDisplayPowerCallbacks);
     }
 
     @Test
@@ -265,7 +265,7 @@
 
         // Validate one suspend blocker was released
         assertFalse(mWakelockController.isOnStateChangedPending());
-        verifyZeroInteractions(mDisplayPowerCallbacks);
+        verifyNoMoreInteractions(mDisplayPowerCallbacks);
     }
 
     @Test
diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
index 49de801..bf05439 100644
--- a/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
+++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/DisplayBrightnessControllerTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -422,7 +421,7 @@
         mDisplayBrightnessController.setAutomaticBrightnessController(
                 automaticBrightnessController);
         assertEquals(brightness, mDisplayBrightnessController.getCurrentBrightness(), 0.01f);
-        verifyZeroInteractions(automaticBrightnessController);
+        verifyNoMoreInteractions(automaticBrightnessController);
         verify(mBrightnessSetting, never()).getBrightnessNitsForDefaultDisplay();
         verify(mBrightnessSetting, never()).setBrightnessNoNotify(brightness);
     }
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index d79d884..f0e61ec 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -109,7 +109,7 @@
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.Manifest;
 import android.app.ActivityManager;
@@ -3724,8 +3724,8 @@
         setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, 0);
 
         mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
-        verifyZeroInteractions(mPackageManagerInternal);
-        verifyZeroInteractions(mService.mHandler);
+        verifyNoMoreInteractions(mPackageManagerInternal);
+        verifyNoMoreInteractions(mService.mHandler);
     }
 
     private void testTemporaryQuota_bumpedAfterDeferral(int standbyBucket) throws Exception {
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
index 7dab1c8..859d2d2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmStoreTest.java
@@ -30,7 +30,7 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.app.AlarmManager;
 import android.app.PendingIntent;
@@ -244,7 +244,7 @@
         addAlarmsToStore(simpleAlarm, alarmClock);
 
         mAlarmStore.remove(simpleAlarm::equals);
-        verifyZeroInteractions(onRemoved);
+        verifyNoMoreInteractions(onRemoved);
 
         mAlarmStore.remove(alarmClock::equals);
         verify(onRemoved).run();
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 35ab2d2..acc06d0 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -74,7 +74,6 @@
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.Manifest;
 import android.app.ActivityManager;
@@ -584,7 +583,7 @@
             if (app.uid == uidRec.getUid() && expectedBlockState == NETWORK_STATE_BLOCK) {
                 verify(app.getThread()).setNetworkBlockSeq(uidRec.curProcStateSeq);
             } else {
-                verifyZeroInteractions(app.getThread());
+                verifyNoMoreInteractions(app.getThread());
             }
             Mockito.reset(app.getThread());
         }
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
index e678acc..3289d70b 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/ApplicationStartInfoTest.java
@@ -21,6 +21,7 @@
 import static com.android.server.am.ActivityManagerService.Injector;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
@@ -625,6 +626,121 @@
         assertTrue(startInfo.equals(startInfoFromParcel));
     }
 
+    /** Test that new timestamps are added to the correct record (the most recently created one). */
+    @Test
+    public void testTimestampAddedToCorrectRecord() throws Exception {
+        // Use a different start timestamp for each record so we can identify which was added to.
+        final long startTimeRecord1 = 123L;
+        final long startTimeRecord2 = 456L;
+
+        final long forkTime = 789L;
+
+        // Create a process record to use with all starts.
+        ProcessRecord app = makeProcessRecord(
+                APP_1_PID_1,                     // pid
+                APP_1_UID,                       // uid
+                APP_1_UID,                       // packageUid
+                null,                            // definingUid
+                APP_1_PROCESS_NAME,              // processName
+                APP_1_PACKAGE_NAME);             // packageName
+
+        // Trigger a start info record.
+        mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord1, app,
+                buildIntent(COMPONENT), false /* isAlarm */);
+
+        // Wait at least 1 ms for monotonic time to increase.
+        sleep(1);
+
+        // Verify the record was added successfully.
+        ArrayList<ApplicationStartInfo> list = new ArrayList<ApplicationStartInfo>();
+        mAppStartInfoTracker.getStartInfo(null, APP_1_UID, 0, 0, list);
+        assertEquals(1, list.size());
+        assertEquals(startTimeRecord1, list.get(0).getStartupTimestamps().get(0).longValue());
+
+        // Now trigger another start info record.
+        mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord2, app,
+                buildIntent(COMPONENT), false /* isAlarm */);
+
+        // Add a timestamp to the most recent record.
+        mAppStartInfoTracker.addTimestampToStart(
+                app, forkTime, ApplicationStartInfo.START_TIMESTAMP_FORK);
+
+        // Verify the record was added successfully.
+        list.clear();
+        mAppStartInfoTracker.getStartInfo(null, APP_1_UID, 0, 0, list);
+        assertEquals(2, list.size());
+        assertEquals(startTimeRecord2, list.get(0).getStartupTimestamps().get(0).longValue());
+        assertEquals(startTimeRecord1, list.get(1).getStartupTimestamps().get(0).longValue());
+
+        // Verify that the new timestamp is set correctly on the 2nd record that was added and not
+        // on the first.
+        assertEquals(forkTime, list.get(0).getStartupTimestamps()
+                .get(ApplicationStartInfo.START_TIMESTAMP_FORK).longValue());
+        assertFalse(list.get(1).getStartupTimestamps().containsKey(
+                ApplicationStartInfo.START_TIMESTAMP_FORK));
+    }
+
+    /**
+     * Test that cleanup old records works as expected, removing records that are older than the max
+     * retention length.
+     */
+    @Test
+    @EnableFlags(android.app.Flags.FLAG_APP_START_INFO_CLEANUP_OLD_RECORDS)
+    public void testOldRecordsCleanup() throws Exception {
+        // Use a different start timestamp for each record so we can identify which was removed.
+        // This timestamp is not used for ordering and has no impact on removal.
+        final long startTimeRecord1 = 123L;
+        final long startTimeRecord2 = 456L;
+        final long startTimeRecord3 = 789L;
+
+        // Create a process record to use with all starts.
+        ProcessRecord app = makeProcessRecord(
+                APP_1_PID_1,                     // pid
+                APP_1_UID,                       // uid
+                APP_1_UID,                       // packageUid
+                null,                            // definingUid
+                APP_1_PROCESS_NAME,              // processName
+                APP_1_PACKAGE_NAME);             // packageName
+
+        // Set monotonic time to 1, and then trigger a start info record.
+        doReturn(1L).when(mAppStartInfoTracker).getMonotonicTimeMs();
+        mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord1, app,
+                buildIntent(COMPONENT), false /* isAlarm */);
+
+        // Set monotonic time to 2, and then trigger another start info record.
+        doReturn(2L).when(mAppStartInfoTracker).getMonotonicTimeMs();
+        mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord2, app,
+                buildIntent(COMPONENT), false /* isAlarm */);
+
+        // Set monotonic time to 3, then trigger another start info record.
+        doReturn(3L).when(mAppStartInfoTracker).getMonotonicTimeMs();
+        mAppStartInfoTracker.handleProcessBroadcastStart(startTimeRecord3, app,
+                buildIntent(COMPONENT), false /* isAlarm */);
+
+        // Verify that all 3 records were added successfully.
+        ArrayList<ApplicationStartInfo> list = new ArrayList<ApplicationStartInfo>();
+        mAppStartInfoTracker.getStartInfo(null, APP_1_UID, 0, 0, list);
+        assertEquals(3, list.size());
+        assertEquals(startTimeRecord3, list.get(0).getStartupTimestamps().get(0).longValue());
+        assertEquals(startTimeRecord2, list.get(1).getStartupTimestamps().get(0).longValue());
+        assertEquals(startTimeRecord1, list.get(2).getStartupTimestamps().get(0).longValue());
+
+        // Set monotonic time to max history length + 3 so that the older 2 records will be removed
+        // but that newest 1 will remain.
+        doReturn(AppStartInfoTracker.APP_START_INFO_HISTORY_LENGTH_MS + 3L)
+                .when(mAppStartInfoTracker).getMonotonicTimeMs();
+
+        // Trigger a persist which will trigger the cleanup of old records.
+        mAppStartInfoTracker.persistProcessStartInfo();
+
+        // Now verify that the records older than max were removed, and that the records not older
+        // remain.
+        list.clear();
+        mAppStartInfoTracker.getStartInfo(null, APP_1_UID, 0, 0, list);
+        assertEquals(1, list.size());
+        assertEquals(startTimeRecord3, list.get(0).getStartupTimestamps().get(0).longValue());
+    }
+
     private static <T> void setFieldValue(Class clazz, Object obj, String fieldName, T val) {
         try {
             Field field = clazz.getDeclaredField(fieldName);
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 e094111..773114e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -74,6 +74,10 @@
 import static com.android.server.am.ProcessList.SERVICE_B_ADJ;
 import static com.android.server.am.ProcessList.UNKNOWN_ADJ;
 import static com.android.server.am.ProcessList.VISIBLE_APP_ADJ;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING;
+import static com.android.server.wm.WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -544,7 +548,7 @@
                 MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
         WindowProcessController wpc = app.getWindowProcessController();
         doReturn(true).when(wpc).hasActivities();
-        doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE)
+        doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE)
                 .when(wpc).getActivityStateFlags();
         setWakefulness(PowerManagerInternal.WAKEFULNESS_AWAKE);
         updateOomAdj(app);
@@ -553,28 +557,58 @@
         assertFalse(app.mState.isCached());
         assertFalse(app.mState.isEmpty());
         assertEquals("vis-activity", app.mState.getAdjType());
+        assertCpuTime(app);
 
-        doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+        doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE
                 | WindowProcessController.ACTIVITY_STATE_FLAG_RESUMED_SPLIT_SCREEN)
                 .when(wpc).getActivityStateFlags();
         updateOomAdj(app);
         assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP);
         assertEquals("resumed-split-screen-activity", app.mState.getAdjType());
+        assertCpuTime(app);
 
-        doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+        doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE
                 | WindowProcessController.ACTIVITY_STATE_FLAG_PERCEPTIBLE_FREEFORM)
                 .when(wpc).getActivityStateFlags();
         updateOomAdj(app);
         assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ, SCHED_GROUP_TOP_APP);
         assertEquals("perceptible-freeform-activity", app.mState.getAdjType());
+        assertCpuTime(app);
 
-        doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE
+        doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE
                 | WindowProcessController.ACTIVITY_STATE_FLAG_VISIBLE_MULTI_WINDOW_MODE)
                 .when(wpc).getActivityStateFlags();
         updateOomAdj(app);
         assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ,
                 SCHED_GROUP_FOREGROUND_WINDOW);
         assertEquals("vis-multi-window-activity", app.mState.getAdjType());
+        assertCpuTime(app);
+    }
+    @SuppressWarnings("GuardedBy")
+    @Test
+    public void testUpdateOomAdj_DoOne_PausingStoppingActivities() {
+        ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
+                MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
+        WindowProcessController wpc = app.getWindowProcessController();
+        doReturn(true).when(wpc).hasActivities();
+        doReturn(ACTIVITY_STATE_FLAG_IS_PAUSING_OR_PAUSED).when(wpc).getActivityStateFlags();
+        setWakefulness(PowerManagerInternal.WAKEFULNESS_AWAKE);
+        updateOomAdj(app);
+        assertProcStates(app, PROCESS_STATE_TOP, PERCEPTIBLE_APP_ADJ, SCHED_GROUP_DEFAULT,
+                "pause-activity");
+        assertCpuTime(app);
+
+        doReturn(ACTIVITY_STATE_FLAG_IS_STOPPING).when(wpc).getActivityStateFlags();
+        updateOomAdj(app);
+        assertProcStates(app, PROCESS_STATE_LAST_ACTIVITY, PERCEPTIBLE_APP_ADJ,
+                SCHED_GROUP_BACKGROUND, "stop-activity");
+        assertCpuTime(app);
+
+        doReturn(ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING).when(wpc).getActivityStateFlags();
+        updateOomAdj(app);
+        assertProcStates(app, PROCESS_STATE_CACHED_ACTIVITY, CACHED_APP_MIN_ADJ,
+                SCHED_GROUP_BACKGROUND, "cch-act");
+        assertNoCpuTime(app);
     }
 
     @SuppressWarnings("GuardedBy")
@@ -750,7 +784,8 @@
         ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID,
                 MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true));
         WindowProcessController wpc = app.getWindowProcessController();
-        doReturn(true).when(wpc).hasVisibleActivities();
+        doReturn(true).when(wpc).hasActivities();
+        doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE).when(wpc).getActivityStateFlags();
 
         final ProcessRecord app2 = spy(makeDefaultProcessRecord(MOCKAPP2_PID, MOCKAPP2_UID,
                 MOCKAPP2_PROCESSNAME, MOCKAPP2_PACKAGENAME, false));
@@ -3483,12 +3518,14 @@
         // EXPECT: stale-perceptible-act adjustment
         doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_STOPPING_FINISHING)
                 .when(wpc).getActivityStateFlags();
+        assertNoCpuTime(app);
 
         doReturn(now - OomAdjuster.PERCEPTIBLE_TASK_TIMEOUT_MILLIS).when(
                 wpc).getPerceptibleTaskStoppedTimeMillis();
         updateOomAdj(app);
         assertProcStates(app, PROCESS_STATE_LAST_ACTIVITY, PREVIOUS_APP_ADJ,
                 SCHED_GROUP_BACKGROUND, "stale-perceptible-act");
+        assertNoCpuTime(app);
 
         // GIVEN: perceptible adjustment is is disabled
         // EXPECT: no perceptible adjustment
@@ -3498,15 +3535,17 @@
         updateOomAdj(app);
         assertProcStates(app, PROCESS_STATE_CACHED_ACTIVITY, CACHED_APP_MIN_ADJ,
                 SCHED_GROUP_BACKGROUND, "cch-act");
+        assertNoCpuTime(app);
 
         // GIVEN: perceptible app is in foreground
         // EXPECT: no perceptible adjustment
-        doReturn(WindowProcessController.ACTIVITY_STATE_FLAG_IS_VISIBLE)
+        doReturn(ACTIVITY_STATE_FLAG_IS_VISIBLE)
                 .when(wpc).getActivityStateFlags();
         doReturn(now).when(wpc).getPerceptibleTaskStoppedTimeMillis();
         updateOomAdj(app);
         assertProcStates(app, PROCESS_STATE_TOP, VISIBLE_APP_ADJ,
                 SCHED_GROUP_DEFAULT, "vis-activity");
+        assertCpuTime(app);
     }
 
     @SuppressWarnings("GuardedBy")
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
index ae0452a..b7087c7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/FullBackupUtilsTest.java
@@ -21,7 +21,7 @@
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.os.ParcelFileDescriptor;
 import android.platform.test.annotations.Presubmit;
@@ -105,7 +105,7 @@
         } catch (EOFException expected) {
         }
 
-        verifyZeroInteractions(mOutputStreamMock);
+        verifyNoMoreInteractions(mOutputStreamMock);
         assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
     }
 
@@ -126,7 +126,7 @@
         } catch (EOFException expected) {
         }
 
-        verifyZeroInteractions(mOutputStreamMock);
+        verifyNoMoreInteractions(mOutputStreamMock);
         assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
     }
 
@@ -141,7 +141,7 @@
 
         FullBackupUtils.routeSocketDataToOutput(mTemporaryFileDescriptor, mOutputStreamMock);
 
-        verifyZeroInteractions(mOutputStreamMock);
+        verifyNoMoreInteractions(mOutputStreamMock);
         assertThat(mTemporaryFileDescriptor.getFileDescriptor().valid()).isTrue();
     }
 
diff --git a/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java b/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
index bf7e3a0..346d5f7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/backup/utils/TarBackupReaderTest.java
@@ -32,7 +32,6 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.internal.verification.VerificationModeFactory.times;
 
 import android.app.backup.IBackupManagerMonitor;
@@ -239,7 +238,7 @@
                 mMockPackageManagerInternal, mUserId, mContext);
 
         assertThat(policy).isEqualTo(RestorePolicy.IGNORE);
-        verifyZeroInteractions(mBackupManagerMonitorMock);
+        verifyNoMoreInteractions(mBackupManagerMonitorMock);
     }
 
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 8c09f26..fdf78ad 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -56,12 +56,12 @@
 import android.app.AppGlobals;
 import android.app.IActivityManager;
 import android.app.UiModeManager;
+import android.app.compat.CompatChanges;
 import android.app.job.JobInfo;
 import android.app.job.JobParameters;
 import android.app.job.JobScheduler;
 import android.app.job.JobWorkItem;
 import android.app.usage.UsageStatsManagerInternal;
-import android.compat.testing.PlatformCompatChangeRule;
 import android.content.ComponentName;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -81,6 +81,7 @@
 import android.os.Looper;
 import android.os.Process;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.WorkSource;
 import android.os.WorkSource.WorkChain;
@@ -98,6 +99,7 @@
 import com.android.server.LocalServices;
 import com.android.server.PowerAllowlistInternal;
 import com.android.server.SystemServiceManager;
+import com.android.server.compat.PlatformCompat;
 import com.android.server.job.controllers.ConnectivityController;
 import com.android.server.job.controllers.JobStatus;
 import com.android.server.job.controllers.QuotaController;
@@ -106,14 +108,10 @@
 import com.android.server.pm.UserManagerInternal;
 import com.android.server.usage.AppStandbyInternal;
 
-import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.junit.rules.TestRule;
 import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
@@ -147,9 +145,6 @@
     @Rule
     public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule();
 
-    @Rule
-    public TestRule compatChangeRule = new PlatformCompatChangeRule();
-
     private ChargingPolicyChangeListener mChargingPolicyChangeListener;
 
     private int mSourceUid;
@@ -166,8 +161,10 @@
         mMockingSession = mockitoSession()
                 .initMocks(this)
                 .strictness(Strictness.LENIENT)
+                .mockStatic(CompatChanges.class)
                 .mockStatic(LocalServices.class)
                 .mockStatic(PermissionChecker.class)
+                .mockStatic(ServiceManager.class)
                 .startMocking();
 
         // Called in JobSchedulerService constructor.
@@ -230,6 +227,9 @@
         ArgumentCaptor<ChargingPolicyChangeListener> chargingPolicyChangeListenerCaptor =
                 ArgumentCaptor.forClass(ChargingPolicyChangeListener.class);
 
+        doReturn(mock(PlatformCompat.class))
+                .when(() -> ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
+
         mService = new TestJobSchedulerService(mContext);
         mService.waitOnAsyncLoadingForTesting();
 
@@ -1074,12 +1074,15 @@
      */
     @Test
     @EnableFlags(FLAG_HANDLE_ABANDONED_JOBS)
-    @DisableCompatChanges({JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS})
     public void testGetRescheduleJobForFailure_abandonedJob() {
         final long nowElapsed = sElapsedRealtimeClock.millis();
         final long initialBackoffMs = MINUTE_IN_MILLIS;
         mService.mConstants.SYSTEM_STOP_TO_FAILURE_RATIO = 3;
 
+        // Mock the OVERRIDE_HANDLE_ABANDONED_JOBS compat change overrides.
+        when(CompatChanges.isChangeEnabled(
+                eq(JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS), anyInt())).thenReturn(false);
+
         JobStatus originalJob = createJobStatus("testGetRescheduleJobForFailure",
                 createJobInfo()
                         .setBackoffCriteria(initialBackoffMs, JobInfo.BACKOFF_POLICY_LINEAR));
@@ -1148,8 +1151,10 @@
      */
     @Test
     @EnableFlags(FLAG_HANDLE_ABANDONED_JOBS)
-    @DisableCompatChanges({JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS})
     public void testGetRescheduleJobForFailure_EnableFlagDisableCompatCheckAggressiveBackoff() {
+        // Mock the OVERRIDE_HANDLE_ABANDONED_JOBS compat change overrides.
+        when(CompatChanges.isChangeEnabled(
+                eq(JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS), anyInt())).thenReturn(false);
         assertFalse(mService.shouldUseAggressiveBackoff(
                         mService.mConstants.ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF - 1,
                         mSourceUid));
@@ -1167,8 +1172,10 @@
      */
     @Test
     @EnableFlags(FLAG_HANDLE_ABANDONED_JOBS)
-    @EnableCompatChanges({JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS})
     public void testGetRescheduleJobForFailure_EnableFlagEnableCompatCheckAggressiveBackoff() {
+        // Mock the OVERRIDE_HANDLE_ABANDONED_JOBS compat change overrides.
+        when(CompatChanges.isChangeEnabled(
+                eq(JobParameters.OVERRIDE_HANDLE_ABANDONED_JOBS), anyInt())).thenReturn(true);
         assertFalse(mService.shouldUseAggressiveBackoff(
                         mService.mConstants.ABANDONED_JOB_TIMEOUTS_BEFORE_AGGRESSIVE_BACKOFF - 1,
                         mSourceUid));
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
index 3e87943..924fe95 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/QuotaControllerTest.java
@@ -76,6 +76,7 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.platform.test.annotations.DisableFlags;
 import android.platform.test.annotations.EnableFlags;
@@ -93,6 +94,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.server.LocalServices;
 import com.android.server.PowerAllowlistInternal;
+import com.android.server.compat.PlatformCompat;
 import com.android.server.job.Flags;
 import com.android.server.job.JobSchedulerInternal;
 import com.android.server.job.JobSchedulerService;
@@ -104,8 +106,6 @@
 import com.android.server.job.controllers.QuotaController.TimingSession;
 import com.android.server.usage.AppStandbyInternal;
 
-import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
-
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -168,6 +168,8 @@
     private PowerAllowlistInternal mPowerAllowlistInternal;
     @Mock
     private UsageStatsManagerInternal mUsageStatsManager;
+    @Mock
+    private PlatformCompat mPlatformCompat;
 
     @Rule
     public final CheckFlagsRule mCheckFlagsRule =
@@ -182,6 +184,7 @@
                 .strictness(Strictness.LENIENT)
                 .spyStatic(DeviceConfig.class)
                 .mockStatic(LocalServices.class)
+                .mockStatic(ServiceManager.class)
                 .startMocking();
 
         // Called in StateController constructor.
@@ -198,6 +201,7 @@
         }
         when(mContext.getMainLooper()).thenReturn(Looper.getMainLooper());
         when(mContext.getSystemService(AlarmManager.class)).thenReturn(mAlarmManager);
+
         doReturn(mActivityMangerInternal)
                 .when(() -> LocalServices.getService(ActivityManagerInternal.class));
         doReturn(mock(AppStandbyInternal.class))
@@ -253,6 +257,8 @@
                 ArgumentCaptor.forClass(PowerAllowlistInternal.TempAllowlistChangeListener.class);
         ArgumentCaptor<UsageStatsManagerInternal.UsageEventListener> ueListenerCaptor =
                 ArgumentCaptor.forClass(UsageStatsManagerInternal.UsageEventListener.class);
+        doReturn(mPlatformCompat)
+                .when(() -> ServiceManager.getService(Context.PLATFORM_COMPAT_SERVICE));
         mQuotaController = new QuotaController(mJobSchedulerService,
                 mock(BackgroundJobsController.class), mock(ConnectivityController.class));
 
@@ -1029,6 +1035,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS)
+    @DisableFlags(Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS)
     public void testGetExecutionStatsLocked_Values_NewDefaultBucketWindowSizes() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         mQuotaController.saveTimingSession(0, "com.android.test",
@@ -1127,6 +1134,54 @@
         }
     }
 
+    @Test
+    @EnableFlags({Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS,
+            Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS})
+    public void testGetExecutionStatsLocked_Values_NewDefaultBucketWindowSizes_Tuning() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        mQuotaController.saveTimingSession(0, "com.android.test",
+                createTimingSession(now - (23 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
+        mQuotaController.saveTimingSession(0, "com.android.test",
+                createTimingSession(now - (7 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
+        mQuotaController.saveTimingSession(0, "com.android.test",
+                createTimingSession(now - (2 * HOUR_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5), false);
+        mQuotaController.saveTimingSession(0, "com.android.test",
+                createTimingSession(now - (6 * MINUTE_IN_MILLIS), 3 * MINUTE_IN_MILLIS, 5), false);
+
+        ExecutionStats expectedStats = new ExecutionStats();
+
+        // Exempted
+        expectedStats.allowedTimePerPeriodMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
+        expectedStats.windowSizeMs = mQcConstants.WINDOW_SIZE_EXEMPTED_MS;
+        expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_EXEMPTED;
+        expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_EXEMPTED;
+        expectedStats.expirationTimeElapsed = now + 34 * MINUTE_IN_MILLIS;
+        expectedStats.executionTimeInWindowMs = 3 * MINUTE_IN_MILLIS;
+        expectedStats.bgJobCountInWindow = 5;
+        expectedStats.executionTimeInMaxPeriodMs = 33 * MINUTE_IN_MILLIS;
+        expectedStats.bgJobCountInMaxPeriod = 20;
+        expectedStats.sessionCountInWindow = 1;
+        synchronized (mQuotaController.mLock) {
+            assertEquals(expectedStats,
+                    mQuotaController.getExecutionStatsLocked(0, "com.android.test",
+                            EXEMPTED_INDEX));
+        }
+
+        // Active
+        expectedStats.allowedTimePerPeriodMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
+        expectedStats.windowSizeMs = mQcConstants.WINDOW_SIZE_ACTIVE_MS;
+        expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_ACTIVE;
+        expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_ACTIVE;
+        // There is only one session in the past active bucket window, the empty time for this
+        // window is the bucket window size - duration of the session.
+        expectedStats.expirationTimeElapsed = now + 54 * MINUTE_IN_MILLIS;
+        synchronized (mQuotaController.mLock) {
+            assertEquals(expectedStats,
+                    mQuotaController.getExecutionStatsLocked(0, "com.android.test",
+                            ACTIVE_INDEX));
+        }
+    }
+
     /**
      * Tests that getExecutionStatsLocked returns the correct stats soon after device startup.
      */
@@ -1195,6 +1250,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS)
+    @DisableFlags(Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS)
     public void testGetExecutionStatsLocked_Values_BeginningOfTime_NewDefaultBucketWindowSizes() {
         // Set time to 3 minutes after boot.
         advanceElapsedClock(-JobSchedulerService.sElapsedRealtimeClock.millis());
@@ -1206,10 +1262,10 @@
         ExecutionStats expectedStats = new ExecutionStats();
 
         // Exempted
-        expectedStats.allowedTimePerPeriodMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
+        expectedStats.allowedTimePerPeriodMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
         expectedStats.windowSizeMs = mQcConstants.WINDOW_SIZE_EXEMPTED_MS;
-        expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_ACTIVE;
-        expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_ACTIVE;
+        expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_EXEMPTED;
+        expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_EXEMPTED;
         expectedStats.expirationTimeElapsed = 10 * MINUTE_IN_MILLIS + 11 * MINUTE_IN_MILLIS;
         expectedStats.executionTimeInWindowMs = MINUTE_IN_MILLIS;
         expectedStats.bgJobCountInWindow = 2;
@@ -1268,6 +1324,49 @@
         }
     }
 
+    @Test
+    @EnableFlags({Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS,
+            Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS})
+    public void testGetExecutionStatsLocked_Values_BeginningOfTime_NewDefaultBucketWindowSizes_Tunning() {
+        // Set time to 3 minutes after boot.
+        advanceElapsedClock(-JobSchedulerService.sElapsedRealtimeClock.millis());
+        advanceElapsedClock(3 * MINUTE_IN_MILLIS);
+
+        mQuotaController.saveTimingSession(0, "com.android.test",
+                createTimingSession(MINUTE_IN_MILLIS, MINUTE_IN_MILLIS, 2), false);
+
+        ExecutionStats expectedStats = new ExecutionStats();
+
+        // Exempted
+        expectedStats.allowedTimePerPeriodMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS;
+        expectedStats.windowSizeMs = mQcConstants.WINDOW_SIZE_EXEMPTED_MS;
+        expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_EXEMPTED;
+        expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_EXEMPTED;
+        expectedStats.expirationTimeElapsed = 30 * MINUTE_IN_MILLIS + 11 * MINUTE_IN_MILLIS;
+        expectedStats.executionTimeInWindowMs = MINUTE_IN_MILLIS;
+        expectedStats.bgJobCountInWindow = 2;
+        expectedStats.executionTimeInMaxPeriodMs = MINUTE_IN_MILLIS;
+        expectedStats.bgJobCountInMaxPeriod = 2;
+        expectedStats.sessionCountInWindow = 1;
+        synchronized (mQuotaController.mLock) {
+            assertEquals(expectedStats,
+                    mQuotaController.getExecutionStatsLocked(0, "com.android.test",
+                            EXEMPTED_INDEX));
+        }
+
+        // Active
+        expectedStats.allowedTimePerPeriodMs = mQcConstants.ALLOWED_TIME_PER_PERIOD_ACTIVE_MS;
+        expectedStats.windowSizeMs = mQcConstants.WINDOW_SIZE_ACTIVE_MS;
+        expectedStats.jobCountLimit = mQcConstants.MAX_JOB_COUNT_ACTIVE;
+        expectedStats.sessionCountLimit = mQcConstants.MAX_SESSION_COUNT_ACTIVE;
+        expectedStats.expirationTimeElapsed = 50 * MINUTE_IN_MILLIS + 11 * MINUTE_IN_MILLIS;
+        synchronized (mQuotaController.mLock) {
+            assertEquals(expectedStats,
+                    mQuotaController.getExecutionStatsLocked(0, "com.android.test",
+                            ACTIVE_INDEX));
+        }
+    }
+
     /**
      * Tests that getExecutionStatsLocked returns the correct timing session stats when coalescing.
      */
@@ -1425,6 +1524,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS)
+    @DisableFlags(Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS)
     public void testGetExecutionStatsLocked_CoalescingSessions_NewDefaultBucketWindowSizes() {
         for (int i = 0; i < 20; ++i) {
             mQuotaController.saveTimingSession(0, "com.android.test",
@@ -1581,6 +1681,165 @@
         }
     }
 
+    @Test
+    @EnableFlags({Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS,
+            Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS})
+    public void testGetExecutionStatsLocked_CoalescingSessions_NewDefaultBucketWindowSizes_Tuning() {
+        for (int i = 0; i < 20; ++i) {
+            mQuotaController.saveTimingSession(0, "com.android.test",
+                    createTimingSession(
+                            JobSchedulerService.sElapsedRealtimeClock.millis(),
+                            5 * MINUTE_IN_MILLIS, 5), false);
+            advanceElapsedClock(5 * MINUTE_IN_MILLIS);
+            advanceElapsedClock(5 * MINUTE_IN_MILLIS);
+            for (int j = 0; j < 5; ++j) {
+                mQuotaController.saveTimingSession(0, "com.android.test",
+                        createTimingSession(
+                                JobSchedulerService.sElapsedRealtimeClock.millis(),
+                                MINUTE_IN_MILLIS, 2), false);
+                advanceElapsedClock(MINUTE_IN_MILLIS);
+                advanceElapsedClock(54 * SECOND_IN_MILLIS);
+                mQuotaController.saveTimingSession(0, "com.android.test",
+                        createTimingSession(
+                                JobSchedulerService.sElapsedRealtimeClock.millis(), 500, 1), false);
+                advanceElapsedClock(500);
+                advanceElapsedClock(400);
+                mQuotaController.saveTimingSession(0, "com.android.test",
+                        createTimingSession(
+                                JobSchedulerService.sElapsedRealtimeClock.millis(), 100, 1), false);
+                advanceElapsedClock(100);
+                advanceElapsedClock(5 * SECOND_IN_MILLIS);
+            }
+            advanceElapsedClock(40 * MINUTE_IN_MILLIS);
+        }
+
+        setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 0);
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.invalidateAllExecutionStatsLocked();
+            assertEquals(16, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow);
+            assertEquals(64, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", WORKING_INDEX).sessionCountInWindow);
+            assertEquals(192, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow);
+            assertEquals(320, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", RARE_INDEX).sessionCountInWindow);
+        }
+
+        setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 500);
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.invalidateAllExecutionStatsLocked();
+            assertEquals(11, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow);
+            // WINDOW_SIZE_WORKING_MS * 5 TimingSessions are coalesced
+            assertEquals(44, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", WORKING_INDEX).sessionCountInWindow);
+            // WINDOW_SIZE_FREQUENT_MS * 5 TimingSessions are coalesced
+            assertEquals(132, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow);
+            // WINDOW_SIZE_RARE_MS * 5 TimingSessions are coalesced
+            assertEquals(220, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", RARE_INDEX).sessionCountInWindow);
+        }
+
+        setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, 1000);
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.invalidateAllExecutionStatsLocked();
+            assertEquals(11, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow);
+            assertEquals(44, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", WORKING_INDEX).sessionCountInWindow);
+            assertEquals(132, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow);
+            assertEquals(220, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", RARE_INDEX).sessionCountInWindow);
+        }
+
+        setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS,
+                5 * SECOND_IN_MILLIS);
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.invalidateAllExecutionStatsLocked();
+            assertEquals(7, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow);
+            // WINDOW_SIZE_WORKING_MS * 9 TimingSessions are coalesced
+            assertEquals(28, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", WORKING_INDEX).sessionCountInWindow);
+            // WINDOW_SIZE_FREQUENT_MS * 9 TimingSessions are coalesced
+            assertEquals(84, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow);
+            // WINDOW_SIZE_RARE_MS * 9 TimingSessions are coalesced
+            assertEquals(140, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", RARE_INDEX).sessionCountInWindow);
+        }
+
+        setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS,
+                MINUTE_IN_MILLIS);
+
+        // Only two TimingSessions there for every hour.
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.invalidateAllExecutionStatsLocked();
+            assertEquals(2, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow);
+            assertEquals(8, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", WORKING_INDEX).sessionCountInWindow);
+            assertEquals(24, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow);
+            assertEquals(40, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", RARE_INDEX).sessionCountInWindow);
+        }
+
+        setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS,
+                5 * MINUTE_IN_MILLIS);
+
+        // Only one TimingSessions there for every hour
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.invalidateAllExecutionStatsLocked();
+            assertEquals(1, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow);
+            assertEquals(4, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", WORKING_INDEX).sessionCountInWindow);
+            assertEquals(12, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow);
+            assertEquals(20, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", RARE_INDEX).sessionCountInWindow);
+        }
+
+        setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS,
+                15 * MINUTE_IN_MILLIS);
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.invalidateAllExecutionStatsLocked();
+            assertEquals(1, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow);
+            assertEquals(4, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", WORKING_INDEX).sessionCountInWindow);
+            assertEquals(12, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow);
+            assertEquals(20, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", RARE_INDEX).sessionCountInWindow);
+        }
+
+        // QuotaController caps the duration at 15 minutes, so there shouldn't be any difference
+        // between an hour and 15 minutes.
+        setDeviceConfigLong(QcConstants.KEY_TIMING_SESSION_COALESCING_DURATION_MS, HOUR_IN_MILLIS);
+
+        synchronized (mQuotaController.mLock) {
+            mQuotaController.invalidateAllExecutionStatsLocked();
+            assertEquals(1, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", ACTIVE_INDEX).sessionCountInWindow);
+            assertEquals(4, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", WORKING_INDEX).sessionCountInWindow);
+            assertEquals(12, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", FREQUENT_INDEX).sessionCountInWindow);
+            assertEquals(20, mQuotaController.getExecutionStatsLocked(
+                    0, "com.android.test", RARE_INDEX).sessionCountInWindow);
+        }
+    }
+
     /**
      * Tests that getExecutionStatsLocked properly caches the stats and returns the cached object.
      */
@@ -2231,32 +2490,6 @@
         }
     }
 
-    @Test
-    @EnableFlags(Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS)
-    public void testGetTimeUntilQuotaConsumedLocked_AllowedEqualsWindow_NewDefaultBucketWindowSizes() {
-        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (8 * HOUR_IN_MILLIS), 20 * MINUTE_IN_MILLIS, 5), false);
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (10 * MINUTE_IN_MILLIS), 10 * MINUTE_IN_MILLIS, 5),
-                false);
-
-        setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS,
-                20 * MINUTE_IN_MILLIS);
-        setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_EXEMPTED_MS, 20 * MINUTE_IN_MILLIS);
-        // window size = allowed time, so jobs can essentially run non-stop until they reach the
-        // max execution time.
-        setStandbyBucket(EXEMPTED_INDEX);
-        synchronized (mQuotaController.mLock) {
-            assertEquals(10 * MINUTE_IN_MILLIS,
-                    mQuotaController.getRemainingExecutionTimeLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE));
-            assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 30 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE));
-        }
-    }
-
     /**
      * Test getTimeUntilQuotaConsumedLocked when the determination is based within the bucket
      * window.
@@ -2327,6 +2560,7 @@
 
     @Test
     @EnableFlags(Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS)
+    @DisableFlags(Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS)
     public void testGetTimeUntilQuotaConsumedLocked_BucketWindow_NewDefaultBucketWindowSizes() {
         final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
         // Close to RARE boundary.
@@ -2390,7 +2624,30 @@
 
     @Test
     @EnableFlags({Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS,
+            Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS})
+    public void testGetTimeUntilQuotaConsumedLocked_BucketWindow_NewDefaultBucketWindowSizes_Tuning() {
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        // Close to ACTIVE boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(now - (mQcConstants.WINDOW_SIZE_ACTIVE_MS -  MINUTE_IN_MILLIS),
+                        3 * MINUTE_IN_MILLIS, 5), false);
+
+        // ACTIVE window != allowed time.
+        setStandbyBucket(ACTIVE_INDEX);
+        synchronized (mQuotaController.mLock) {
+            assertEquals(17 * MINUTE_IN_MILLIS,
+                    mQuotaController.getRemainingExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+            assertEquals(20 * MINUTE_IN_MILLIS,
+                    mQuotaController.getTimeUntilQuotaConsumedLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS,
             Flags.FLAG_ADDITIONAL_QUOTA_FOR_SYSTEM_INSTALLER})
+    @DisableFlags(Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS)
     public void testGetTimeUntilQuotaConsumedLocked_Installer() {
         PackageInfo pi = new PackageInfo();
         pi.packageName = SOURCE_PACKAGE;
@@ -2412,7 +2669,7 @@
         // Far away from FREQUENT boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
-                        now - (mQcConstants.WINDOW_SIZE_FREQUENT_MS -  HOUR_IN_MILLIS),
+                        now - (mQcConstants.WINDOW_SIZE_FREQUENT_MS - HOUR_IN_MILLIS),
                         2 * MINUTE_IN_MILLIS, 5), false);
         // Overlap WORKING_SET boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
@@ -2422,12 +2679,12 @@
         // Close to ACTIVE boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
-                        now - (mQcConstants.WINDOW_SIZE_ACTIVE_MS -  MINUTE_IN_MILLIS),
+                        now - (mQcConstants.WINDOW_SIZE_ACTIVE_MS - MINUTE_IN_MILLIS),
                         2 * MINUTE_IN_MILLIS, 5), false);
         // Close to EXEMPTED boundary.
         mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
                 createTimingSession(
-                        now - (mQcConstants.WINDOW_SIZE_EXEMPTED_MS -  MINUTE_IN_MILLIS),
+                        now - (mQcConstants.WINDOW_SIZE_EXEMPTED_MS - MINUTE_IN_MILLIS),
                         2 * MINUTE_IN_MILLIS, 5), false);
 
         // No additional quota for the system installer when the app is in RARE, FREQUENT,
@@ -2486,6 +2743,42 @@
         }
     }
 
+    @Test
+    @EnableFlags({Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS,
+            Flags.FLAG_ADDITIONAL_QUOTA_FOR_SYSTEM_INSTALLER,
+            Flags.FLAG_TUNE_QUOTA_WINDOW_DEFAULT_PARAMETERS})
+    public void testGetTimeUntilQuotaConsumedLocked_Installer_Tuning() {
+        PackageInfo pi = new PackageInfo();
+        pi.packageName = SOURCE_PACKAGE;
+        pi.requestedPermissions = new String[]{Manifest.permission.INSTALL_PACKAGES};
+        pi.requestedPermissionsFlags = new int[]{PackageInfo.REQUESTED_PERMISSION_GRANTED};
+        pi.applicationInfo = new ApplicationInfo();
+        pi.applicationInfo.uid = mSourceUid;
+        doReturn(List.of(pi)).when(mPackageManager).getInstalledPackagesAsUser(anyInt(), anyInt());
+        doReturn(PackageManager.PERMISSION_GRANTED).when(mContext).checkPermission(
+                eq(Manifest.permission.INSTALL_PACKAGES), anyInt(), eq(mSourceUid));
+        mQuotaController.onSystemServicesReady();
+
+        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
+        // Close to EXEMPTED boundary.
+        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
+                createTimingSession(
+                        now - (mQcConstants.WINDOW_SIZE_EXEMPTED_MS - MINUTE_IN_MILLIS),
+                        2 * MINUTE_IN_MILLIS, 5), false);
+
+        // Additional quota for the system installer when the app is in EXEMPTED bucket.
+        // EXEMPTED window == allowed time.
+        setStandbyBucket(EXEMPTED_INDEX);
+        synchronized (mQuotaController.mLock) {
+            assertEquals(38 * MINUTE_IN_MILLIS,
+                    mQuotaController.getRemainingExecutionTimeLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+            assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 2 * MINUTE_IN_MILLIS,
+                    mQuotaController.getTimeUntilQuotaConsumedLocked(
+                            SOURCE_USER_ID, SOURCE_PACKAGE));
+        }
+    }
+
     /**
      * Test getTimeUntilQuotaConsumedLocked when the app is close to the max execution limit.
      */
@@ -2637,33 +2930,6 @@
         }
     }
 
-    @Test
-    @EnableFlags(Flags.FLAG_ADJUST_QUOTA_DEFAULT_CONSTANTS)
-    public void testGetTimeUntilQuotaConsumedLocked_EdgeOfWindow_AllowedEqualsWindow_NewDefaultBucketWindowSizes() {
-        final long now = JobSchedulerService.sElapsedRealtimeClock.millis();
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (24 * HOUR_IN_MILLIS),
-                        mQcConstants.MAX_EXECUTION_TIME_MS - 20 * MINUTE_IN_MILLIS, 5),
-                false);
-        mQuotaController.saveTimingSession(SOURCE_USER_ID, SOURCE_PACKAGE,
-                createTimingSession(now - (20 * MINUTE_IN_MILLIS), 20 * MINUTE_IN_MILLIS, 5),
-                false);
-
-        setDeviceConfigLong(QcConstants.KEY_ALLOWED_TIME_PER_PERIOD_EXEMPTED_MS,
-                20 * MINUTE_IN_MILLIS);
-        setDeviceConfigLong(QcConstants.KEY_WINDOW_SIZE_EXEMPTED_MS, 20 * MINUTE_IN_MILLIS);
-        // window size != allowed time.
-        setStandbyBucket(EXEMPTED_INDEX);
-        synchronized (mQuotaController.mLock) {
-            assertEquals(0,
-                    mQuotaController.getRemainingExecutionTimeLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE));
-            assertEquals(mQcConstants.MAX_EXECUTION_TIME_MS - 20 * MINUTE_IN_MILLIS,
-                    mQuotaController.getTimeUntilQuotaConsumedLocked(
-                            SOURCE_USER_ID, SOURCE_PACKAGE));
-        }
-    }
-
     /**
      * Test getTimeUntilQuotaConsumedLocked when the determination is based within the bucket
      * window and the session is rolling out of the window.
@@ -5331,13 +5597,17 @@
     }
 
     @Test
-    @EnableCompatChanges({QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS,
-            QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS})
     @RequiresFlagsEnabled({Flags.FLAG_ENFORCE_QUOTA_POLICY_TO_TOP_STARTED_JOBS,
             Flags.FLAG_ENFORCE_QUOTA_POLICY_TO_FGS_JOBS})
     public void testTracking_OutOfQuota_ForegroundAndBackground_CompactChangeOverrides() {
         setDischarging();
 
+        // Mock the OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS compat change overrides.
+        doReturn(true).when(mPlatformCompat).isChangeEnabledByUid(
+                eq(QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_TOP_STARTED_JOBS), anyInt());
+        doReturn(true).when(mPlatformCompat).isChangeEnabledByUid(
+                eq(QuotaController.OVERRIDE_QUOTA_ENFORCEMENT_TO_FGS_JOBS), anyInt());
+
         JobStatus jobBg = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 1);
         JobStatus jobTop = createJobStatus("testTracking_OutOfQuota_ForegroundAndBackground", 2);
         trackJobs(jobBg, jobTop);
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java
index 3d0c637..29af7d2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/BackgroundUserSoundNotifierTest.java
@@ -27,7 +27,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 import static org.testng.AssertJUnit.assertEquals;
 
@@ -128,7 +128,7 @@
                 AudioManager.AUDIOFOCUS_NONE, /* flags= */ 0, Build.VERSION.SDK_INT);
         clearInvocations(mNotificationManager);
         mBackgroundUserSoundNotifier.notifyForegroundUserAboutSoundIfNecessary(afi);
-        verifyZeroInteractions(mNotificationManager);
+        verifyNoMoreInteractions(mNotificationManager);
     }
 
     @Test
@@ -143,7 +143,7 @@
                 Build.VERSION.SDK_INT);
         clearInvocations(mNotificationManager);
         mBackgroundUserSoundNotifier.notifyForegroundUserAboutSoundIfNecessary(afi);
-        verifyZeroInteractions(mNotificationManager);
+        verifyNoMoreInteractions(mNotificationManager);
     }
 
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java
index dc04b6a..bf3fe8c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/sensorprivacy/CameraPrivacyLightControllerTest.java
@@ -29,7 +29,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.app.AppOpsManager;
 import android.content.Context;
@@ -176,9 +176,9 @@
         prepareCameraPrivacyLightController(List.of(getNextLight(true)), Collections.EMPTY_SET,
                 true, new int[0], mDefaultAlsThresholdsLux, mDefaultAlsAveragingIntervalMillis);
 
-        verifyZeroInteractions(mLightsManager);
-        verifyZeroInteractions(mAppOpsManager);
-        verifyZeroInteractions(mSensorManager);
+        verifyNoMoreInteractions(mLightsManager);
+        verifyNoMoreInteractions(mAppOpsManager);
+        verifyNoMoreInteractions(mSensorManager);
     }
 
     @Test
diff --git a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
index 241ffdc..4f74667 100644
--- a/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/wallpaper/WallpaperCropperTest.java
@@ -33,10 +33,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.mockito.MockitoAnnotations.initMocks;
 
@@ -48,7 +46,6 @@
 import android.util.ArraySet;
 import android.util.Log;
 import android.util.SparseArray;
-import android.view.Display;
 import android.view.DisplayInfo;
 import android.view.WindowInsets;
 import android.view.WindowManager;
@@ -95,7 +92,6 @@
 
     @Mock
     private Resources mResources;
-    private WallpaperCropper mWallpaperCropper;
 
     private static final Point PORTRAIT_ONE = new Point(500, 800);
     private static final Point PORTRAIT_TWO = new Point(400, 1000);
@@ -171,7 +167,6 @@
             return getWallpaperTestDir(userId);
         }).when(() -> WallpaperUtils.getWallpaperDir(anyInt()));
 
-        mWallpaperCropper = new WallpaperCropper(mWallpaperDisplayHelper);
     }
 
     private File getWallpaperTestDir(int userId) {
@@ -738,13 +733,13 @@
         DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 2560;
         displayInfo.logicalHeight = 1044;
+        setUpWithDisplays(List.of(new Point(displayInfo.logicalWidth, displayInfo.logicalHeight)));
         doReturn(displayInfo).when(mWallpaperDisplayHelper).getDisplayInfo(eq(DEFAULT_DISPLAY));
         WallpaperData wallpaperData = createWallpaperData(/* isStockWallpaper = */ false,
                 new Point(100, 100));
 
-        assertThat(
-                mWallpaperCropper.isWallpaperCompatibleForDisplay(DEFAULT_DISPLAY,
-                        wallpaperData)).isTrue();
+        assertThat(new WallpaperCropper(mWallpaperDisplayHelper).isWallpaperCompatibleForDisplay(
+                DEFAULT_DISPLAY, wallpaperData)).isTrue();
     }
 
     // Test isWallpaperCompatibleForDisplay always return true for the stock wallpaper.
@@ -755,49 +750,67 @@
         DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 2560;
         displayInfo.logicalHeight = 1044;
+        setUpWithDisplays(List.of(new Point(displayInfo.logicalWidth, displayInfo.logicalHeight)));
         doReturn(displayInfo).when(mWallpaperDisplayHelper).getDisplayInfo(eq(displayId));
         WallpaperData wallpaperData = createWallpaperData(/* isStockWallpaper = */ true,
                 new Point(100, 100));
 
-        assertThat(
-                mWallpaperCropper.isWallpaperCompatibleForDisplay(displayId,
-                        wallpaperData)).isTrue();
+        assertThat(new WallpaperCropper(mWallpaperDisplayHelper).isWallpaperCompatibleForDisplay(
+                displayId, wallpaperData)).isTrue();
     }
 
     // Test isWallpaperCompatibleForDisplay wallpaper is suitable for the display and wallpaper
     // aspect ratio meets the hard-coded aspect ratio.
     @Test
-    public void isWallpaperCompatibleForDisplay_wallpaperSizeSuitableForDisplayAndMeetAspectRatio_returnTrue()
+    public void isWallpaperCompatibleForDisplay_wallpaperSizeLargerThanDisplayAndMeetAspectRatio_returnTrue()
             throws Exception {
         final int displayId = 2;
         DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 2560;
         displayInfo.logicalHeight = 1044;
+        setUpWithDisplays(List.of(new Point(displayInfo.logicalWidth, displayInfo.logicalHeight)));
         doReturn(displayInfo).when(mWallpaperDisplayHelper).getDisplayInfo(eq(displayId));
         WallpaperData wallpaperData = createWallpaperData(/* isStockWallpaper = */ false,
                 new Point(4000, 3000));
 
-        assertThat(
-                mWallpaperCropper.isWallpaperCompatibleForDisplay(displayId,
-                        wallpaperData)).isTrue();
+        assertThat(new WallpaperCropper(mWallpaperDisplayHelper).isWallpaperCompatibleForDisplay(
+                displayId, wallpaperData)).isTrue();
     }
 
-    // Test isWallpaperCompatibleForDisplay wallpaper is not suitable for the display and wallpaper
-    // aspect ratio meets the hard-coded aspect ratio.
+    // Test isWallpaperCompatibleForDisplay wallpaper is smaller than the display but larger than
+    // the threshold and wallpaper aspect ratio meets the hard-coded aspect ratio.
     @Test
-    public void isWallpaperCompatibleForDisplay_wallpaperSizeNotSuitableForDisplayAndMeetAspectRatio_returnFalse()
+    public void isWallpaperCompatibleForDisplay_wallpaperSizeSmallerThanDisplayButBeyondThresholdAndMeetAspectRatio_returnTrue()
             throws Exception {
         final int displayId = 2;
         DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 2560;
         displayInfo.logicalHeight = 1044;
+        setUpWithDisplays(List.of(new Point(displayInfo.logicalWidth, displayInfo.logicalHeight)));
         doReturn(displayInfo).when(mWallpaperDisplayHelper).getDisplayInfo(eq(displayId));
         WallpaperData wallpaperData = createWallpaperData(/* isStockWallpaper = */ false,
-                new Point(1000, 500));
+                new Point(2000, 900));
 
-        assertThat(
-                mWallpaperCropper.isWallpaperCompatibleForDisplay(displayId,
-                        wallpaperData)).isFalse();
+        assertThat(new WallpaperCropper(mWallpaperDisplayHelper).isWallpaperCompatibleForDisplay(
+                displayId, wallpaperData)).isTrue();
+    }
+
+    // Test isWallpaperCompatibleForDisplay wallpaper is smaller than the display but larger than
+    // the threshold and wallpaper aspect ratio meets the hard-coded aspect ratio.
+    @Test
+    public void isWallpaperCompatibleForDisplay_wallpaperSizeSmallerThanDisplayButAboveThresholdAndMeetAspectRatio_returnFalse()
+            throws Exception {
+        final int displayId = 2;
+        DisplayInfo displayInfo = new DisplayInfo();
+        displayInfo.logicalWidth = 2560;
+        displayInfo.logicalHeight = 1044;
+        setUpWithDisplays(List.of(new Point(displayInfo.logicalWidth, displayInfo.logicalHeight)));
+        doReturn(displayInfo).when(mWallpaperDisplayHelper).getDisplayInfo(eq(displayId));
+        WallpaperData wallpaperData = createWallpaperData(/* isStockWallpaper = */ false,
+                new Point(2000, 800));
+
+        assertThat(new WallpaperCropper(mWallpaperDisplayHelper).isWallpaperCompatibleForDisplay(
+                displayId, wallpaperData)).isFalse();
     }
 
     // Test isWallpaperCompatibleForDisplay wallpaper is suitable for the display and wallpaper
@@ -809,13 +822,13 @@
         DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 2560;
         displayInfo.logicalHeight = 1044;
+        setUpWithDisplays(List.of(new Point(displayInfo.logicalWidth, displayInfo.logicalHeight)));
         doReturn(displayInfo).when(mWallpaperDisplayHelper).getDisplayInfo(eq(displayId));
         WallpaperData wallpaperData = createWallpaperData(/* isStockWallpaper = */ false,
                 new Point(2000, 4000));
 
-        assertThat(
-                mWallpaperCropper.isWallpaperCompatibleForDisplay(displayId,
-                        wallpaperData)).isFalse();
+        assertThat(new WallpaperCropper(mWallpaperDisplayHelper).isWallpaperCompatibleForDisplay(
+                displayId, wallpaperData)).isFalse();
     }
 
     // Test isWallpaperCompatibleForDisplay, portrait display, wallpaper is suitable for the display
@@ -827,24 +840,13 @@
         DisplayInfo displayInfo = new DisplayInfo();
         displayInfo.logicalWidth = 1044;
         displayInfo.logicalHeight = 2560;
+        setUpWithDisplays(List.of(new Point(displayInfo.logicalWidth, displayInfo.logicalHeight)));
         doReturn(displayInfo).when(mWallpaperDisplayHelper).getDisplayInfo(eq(displayId));
         WallpaperData wallpaperData = createWallpaperData(/* isStockWallpaper = */ false,
                 new Point(2000, 4000));
 
-        assertThat(
-                mWallpaperCropper.isWallpaperCompatibleForDisplay(displayId,
-                        wallpaperData)).isTrue();
-    }
-
-    private void mockDisplay(int displayId, Point displayResolution) {
-        final Display mockDisplay = mock(Display.class);
-        when(mockDisplay.getDisplayInfo(any(DisplayInfo.class))).thenAnswer(invocation -> {
-            DisplayInfo displayInfo = invocation.getArgument(0);
-            displayInfo.displayId = displayId;
-            displayInfo.logicalWidth = displayResolution.x;
-            displayInfo.logicalHeight = displayResolution.y;
-            return true;
-        });
+        assertThat(new WallpaperCropper(mWallpaperDisplayHelper).isWallpaperCompatibleForDisplay(
+                displayId, wallpaperData)).isTrue();
     }
 
     private WallpaperData createWallpaperData(boolean isStockWallpaper, Point wallpaperSize)
diff --git a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
index 4e56422..94ce723 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/NotifierTest.java
@@ -39,9 +39,9 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
+import android.annotation.NonNull;
 import android.app.ActivityManagerInternal;
 import android.app.AppOpsManager;
 import android.content.Context;
@@ -53,8 +53,8 @@
 import android.os.BatteryStatsInternal;
 import android.os.Handler;
 import android.os.IBinder;
-import android.os.IWakeLockCallback;
 import android.os.IScreenTimeoutPolicyListener;
+import android.os.IWakeLockCallback;
 import android.os.Looper;
 import android.os.PowerManager;
 import android.os.RemoteException;
@@ -205,7 +205,7 @@
         mTestExecutor.simulateAsyncExecutionOfLastCommand();
 
         // THEN the device doesn't vibrate
-        verifyZeroInteractions(mVibrator);
+        verifyNoMoreInteractions(mVibrator);
     }
 
     @Test
@@ -238,7 +238,7 @@
         mTestExecutor.simulateAsyncExecutionOfLastCommand();
 
         // THEN the device doesn't vibrate
-        verifyZeroInteractions(mVibrator);
+        verifyNoMoreInteractions(mVibrator);
     }
 
     @Test
@@ -725,10 +725,11 @@
 
         final int uid = 1234;
         final int pid = 5678;
+
         mNotifier.onWakeLockReleased(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
                 "my.package.name", uid, pid, /* workSource= */ null, /* historyTag= */ null,
                 exceptingCallback);
-        verifyZeroInteractions(mWakeLockLog);
+        verifyNoMoreInteractions(mWakeLockLog);
         mTestLooper.dispatchAll();
         verify(mWakeLockLog).onWakeLockReleased("wakelockTag", uid, 1);
         clearInvocations(mBatteryStats);
@@ -790,6 +791,55 @@
     }
 
     @Test
+    public void test_wakeLockLogUsesWorkSource() {
+        createNotifier();
+        clearInvocations(mWakeLockLog);
+        IWakeLockCallback exceptingCallback = new IWakeLockCallback.Stub() {
+            @Override public void onStateChanged(boolean enabled) throws RemoteException {
+                throw new RemoteException("Just testing");
+            }
+        };
+
+        final int uid = 1234;
+        final int pid = 5678;
+        WorkSource worksource = new WorkSource(1212);
+        WorkSource worksource2 = new WorkSource(3131);
+
+        mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, worksource, /* historyTag= */ null,
+                exceptingCallback);
+        verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", 1212,
+                PowerManager.PARTIAL_WAKE_LOCK, -1);
+
+        // Release the wakelock
+        mNotifier.onWakeLockReleased(PowerManager.FULL_WAKE_LOCK, "wakelockTag2",
+                "my.package.name", uid, pid, worksource2, /* historyTag= */ null,
+                exceptingCallback);
+        verify(mWakeLockLog).onWakeLockReleased("wakelockTag2", 3131, -1);
+
+        // clear the handler
+        mTestLooper.dispatchAll();
+
+        // Now test with improveWakelockLatency flag true
+        clearInvocations(mWakeLockLog);
+        when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true);
+
+        mNotifier.onWakeLockAcquired(PowerManager.PARTIAL_WAKE_LOCK, "wakelockTag",
+                "my.package.name", uid, pid, worksource, /* historyTag= */ null,
+                exceptingCallback);
+        mTestLooper.dispatchAll();
+        verify(mWakeLockLog).onWakeLockAcquired("wakelockTag", 1212,
+                PowerManager.PARTIAL_WAKE_LOCK, 1);
+
+        // Release the wakelock
+        mNotifier.onWakeLockReleased(PowerManager.FULL_WAKE_LOCK, "wakelockTag2",
+                "my.package.name", uid, pid, worksource2, /* historyTag= */ null,
+                exceptingCallback);
+        mTestLooper.dispatchAll();
+        verify(mWakeLockLog).onWakeLockReleased("wakelockTag2", 3131, 1);
+    }
+
+    @Test
     public void
             test_notifierProcessesWorkSourceDeepCopy_OnWakelockChanging() throws RemoteException {
         when(mPowerManagerFlags.improveWakelockLatency()).thenReturn(true);
@@ -845,7 +895,7 @@
                 exceptingCallback);
 
         // No interaction because we expect that to happen in async
-        verifyZeroInteractions(mWakeLockLog, mBatteryStats, mAppOpsManager);
+        verifyNoMoreInteractions(mWakeLockLog, mBatteryStats, mAppOpsManager);
 
         // Progressing the looper, and validating all the interactions
         mTestLooper.dispatchAll();
@@ -944,15 +994,23 @@
         assertEquals(mNotifier.getWakelockMonitorTypeForLogging(PowerManager.PARTIAL_WAKE_LOCK),
                 PowerManager.PARTIAL_WAKE_LOCK);
         assertEquals(mNotifier.getWakelockMonitorTypeForLogging(
+                        PowerManager.DOZE_WAKE_LOCK), -1);
+    }
+
+    @Test
+    public void getWakelockMonitorTypeForLogging_evaluateProximityLevel() {
+        // How proximity wakelock is evaluated depends on boolean configuration. Test both.
+        when(mResourcesSpy.getBoolean(
+                com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity))
+                .thenReturn(false);
+        createNotifier();
+        assertEquals(mNotifier.getWakelockMonitorTypeForLogging(
                         PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK),
                 PowerManager.PARTIAL_WAKE_LOCK);
-        assertEquals(mNotifier.getWakelockMonitorTypeForLogging(
-                        PowerManager.DOZE_WAKE_LOCK), -1);
 
         when(mResourcesSpy.getBoolean(
                 com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity))
                 .thenReturn(true);
-
         createNotifier();
         assertEquals(mNotifier.getWakelockMonitorTypeForLogging(
                         PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK), -1);
@@ -1239,7 +1297,7 @@
                     }
 
                     @Override
-                    public WakeLockLog getWakeLockLog(Context context) {
+                    public @NonNull WakeLockLog getWakeLockLog(Context context) {
                         return mWakeLockLog;
                     }
 
diff --git a/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java b/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
index c1d7c7b..534337e 100644
--- a/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
+++ b/services/tests/powerservicetests/src/com/android/server/power/WakeLockLogTest.java
@@ -27,6 +27,8 @@
 import android.os.PowerManager;
 import android.os.Process;
 
+import com.android.server.power.WakeLockLog.TagData;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
@@ -62,8 +64,9 @@
     @Test
     public void testAddTwoItems_withNoEventTimeSupplied() {
         final int tagDatabaseSize = 128;
+        final int tagStartingSize = 16;
         final int logSize = 20;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
         log.onWakeLockAcquired("TagPartial", 101,
@@ -93,8 +96,9 @@
     @Test
     public void testAddTwoItems() {
         final int tagDatabaseSize = 128;
+        final int tagStartingSize = 16;
         final int logSize = 20;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("TagPartial", 101,
@@ -117,8 +121,9 @@
     @Test
     public void testAddTwoItemsWithTimeReset() {
         final int tagDatabaseSize = 128;
+        final int tagStartingSize = 16;
         final int logSize = 20;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK, 1000L);
@@ -136,9 +141,10 @@
 
     @Test
     public void testAddTwoItemsWithTagOverwrite() {
-        final int tagDatabaseSize = 2;
+        final int tagDatabaseSize = 1;
+        final int tagStartingSize = 1;
         final int logSize = 20;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK, 1000L);
@@ -157,8 +163,9 @@
     @Test
     public void testAddFourItemsWithRingBufferOverflow() {
         final int tagDatabaseSize = 6;
+        final int tagStartingSize = 2;
         final int logSize = 10;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         // Wake lock 1 acquired - log size = 3
@@ -206,8 +213,9 @@
     @Test
     public void testAddItemWithBadTag() {
         final int tagDatabaseSize = 6;
+        final int tagStartingSize = 2;
         final int logSize = 10;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         // Bad tag means it wont get written
@@ -224,8 +232,9 @@
     @Test
     public void testAddItemWithReducedTagName() {
         final int tagDatabaseSize = 6;
+        final int tagStartingSize = 2;
         final int logSize = 10;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("*job*/com.one.two.3hree/.one..Last", 101,
@@ -242,9 +251,10 @@
 
     @Test
     public void testAddAcquireAndReleaseWithRepeatTagName() {
-        final int tagDatabaseSize = 6;
+        final int tagDatabaseSize = 5;
+        final int tagStartingSize = 5;
         final int logSize = 10;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("HowdyTag", 101, PowerManager.PARTIAL_WAKE_LOCK, 1000L);
@@ -263,8 +273,9 @@
     @Test
     public void testAddAcquireAndReleaseWithTimeTravel() {
         final int tagDatabaseSize = 6;
+        final int tagStartingSize = 2;
         final int logSize = 10;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("HowdyTag", 101, PowerManager.PARTIAL_WAKE_LOCK, 1100L);
@@ -283,8 +294,9 @@
     @Test
     public void testAddSystemWakelock() {
         final int tagDatabaseSize = 6;
+        final int tagStartingSize = 2;
         final int logSize = 10;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("TagPartial", 101,
@@ -302,8 +314,9 @@
     @Test
     public void testAddItemWithNoPackageName() {
         final int tagDatabaseSize = 128;
+        final int tagStartingSize = 16;
         final int logSize = 20;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         when(mPackageManager.getPackagesForUid(101)).thenReturn(null);
@@ -322,8 +335,9 @@
     @Test
     public void testAddItemWithMultiplePackageNames() {
         final int tagDatabaseSize = 128;
+        final int tagStartingSize = 16;
         final int logSize = 20;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         when(mPackageManager.getPackagesForUid(101)).thenReturn(
@@ -344,8 +358,9 @@
     @Test
     public void testAddItemsWithRepeatOwnerUid_UsesCache() {
         final int tagDatabaseSize = 128;
+        final int tagStartingSize = 16;
         final int logSize = 20;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("TagPartial", 101,
@@ -375,8 +390,9 @@
     @Test
     public void testAddItemsWithRepeatOwnerUid_SavedAcquisitions_UsesCache() {
         final int tagDatabaseSize = 128;
+        final int tagStartingSize = 16;
         final int logSize = 10;
-        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
+        TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, tagStartingSize, logSize));
         WakeLockLog log = new WakeLockLog(injectorSpy, mContext);
 
         log.onWakeLockAcquired("TagPartial", 101,
@@ -420,6 +436,34 @@
         verify(mPackageManager, times(1)).getPackagesForUid(101);
     }
 
+    @Test
+    public void testTagDatabaseGrowsBeyondStartingSize() {
+        final int tagDatabaseSize = 3;
+        final int tagStartingSize = 1;
+        final int logSize = 10;
+        // start with size = 1 and max size
+        TestInjector injector = new TestInjector(tagDatabaseSize, tagStartingSize, logSize);
+        WakeLockLog.TagDatabase td = new WakeLockLog.TagDatabase(injector);
+
+        // Add one
+        TagData data1 = td.findOrCreateTag("Tagname1", 1001, /* shouldCreate= */ true);
+        assertEquals(0, td.getTagIndex(data1));
+
+        // Check that it grows by adding 1 more
+        TagData data2 = td.findOrCreateTag("Tagname2", 1001, /* shouldCreate= */ true);
+        assertEquals(1, td.getTagIndex(data2));
+
+        // Lets add the last one to fill up the DB to maxSize
+        TagData data3 = td.findOrCreateTag("Tagname3", 1001, /* shouldCreate= */ true);
+        assertEquals(2, td.getTagIndex(data3));
+
+        // Adding a fourth one should replace the oldest one (Tagname1)
+        TagData data4 = td.findOrCreateTag("Tagname4", 1001, /* shouldCreate= */ true);
+        assertEquals(0, td.getTagIndex(data4));
+        assertEquals(tagDatabaseSize, td.getTagIndex(data1));
+
+    }
+
     private String dumpLog(WakeLockLog log, boolean includeTagDb) {
         StringWriter sw = new StringWriter();
         PrintWriter pw = new PrintWriter(sw);
@@ -429,10 +473,12 @@
 
     public static class TestInjector extends WakeLockLog.Injector {
         private final int mTagDatabaseSize;
+        private final int mTagStartingSize;
         private final int mLogSize;
 
-        public TestInjector(int tagDatabaseSize, int logSize) {
+        public TestInjector(int tagDatabaseSize, int tagStartingSize, int logSize) {
             mTagDatabaseSize = tagDatabaseSize;
+            mTagStartingSize = tagStartingSize;
             mLogSize = logSize;
         }
 
@@ -442,6 +488,11 @@
         }
 
         @Override
+        public int getTagDatabaseStartingSize() {
+            return mTagStartingSize;
+        }
+
+        @Override
         public int getLogSize() {
             return mLogSize;
         }
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
index 4b91d84..28d39fd 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AmbientDisplayPowerCalculatorTest.java
@@ -21,7 +21,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.os.BatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.view.Display;
 
 import androidx.test.filters.SmallTest;
@@ -35,15 +34,10 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class AmbientDisplayPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final long MINUTE_IN_MS = 60 * 1000;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_AMBIENT, 0, 10.0)
             .setNumDisplays(1);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java
index ce451c2..7f03953 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/AudioPowerCalculatorTest.java
@@ -21,7 +21,6 @@
 import android.os.BatteryConsumer;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -35,16 +34,11 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class AudioPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_AUDIO, 360.0);
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java
index ec8ede0..7faa295 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryChargeCalculatorTest.java
@@ -23,7 +23,6 @@
 import android.content.Context;
 import android.os.BatteryManager;
 import android.os.BatteryUsageStats;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -38,14 +37,9 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class BatteryChargeCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
                     .setAveragePower(PowerProfile.POWER_BATTERY_CAPACITY, 4000.0);
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java
index ad05b51..8791c2f 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBackgroundStatsTest.java
@@ -25,13 +25,11 @@
 import android.app.ActivityManager;
 import android.os.BatteryStats;
 import android.os.WorkSource;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.ArrayMap;
 import android.view.Display;
 
 import androidx.test.filters.SmallTest;
 
-import org.junit.Rule;
 import org.junit.Test;
 
 /**
@@ -39,11 +37,6 @@
  */
 public class BatteryStatsBackgroundStatsTest {
 
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final int UID = 10500;
 
     /** Test that BatteryStatsImpl.Uid.mOnBatteryBackgroundTimeBase works correctly. */
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java
index 4dfc3fc..c0d33cb 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsBinderCallStatsTest.java
@@ -20,7 +20,6 @@
 
 import android.os.Binder;
 import android.os.Process;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
@@ -28,7 +27,6 @@
 import com.android.internal.os.BinderCallsStats;
 import com.android.internal.os.BinderTransactionNameResolver;
 
-import org.junit.Rule;
 import org.junit.Test;
 
 import java.util.ArrayList;
@@ -41,11 +39,6 @@
 @android.platform.test.annotations.DisabledOnRavenwood(blockedBy = BinderCallsStats.class)
 public class BatteryStatsBinderCallStatsTest {
 
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final int TRANSACTION_CODE1 = 100;
     private static final int TRANSACTION_CODE2 = 101;
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
index eff1b7b..b73895c 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsCpuTimesTest.java
@@ -40,7 +40,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.UserHandle;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseArray;
 import android.util.SparseLongArray;
 import android.view.Display;
@@ -57,7 +56,6 @@
 import com.android.internal.util.ArrayUtils;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -88,11 +86,6 @@
 @RunWith(AndroidJUnit4.class)
 @SuppressWarnings("SynchronizeOnNonFinalField")
 public class BatteryStatsCpuTimesTest {
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     @Mock
     KernelCpuUidUserSysTimeReader mCpuUidUserSysTimeReader;
     @Mock
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java
index 7e40e6b..503e233 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryIteratorTest.java
@@ -22,7 +22,6 @@
 import android.os.BatteryManager;
 import android.os.BatteryStats;
 import android.os.Process;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -31,7 +30,6 @@
 import com.android.internal.os.MonotonicClock;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -44,11 +42,6 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class BatteryStatsHistoryIteratorTest {
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
 
     private final MockClock mMockClock = new MockClock();
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
index fc864dd..3ed4a52 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsHistoryTest.java
@@ -343,12 +343,13 @@
                 assertThat(mReadFiles).containsExactly("123.bh", "1000.bh");
             } else if (item.eventCode == HistoryItem.EVENT_ALARM) {
                 eventsRead++;
-                assertThat(mReadFiles).containsExactly("123.bh", "1000.bh", "2000.bh");
+                // This event is in the current buffer, so 2000.bh shouldn't be read from disk
+                assertThat(mReadFiles).containsExactly("123.bh", "1000.bh");
             }
         }
 
         assertThat(eventsRead).isEqualTo(3);
-        assertThat(mReadFiles).containsExactly("123.bh", "1000.bh", "2000.bh", "3000.bh");
+        assertThat(mReadFiles).containsExactly("123.bh", "1000.bh");
     }
 
     @Test
@@ -366,34 +367,41 @@
             return invocation.callRealMethod();
         }).when(mHistory).readFragmentToParcel(any(), any());
 
-        BatteryStatsHistoryIterator iterator = mHistory.iterate(1000, 3000);
+        int eventsRead = 0;
+        BatteryStatsHistoryIterator iterator = mHistory.iterate(1001, 3000);
         while (iterator.hasNext()) {
             HistoryItem item = iterator.next();
             if (item.eventCode == HistoryItem.EVENT_JOB_START) {
                 fail("Event outside the range");
             } else if (item.eventCode == HistoryItem.EVENT_JOB_FINISH) {
+                eventsRead++;
                 assertThat(mReadFiles).containsExactly("1000.bh");
             } else if (item.eventCode == HistoryItem.EVENT_ALARM) {
                 fail("Event outside the range");
             }
         }
 
-        assertThat(mReadFiles).containsExactly("1000.bh", "2000.bh");
+        assertThat(eventsRead).isEqualTo(1);
+        assertThat(mReadFiles).containsExactly("1000.bh");
     }
 
     private void prepareMultiFileHistory() {
-        mClock.realtime = 1000;
-        mClock.uptime = 1000;
+        mClock.realtime = 500;
+        mClock.uptime = 500;
         mHistory.recordEvent(mClock.realtime, mClock.uptime,
                 BatteryStats.HistoryItem.EVENT_JOB_START, "job", 42);
 
+        mClock.realtime = 1000;
+        mClock.uptime = 1000;
         mHistory.startNextFragment(mClock.realtime);       // 1000.bh
 
-        mClock.realtime = 2000;
-        mClock.uptime = 2000;
+        mClock.realtime = 1500;
+        mClock.uptime = 1500;
         mHistory.recordEvent(mClock.realtime, mClock.uptime,
                 BatteryStats.HistoryItem.EVENT_JOB_FINISH, "job", 42);
 
+        mClock.realtime = 2000;
+        mClock.uptime = 2000;
         mHistory.startNextFragment(mClock.realtime);       // 2000.bh
 
         mClock.realtime = 3000;
@@ -401,8 +409,8 @@
         mHistory.recordEvent(mClock.realtime, mClock.uptime,
                 HistoryItem.EVENT_ALARM, "alarm", 42);
 
-        // Flush accumulated history to disk
-        mHistory.startNextFragment(mClock.realtime);
+        // Back up accumulated history to disk
+        mHistory.writeHistory();
     }
 
     private void verifyActiveFile(BatteryStatsHistory history, String file) {
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
index db32687..1744093 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsImplTest.java
@@ -92,7 +92,6 @@
 public class BatteryStatsImplTest {
     @Rule(order = 0)
     public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
             .setSystemPropertyImmutable("persist.sys.com.android.server.power.feature.flags."
                 + "framework_wakelock_info-override", null)
             .build();
@@ -150,7 +149,7 @@
         File systemDir = Files.createTempDirectory("BatteryStatsHistoryTest").toFile();
 
         Context context;
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             context = mock(Context.class);
             SensorManager sensorManager = mock(SensorManager.class);
             when(sensorManager.getSensorList(anyInt())).thenReturn(List.of());
@@ -856,7 +855,7 @@
     }
 
     private UidTraffic createUidTraffic(int appUid, long rxBytes, long txBytes) {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             UidTraffic uidTraffic = mock(UidTraffic.class);
             when(uidTraffic.getUid()).thenReturn(appUid);
             when(uidTraffic.getRxBytes()).thenReturn(rxBytes);
@@ -881,7 +880,7 @@
             long controllerIdleTimeMs,
             long controllerEnergyUsed,
             UidTraffic... uidTraffic) {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             BluetoothActivityEnergyInfo info = mock(BluetoothActivityEnergyInfo.class);
             when(info.getTimestampMillis()).thenReturn(timestamp);
             when(info.getControllerTxTimeMillis()).thenReturn(controllerTxTimeMs);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
index 30ff800..ffb309a 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsNoteTest.java
@@ -91,7 +91,6 @@
     @Rule
     public final RavenwoodRule mRavenwood =
             new RavenwoodRule.Builder()
-                    .setProvideMainThread(true)
                     .setSystemPropertyImmutable(
                             "persist.sys.com.android.server.power.feature.flags."
                                     + "framework_wakelock_info-override",
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java
index b6d49d0..550df3a 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsResetTest.java
@@ -23,7 +23,6 @@
 
 import android.content.Context;
 import android.os.BatteryManager;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -40,11 +39,6 @@
 public class BatteryStatsResetTest {
 
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .createTempDirectory();
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java
index 96780c3..018e8c2 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsSensorTest.java
@@ -22,12 +22,10 @@
 
 import android.app.ActivityManager;
 import android.os.BatteryStats;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.view.Display;
 
 import androidx.test.filters.SmallTest;
 
-import org.junit.Rule;
 import org.junit.Test;
 
 /**
@@ -36,11 +34,6 @@
 @SmallTest
 public class BatteryStatsSensorTest {
 
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final int UID = 10500;
     private static final int UID_2 = 10501; // second uid for testing pool usage
     private static final int SENSOR_ID = -10000;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java
index 6f683ae..882e48d 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryStatsServTest.java
@@ -18,13 +18,11 @@
 
 import android.os.BatteryStats;
 import android.os.Parcel;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 
 import junit.framework.Assert;
 
-import org.junit.Rule;
 import org.junit.Test;
 
 /**
@@ -32,11 +30,6 @@
  */
 @SmallTest
 public class BatteryStatsServTest {
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final String TAG = "BatteryStatsServTest";
 
     public static class TestServ extends BatteryStatsImpl.Uid.Pkg.Serv {
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
index 93fe8d3..8a1d37b5 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsProviderTest.java
@@ -68,18 +68,13 @@
 @RunWith(AndroidJUnit4.class)
 public class BatteryUsageStatsProviderTest {
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
     private static final long MINUTE_IN_MS = 60 * 1000;
     private static final double PRECISION = 0.00001;
 
-    @Rule(order = 2)
+    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule =
             new BatteryUsageStatsRule(12345)
                     .createTempDirectory()
@@ -94,7 +89,7 @@
 
     @Before
     public void setup() throws IOException {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             mContext = mock(Context.class);
             SensorManager sensorManager = mock(SensorManager.class);
             when(mContext.getSystemService(SensorManager.class)).thenReturn(sensorManager);
@@ -420,7 +415,7 @@
         Parcel parcel = Parcel.obtain();
         parcel.writeParcelable(batteryUsageStats, 0);
 
-        if (!RavenwoodRule.isUnderRavenwood()) {
+        if (!RavenwoodRule.isOnRavenwood()) {
             assertThat(parcel.dataSize()).isAtMost(128_000);
         }
 
@@ -579,7 +574,7 @@
         MockBatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
         accumulateBatteryUsageStats(batteryStats, 10000000, 0);
         // Accumulate every 200 bytes of battery history
-        accumulateBatteryUsageStats(batteryStats, 200, 2);
+        accumulateBatteryUsageStats(batteryStats, 200, 1);
         accumulateBatteryUsageStats(batteryStats, 50, 5);
         // Accumulate on every invocation of accumulateBatteryUsageStats
         accumulateBatteryUsageStats(batteryStats, 0, 7);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
index 097a60e..dc1c3b4 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BatteryUsageStatsTest.java
@@ -37,7 +37,6 @@
 import android.os.Parcel;
 import android.os.UidBatteryConsumer;
 import android.os.UserBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.Xml;
 
 import androidx.test.filters.SmallTest;
@@ -46,7 +45,6 @@
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.modules.utils.TypedXmlSerializer;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -64,11 +62,6 @@
 @SmallTest
 @RunWith(AndroidJUnit4.class)
 public class BatteryUsageStatsTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final int USER_ID = 42;
     private static final int APP_UID1 = 271;
     private static final int APP_UID2 = 314;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
index c9cb0df..9552808 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerCalculatorTest.java
@@ -50,15 +50,10 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class BluetoothPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_IDLE, 10.0)
             .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_RX, 50.0)
@@ -335,7 +330,7 @@
     }
 
     private UidTraffic createUidTraffic(int appUid, long rxBytes, long txBytes) {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             UidTraffic uidTraffic = mock(UidTraffic.class);
             when(uidTraffic.getUid()).thenReturn(appUid);
             when(uidTraffic.getRxBytes()).thenReturn(rxBytes);
@@ -356,7 +351,7 @@
 
     private BluetoothActivityEnergyInfo createBtEnergyInfo(long timestamp, int stackState,
             long txTime, long rxTime, long idleTime, long energyUsed, List<UidTraffic> traffic) {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             BluetoothActivityEnergyInfo info = mock(BluetoothActivityEnergyInfo.class);
             when(info.getTimestampMillis()).thenReturn(timestamp);
             when(info.getBluetoothStackState()).thenReturn(stackState);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsCollectorTest.java
index 3895cb4..98ec6de 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/BluetoothPowerStatsCollectorTest.java
@@ -57,11 +57,6 @@
     private static final int ISOLATED_UID = 99123;
 
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setPowerStatsThrottlePeriodMillis(BatteryConsumer.POWER_COMPONENT_BLUETOOTH, 1000);
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
index 4cd3857..6745ffd 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CameraPowerCalculatorTest.java
@@ -21,7 +21,6 @@
 import android.os.BatteryConsumer;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -35,17 +34,12 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class CameraPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
     private static final int APP1_UID = Process.FIRST_APPLICATION_UID + 42;
     private static final int APP2_UID = Process.FIRST_APPLICATION_UID + 43;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_CAMERA, 360.0)
             .initMeasuredEnergyStatsLocked();
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
index 527db67..ee58d7e 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerCalculatorTest.java
@@ -32,7 +32,6 @@
 import android.os.BatteryUsageStatsQuery;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseArray;
 
 import androidx.test.filters.SmallTest;
@@ -56,11 +55,6 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class CpuPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
     private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42;
@@ -68,7 +62,7 @@
 
     private static final int NUM_CPU_FREQS = 2 + 2;  // 2 clusters * 2 freqs each
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_CPU_ACTIVE, 720)
             .setCpuScalingPolicy(0, new int[]{0, 1}, new int[]{100, 200})
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
index 1fea462..70f0370 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CpuPowerStatsCollectorTest.java
@@ -32,7 +32,6 @@
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.IndentingPrintWriter;
 import android.util.SparseArray;
 
@@ -46,7 +45,6 @@
 import com.android.server.power.stats.format.CpuPowerStatsLayout;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
@@ -60,11 +58,6 @@
 @SmallTest
 public class CpuPowerStatsCollectorTest {
 
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final int ISOLATED_UID = 99123;
     private static final int UID_1 = 42;
     private static final int UID_2 = 99;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java
index 5636242..b89310f 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/CustomEnergyConsumerPowerCalculatorTest.java
@@ -21,7 +21,6 @@
 import android.os.BatteryConsumer;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.SparseLongArray;
 
 import androidx.test.filters.SmallTest;
@@ -35,16 +34,11 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class CustomEnergyConsumerPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .initMeasuredEnergyStatsLocked(new String[]{"CUSTOM_COMPONENT1", "CUSTOM_COMPONENT2"});
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java
index 757025e..0d21349 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/FlashlightPowerCalculatorTest.java
@@ -21,7 +21,6 @@
 import android.os.BatteryConsumer;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -35,16 +34,11 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class FlashlightPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_FLASHLIGHT, 360.0);
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
index 506bab4..b7a0d3d5 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/GnssPowerCalculatorTest.java
@@ -21,7 +21,6 @@
 import android.os.BatteryConsumer;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -36,16 +35,12 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class GnssPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
     private static final double PRECISION = 0.00001;
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
     private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 222;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_GPS_ON, 360.0)
             .setAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED,
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java
index 487d864..f9f2119 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/IdlePowerCalculatorTest.java
@@ -19,7 +19,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.os.BatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -33,14 +32,9 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IdlePowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_CPU_IDLE, 720.0)
             .setAveragePower(PowerProfile.POWER_CPU_SUSPEND, 360.0);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java
index 3a27188..fc0ddeb 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MemoryPowerCalculatorTest.java
@@ -19,7 +19,6 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import android.os.BatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -33,14 +32,9 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class MemoryPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_MEMORY, new double[] {360.0, 720.0, 1080.0});
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
index eba820e..b95ff4c 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerCalculatorTest.java
@@ -62,18 +62,13 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class MobileRadioPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
     private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101;
     @Mock
     NetworkStatsManager mNetworkStatsManager;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule();
 
     @Test
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
index cd3683b..645411c 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/MobileRadioPowerStatsCollectorTest.java
@@ -75,11 +75,6 @@
     private static final int ISOLATED_UID = 99123;
 
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule =
             new BatteryUsageStatsRule().setPowerStatsThrottlePeriodMillis(
                     BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO, 10000);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsCollectorTest.java
index a04f721..8e7e437 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsCollectorTest.java
@@ -32,7 +32,6 @@
 import android.os.HandlerThread;
 import android.os.PersistableBundle;
 import android.platform.test.annotations.DisabledOnRavenwood;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.power.PowerStatsInternal;
 
 import androidx.test.filters.SmallTest;
@@ -41,7 +40,6 @@
 import com.android.internal.os.PowerStats;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -51,11 +49,6 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PowerStatsCollectorTest {
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private final MockClock mMockClock = new MockClock();
     private final HandlerThread mHandlerThread = new HandlerThread("test");
     private Handler mHandler;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java
index 143d046..2378715 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsSchedulerTest.java
@@ -18,11 +18,8 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.platform.test.ravenwood.RavenwoodRule;
-
 import androidx.test.runner.AndroidJUnit4;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
@@ -33,11 +30,6 @@
 
 @RunWith(AndroidJUnit4.class)
 public class PowerStatsSchedulerTest {
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     @Test
     public void alignToWallClock() {
         TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsStoreTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsStoreTest.java
index dc8d920..064d999b 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsStoreTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/PowerStatsStoreTest.java
@@ -21,7 +21,6 @@
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -29,7 +28,6 @@
 import com.android.modules.utils.TypedXmlSerializer;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.xmlpull.v1.XmlPullParser;
@@ -45,11 +43,6 @@
 public class PowerStatsStoreTest {
     private static final long MAX_BATTERY_STATS_SNAPSHOT_STORAGE_BYTES = 2 * 1024;
 
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private PowerStatsStore mPowerStatsStore;
     private File mStoreDirectory;
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
index 7f20035..101c362 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerCalculatorTest.java
@@ -25,7 +25,6 @@
 import android.os.BatteryConsumer;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.view.Display;
 
 import androidx.test.filters.SmallTest;
@@ -39,18 +38,13 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class ScreenPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42;
     private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 43;
     private static final long MINUTE_IN_MS = 60 * 1000;
     private static final long MINUTE_IN_US = 60 * 1000 * 1000;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_ON, 0, 36.0)
             .setAveragePowerForOrdinal(POWER_GROUP_DISPLAY_SCREEN_FULL, 0, 48.0)
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsCollectorTest.java
index 8c09d1d..c87f04d 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/ScreenPowerStatsCollectorTest.java
@@ -28,7 +28,6 @@
 import android.os.BatteryConsumer;
 import android.os.BatteryStats;
 import android.os.Handler;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import com.android.internal.os.Clock;
 import com.android.internal.os.PowerStats;
@@ -47,11 +46,6 @@
     private static final int ISOLATED_UID = 99123;
 
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setPowerStatsThrottlePeriodMillis(BatteryConsumer.POWER_COMPONENT_SCREEN, 1000);
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java
index c01f05f..0a42170 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/SensorPowerCalculatorTest.java
@@ -41,11 +41,6 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SensorPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
     private static final int SENSOR_HANDLE_1 = 1;
@@ -53,7 +48,7 @@
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule();
 
     @Test
@@ -93,7 +88,7 @@
     }
 
     private Sensor createSensor(int handle, int type, float power) {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             Sensor sensor = mock(Sensor.class);
 
             when(sensor.getHandle()).thenReturn(handle);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java
index b9b7101..e70f7df 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/VideoPowerCalculatorTest.java
@@ -21,7 +21,6 @@
 import android.os.BatteryConsumer;
 import android.os.Process;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
@@ -35,16 +34,11 @@
 @RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VideoPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_VIDEO, 360.0);
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java
index 9645e90..cfae6b1 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WakelockPowerCalculatorTest.java
@@ -43,7 +43,6 @@
     @Rule(order = 0)
     public final RavenwoodRule mRavenwood =
             new RavenwoodRule.Builder()
-                    .setProvideMainThread(true)
                     .setSystemPropertyImmutable(
                             "persist.sys.com.android.server.power.feature.flags."
                                     + "framework_wakelock_info-override",
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
index 827d2f8..0ec0575 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerCalculatorTest.java
@@ -54,11 +54,6 @@
 @SmallTest
 @SuppressWarnings("GuardedBy")
 public class WifiPowerCalculatorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
 
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
@@ -66,7 +61,7 @@
     @Mock
     NetworkStatsManager mNetworkStatsManager;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_IDLE, 360.0)
             .setAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_RX, 480.0)
@@ -92,7 +87,7 @@
 
     private NetworkStats buildNetworkStats(long elapsedRealtime, long rxBytes, long rxPackets,
             long txBytes, long txPackets) {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             NetworkStats stats = mock(NetworkStats.class);
 //        when(stats.getElapsedRealtime()).thenReturn(elapsedRealtime);
 
@@ -358,7 +353,7 @@
     private WifiActivityEnergyInfo buildWifiActivityEnergyInfo(long timeSinceBoot,
             int stackState, long txDuration, long rxDuration, long scanDuration,
             long idleDuration) {
-        if (RavenwoodRule.isUnderRavenwood()) {
+        if (RavenwoodRule.isOnRavenwood()) {
             WifiActivityEnergyInfo info = mock(WifiActivityEnergyInfo.class);
             when(info.getTimeSinceBootMillis()).thenReturn(timeSinceBoot);
             when(info.getStackState()).thenReturn(stackState);
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
index a26b2c9..3e15c0e2 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/WifiPowerStatsCollectorTest.java
@@ -68,11 +68,6 @@
     private static final int ISOLATED_UID = 99123;
 
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setPowerStatsThrottlePeriodMillis(BatteryConsumer.POWER_COMPONENT_WIFI, 1000);
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/AmbientDisplayPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/AmbientDisplayPowerStatsProcessorTest.java
index 58e9d1e..7ca3a9d 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/AmbientDisplayPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/AmbientDisplayPowerStatsProcessorTest.java
@@ -31,7 +31,6 @@
 import android.hardware.power.stats.EnergyConsumerType;
 import android.os.BatteryConsumer;
 import android.os.Handler;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import com.android.internal.os.Clock;
 import com.android.internal.os.PowerProfile;
@@ -52,11 +51,6 @@
 public class AmbientDisplayPowerStatsProcessorTest {
 
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setNumDisplays(2)
             .setAveragePowerForOrdinal(PowerProfile.POWER_GROUP_DISPLAY_AMBIENT, 0, 180.0)
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BinaryStatePowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BinaryStatePowerStatsProcessorTest.java
index e6e7f6e..10d5e80 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BinaryStatePowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BinaryStatePowerStatsProcessorTest.java
@@ -35,7 +35,6 @@
 import android.os.BatteryStats;
 import android.os.PersistableBundle;
 import android.os.Process;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.annotation.NonNull;
 
@@ -44,17 +43,11 @@
 import com.android.server.power.stats.MockClock;
 import com.android.server.power.stats.format.BinaryStatePowerStatsLayout;
 
-import org.junit.Rule;
 import org.junit.Test;
 
 import java.util.function.Supplier;
 
 public class BinaryStatePowerStatsProcessorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42;
     private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BluetoothPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BluetoothPowerStatsProcessorTest.java
index 6d7119d..d8328bf 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BluetoothPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/BluetoothPowerStatsProcessorTest.java
@@ -69,18 +69,13 @@
 
 public class BluetoothPowerStatsProcessorTest {
 
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42;
     private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101;
     private static final int BLUETOOTH_ENERGY_CONSUMER_ID = 1;
     private static final int VOLTAGE_MV = 3500;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_RX, 50.0)
             .setAveragePower(PowerProfile.POWER_BLUETOOTH_CONTROLLER_TX, 100.0)
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CameraPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CameraPowerStatsTest.java
index a959632..2244b73 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CameraPowerStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CameraPowerStatsTest.java
@@ -40,7 +40,6 @@
 import android.os.BatteryStats;
 import android.os.Handler;
 import android.os.Process;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import com.android.internal.os.Clock;
 import com.android.internal.os.MonotonicClock;
@@ -63,11 +62,6 @@
 
 public class CameraPowerStatsTest {
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_CAMERA, 100.0)
             .initMeasuredEnergyStatsLocked();
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CpuPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CpuPowerStatsProcessorTest.java
index dcddf06..3bc97bd 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CpuPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CpuPowerStatsProcessorTest.java
@@ -33,7 +33,6 @@
 
 import android.os.BatteryConsumer;
 import android.os.PersistableBundle;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.util.IntArray;
 import android.util.LongArray;
 
@@ -60,11 +59,6 @@
 @SmallTest
 public class CpuPowerStatsProcessorTest {
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_CPU_ACTIVE, 720)
             .setCpuScalingPolicy(0, new int[]{0, 1}, new int[]{100, 200})
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CustomEnergyConsumerPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CustomEnergyConsumerPowerStatsTest.java
index a421675..c18bc3e 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CustomEnergyConsumerPowerStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/CustomEnergyConsumerPowerStatsTest.java
@@ -39,7 +39,6 @@
 import android.hardware.power.stats.EnergyConsumerType;
 import android.os.Handler;
 import android.os.Process;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import com.android.internal.os.Clock;
 import com.android.internal.os.PowerStats;
@@ -64,11 +63,6 @@
 
 public class CustomEnergyConsumerPowerStatsTest {
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule();
 
     public static final int ENERGY_CONSUMER_ID1 = 77;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/GnssPowerStatsTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/GnssPowerStatsTest.java
index b4f2113..9071389 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/GnssPowerStatsTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/GnssPowerStatsTest.java
@@ -41,7 +41,6 @@
 import android.os.BatteryStats;
 import android.os.Handler;
 import android.os.Process;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import com.android.internal.os.Clock;
 import com.android.internal.os.MonotonicClock;
@@ -64,11 +63,6 @@
 
 public class GnssPowerStatsTest {
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_GPS_ON, 100.0)
             .setAveragePower(PowerProfile.POWER_GPS_SIGNAL_QUALITY_BASED, new double[]{1000, 100})
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MobileRadioPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MobileRadioPowerStatsProcessorTest.java
index 3dc4017..95bf931 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MobileRadioPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MobileRadioPowerStatsProcessorTest.java
@@ -73,18 +73,13 @@
 import java.util.function.Supplier;
 
 public class MobileRadioPowerStatsProcessorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
     private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101;
     private static final int MOBILE_RADIO_ENERGY_CONSUMER_ID = 1;
     private static final int VOLTAGE_MV = 3500;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule();
     @Mock
     private Context mContext;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MultiStatePowerAttributorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MultiStatePowerAttributorTest.java
index 704ee62..14dd975 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MultiStatePowerAttributorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/MultiStatePowerAttributorTest.java
@@ -27,7 +27,6 @@
 import android.os.ConditionVariable;
 import android.os.Handler;
 import android.os.HandlerThread;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import com.android.internal.os.BatteryStatsHistory;
 import com.android.internal.os.MonotonicClock;
@@ -37,7 +36,6 @@
 import com.android.server.power.stats.PowerStatsStore;
 
 import org.junit.Before;
-import org.junit.Rule;
 import org.junit.Test;
 
 import java.io.IOException;
@@ -52,11 +50,6 @@
 
 public class MultiStatePowerAttributorTest {
 
-    @Rule
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private PowerStatsStore mPowerStatsStore;
     private Handler mHandler;
     private final MockClock mClock = new MockClock();
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PhoneCallPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PhoneCallPowerStatsProcessorTest.java
index 2f742d7..742f250 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PhoneCallPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PhoneCallPowerStatsProcessorTest.java
@@ -37,7 +37,6 @@
 import android.os.BatteryConsumer;
 import android.os.Handler;
 import android.os.OutcomeReceiver;
-import android.platform.test.ravenwood.RavenwoodRule;
 import android.telephony.ModemActivityInfo;
 import android.telephony.TelephonyManager;
 
@@ -59,15 +58,10 @@
 import java.util.function.Supplier;
 
 public class PhoneCallPowerStatsProcessorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final int VOLTAGE_MV = 3500;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule();
     @Mock
     private Context mContext;
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
index 9ef58cc..a5a29f5 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/PowerStatsExporterTest.java
@@ -33,7 +33,6 @@
 import android.os.Parcel;
 import android.os.PersistableBundle;
 import android.os.UidBatteryConsumer;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import androidx.test.runner.AndroidJUnit4;
 
@@ -67,11 +66,6 @@
     private static final double TOLERANCE = 0.01;
 
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_CPU_ACTIVE, 720)
             .setCpuScalingPolicy(0, new int[]{0}, new int[]{100})
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/ScreenPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/ScreenPowerStatsProcessorTest.java
index 31456a15..1ca62b4 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/ScreenPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/ScreenPowerStatsProcessorTest.java
@@ -36,7 +36,6 @@
 import android.os.BatteryStats;
 import android.os.Handler;
 import android.os.Process;
-import android.platform.test.ravenwood.RavenwoodRule;
 
 import com.android.internal.os.Clock;
 import com.android.internal.os.PowerProfile;
@@ -59,11 +58,6 @@
 public class ScreenPowerStatsProcessorTest {
 
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setNumDisplays(2)
             .setAveragePowerForOrdinal(PowerProfile.POWER_GROUP_DISPLAY_AMBIENT, 0, 180.0)
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/SensorPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/SensorPowerStatsProcessorTest.java
index c2f01d1..3c8a580 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/SensorPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/SensorPowerStatsProcessorTest.java
@@ -58,11 +58,6 @@
 
 public class SensorPowerStatsProcessorTest {
     @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
-    @Rule(order = 1)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .initMeasuredEnergyStatsLocked();
 
diff --git a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WifiPowerStatsProcessorTest.java b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WifiPowerStatsProcessorTest.java
index e36056a..d4e6810 100644
--- a/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WifiPowerStatsProcessorTest.java
+++ b/services/tests/powerstatstests/src/com/android/server/power/stats/processor/WifiPowerStatsProcessorTest.java
@@ -74,18 +74,13 @@
 import java.util.function.Supplier;
 
 public class WifiPowerStatsProcessorTest {
-    @Rule(order = 0)
-    public final RavenwoodRule mRavenwood = new RavenwoodRule.Builder()
-            .setProvideMainThread(true)
-            .build();
-
     private static final double PRECISION = 0.00001;
     private static final int APP_UID1 = Process.FIRST_APPLICATION_UID + 42;
     private static final int APP_UID2 = Process.FIRST_APPLICATION_UID + 101;
     private static final int WIFI_ENERGY_CONSUMER_ID = 1;
     private static final int VOLTAGE_MV = 3500;
 
-    @Rule(order = 1)
+    @Rule(order = 0)
     public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
             .setAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_IDLE, 360.0)
             .setAveragePower(PowerProfile.POWER_WIFI_CONTROLLER_RX, 480.0)
diff --git a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
index 75df9a8..d254e96 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkScoreServiceTest.java
@@ -35,7 +35,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.Manifest.permission;
@@ -243,7 +242,7 @@
     @Test
     public void testRequestScores_providerNotConnected() throws Exception {
         assertFalse(mNetworkScoreService.requestScores(new NetworkKey[0]));
-        verifyZeroInteractions(mRecommendationProvider);
+        verifyNoMoreInteractions(mRecommendationProvider);
     }
 
     @Test
@@ -604,7 +603,7 @@
         consumer.accept(mNetworkScoreCache, null /*cookie*/);
 
         verify(mNetworkScoreCache).updateScores(scoredNetworkList);
-        verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter);
+        verifyNoMoreInteractions(mCurrentNetworkFilter, mScanResultsFilter);
     }
 
     @Test
@@ -618,7 +617,7 @@
         consumer.accept(mNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_NONE);
 
         verify(mNetworkScoreCache).updateScores(scoredNetworkList);
-        verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter);
+        verifyNoMoreInteractions(mCurrentNetworkFilter, mScanResultsFilter);
     }
 
     @Test
@@ -632,7 +631,7 @@
         consumer.accept(mNetworkScoreCache, -1 /*cookie*/);
 
         verify(mNetworkScoreCache).updateScores(scoredNetworkList);
-        verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter);
+        verifyNoMoreInteractions(mCurrentNetworkFilter, mScanResultsFilter);
     }
 
     @Test
@@ -646,7 +645,7 @@
         consumer.accept(mNetworkScoreCache, "not an int" /*cookie*/);
 
         verify(mNetworkScoreCache).updateScores(scoredNetworkList);
-        verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter);
+        verifyNoMoreInteractions(mCurrentNetworkFilter, mScanResultsFilter);
     }
 
     @Test
@@ -658,7 +657,7 @@
 
         consumer.accept(mNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_NONE);
 
-        verifyZeroInteractions(mNetworkScoreCache, mCurrentNetworkFilter, mScanResultsFilter);
+        verifyNoMoreInteractions(mNetworkScoreCache, mCurrentNetworkFilter, mScanResultsFilter);
     }
 
     @Test
@@ -676,7 +675,7 @@
         consumer.accept(mNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_CURRENT_NETWORK);
 
         verify(mNetworkScoreCache).updateScores(filteredList);
-        verifyZeroInteractions(mScanResultsFilter);
+        verifyNoMoreInteractions(mScanResultsFilter);
     }
 
     @Test
@@ -694,7 +693,7 @@
         consumer.accept(mNetworkScoreCache, NetworkScoreManager.SCORE_FILTER_SCAN_RESULTS);
 
         verify(mNetworkScoreCache).updateScores(filteredList);
-        verifyZeroInteractions(mCurrentNetworkFilter);
+        verifyNoMoreInteractions(mCurrentNetworkFilter);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
index 42b84bd..c7c8c58 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
@@ -64,7 +64,6 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.accessibilityservice.AccessibilityService;
@@ -838,7 +837,7 @@
         // ...without secure layers included
         assertThat(layerArgsCaptor.getValue().mCaptureSecureLayers).isFalse();
         // No error sent to callback
-        verifyZeroInteractions(mMockCallback);
+        verifyNoMoreInteractions(mMockCallback);
     }
 
     @Test
@@ -856,7 +855,7 @@
         // ...with secure layers included
         assertThat(layerArgsCaptor.getValue().mCaptureSecureLayers).isTrue();
         // No error sent to callback
-        verifyZeroInteractions(mMockCallback);
+        verifyNoMoreInteractions(mMockCallback);
     }
 
     @Test
@@ -889,7 +888,7 @@
         // ...with secure layers included
         assertThat(layerArgsCaptor.getValue().mCaptureSecureLayers).isTrue();
         // No error sent to callback
-        verifyZeroInteractions(mMockCallback);
+        verifyNoMoreInteractions(mMockCallback);
     }
 
     private void takeScreenshotOfWindow(int windowFlags) throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
index 8253595..2ccd336 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityManagerServiceTest.java
@@ -50,6 +50,7 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.atLeastOnce;
 import static org.mockito.Mockito.doAnswer;
@@ -66,6 +67,7 @@
 import android.accessibilityservice.AccessibilityServiceInfo;
 import android.accessibilityservice.IAccessibilityServiceClient;
 import android.annotation.NonNull;
+import android.annotation.Nullable;
 import android.annotation.UserIdInt;
 import android.app.PendingIntent;
 import android.app.RemoteAction;
@@ -77,10 +79,12 @@
 import android.content.IntentFilter;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
 import android.content.res.XmlResourceParser;
 import android.graphics.drawable.Icon;
+import android.hardware.display.DisplayManager;
 import android.hardware.display.DisplayManagerGlobal;
 import android.hardware.input.KeyGestureEvent;
 import android.net.Uri;
@@ -114,6 +118,7 @@
 
 import androidx.test.core.app.ApplicationProvider;
 import androidx.test.filters.SmallTest;
+import androidx.test.platform.app.InstrumentationRegistry;
 
 import com.android.compatibility.common.util.TestUtils;
 import com.android.internal.R;
@@ -136,6 +141,8 @@
 import com.android.server.wm.ActivityTaskManagerInternal;
 import com.android.server.wm.WindowManagerInternal;
 
+import com.google.common.truth.Correspondence;
+
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
@@ -188,6 +195,8 @@
             DESCRIPTION,
             TEST_PENDING_INTENT);
 
+    private static final int FAKE_SYSTEMUI_UID = 1000;
+
     private static final int TEST_DISPLAY = Display.DEFAULT_DISPLAY + 1;
     private static final String TARGET_MAGNIFICATION = MAGNIFICATION_CONTROLLER_NAME;
     private static final ComponentName TARGET_ALWAYS_ON_A11Y_SERVICE =
@@ -207,11 +216,12 @@
     @Mock private AbstractAccessibilityServiceConnection.SystemSupport mMockSystemSupport;
     @Mock private WindowManagerInternal.AccessibilityControllerInternal mMockA11yController;
     @Mock private PackageManager mMockPackageManager;
+    @Mock
+    private PackageManagerInternal mMockPackageManagerInternal;
     @Mock private WindowManagerInternal mMockWindowManagerService;
     @Mock private AccessibilitySecurityPolicy mMockSecurityPolicy;
     @Mock private SystemActionPerformer mMockSystemActionPerformer;
     @Mock private AccessibilityWindowManager mMockA11yWindowManager;
-    @Mock private AccessibilityDisplayListener mMockA11yDisplayListener;
     @Mock private ActivityTaskManagerInternal mMockActivityTaskManagerInternal;
     @Mock private UserManagerInternal mMockUserManagerInternal;
     @Mock private IBinder mMockBinder;
@@ -234,6 +244,7 @@
     private TestableLooper mTestableLooper;
     private Handler mHandler;
     private FakePermissionEnforcer mFakePermissionEnforcer;
+    private TestDisplayManagerWrapper mTestDisplayManagerWrapper;
 
     @Before
     public void setUp() throws Exception {
@@ -246,6 +257,7 @@
         LocalServices.removeServiceForTest(UserManagerInternal.class);
         LocalServices.removeServiceForTest(StatusBarManagerInternal.class);
         LocalServices.removeServiceForTest(PermissionEnforcer.class);
+        LocalServices.removeServiceForTest(PackageManagerInternal.class);
         LocalServices.addService(
                 WindowManagerInternal.class, mMockWindowManagerService);
         LocalServices.addService(
@@ -256,6 +268,12 @@
         mInputFilter = mock(FakeInputFilter.class);
         mTestableContext.addMockSystemService(DevicePolicyManager.class, mDevicePolicyManager);
 
+        when(mMockPackageManagerInternal.getSystemUiServiceComponent()).thenReturn(
+                new ComponentName("com.android.systemui", "com.android.systemui.SystemUIService"));
+        when(mMockPackageManagerInternal.getPackageUid(eq("com.android.systemui"), anyLong(),
+                anyInt())).thenReturn(FAKE_SYSTEMUI_UID);
+        LocalServices.addService(PackageManagerInternal.class, mMockPackageManagerInternal);
+
         when(mMockMagnificationController.getMagnificationConnectionManager()).thenReturn(
                 mMockMagnificationConnectionManager);
         when(mMockMagnificationController.getFullScreenMagnificationController()).thenReturn(
@@ -273,15 +291,9 @@
                 eq(UserHandle.USER_CURRENT)))
                 .thenReturn(mTestableContext.getUserId());
 
-        final ArrayList<Display> displays = new ArrayList<>();
-        final Display defaultDisplay = new Display(DisplayManagerGlobal.getInstance(),
-                Display.DEFAULT_DISPLAY, new DisplayInfo(),
-                DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
-        final Display testDisplay = new Display(DisplayManagerGlobal.getInstance(), TEST_DISPLAY,
-                new DisplayInfo(), DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
-        displays.add(defaultDisplay);
-        displays.add(testDisplay);
-        when(mMockA11yDisplayListener.getValidDisplayList()).thenReturn(displays);
+        mTestDisplayManagerWrapper = new TestDisplayManagerWrapper(mTestableContext);
+        mTestDisplayManagerWrapper.mDisplays = createFakeDisplayList(Display.TYPE_INTERNAL,
+                Display.TYPE_EXTERNAL);
 
         mA11yms = new AccessibilityManagerService(
                 mTestableContext,
@@ -290,7 +302,7 @@
                 mMockSecurityPolicy,
                 mMockSystemActionPerformer,
                 mMockA11yWindowManager,
-                mMockA11yDisplayListener,
+                mTestDisplayManagerWrapper,
                 mMockMagnificationController,
                 mInputFilter,
                 mProxyManager,
@@ -2309,6 +2321,73 @@
                 mA11yms.getCurrentUserIdLocked())).isEmpty();
     }
 
+    @Test
+    public void displayListReturnsDisplays() {
+        mTestDisplayManagerWrapper.mDisplays = createFakeDisplayList(
+                        Display.TYPE_INTERNAL,
+                        Display.TYPE_EXTERNAL,
+                        Display.TYPE_WIFI,
+                        Display.TYPE_OVERLAY,
+                        Display.TYPE_VIRTUAL
+        );
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            // In #setUp() we already have TYPE_INTERNAL and TYPE_EXTERNAL. Call the rest.
+            for (int i = 2; i < mTestDisplayManagerWrapper.mDisplays.size(); i++) {
+                mTestDisplayManagerWrapper.mRegisteredListener.onDisplayAdded(
+                        mTestDisplayManagerWrapper.mDisplays.get(i).getDisplayId());
+            }
+        });
+
+        List<Display> displays = mA11yms.getValidDisplayList();
+        assertThat(displays).hasSize(5);
+        assertThat(displays)
+                .comparingElementsUsing(
+                        Correspondence.transforming(Display::getType, "has a type of"))
+                .containsExactly(Display.TYPE_INTERNAL,
+                        Display.TYPE_EXTERNAL,
+                        Display.TYPE_WIFI,
+                        Display.TYPE_OVERLAY,
+                        Display.TYPE_VIRTUAL);
+    }
+
+    @Test
+    public void displayListReturnsDisplays_excludesVirtualPrivate() {
+        // Add a private virtual display whose uid is different from systemui.
+        final List<Display> displays = createFakeDisplayList(Display.TYPE_INTERNAL,
+                Display.TYPE_EXTERNAL);
+        displays.add(createFakeVirtualPrivateDisplay(/* displayId= */ 2, FAKE_SYSTEMUI_UID + 100));
+        mTestDisplayManagerWrapper.mDisplays = displays;
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            mTestDisplayManagerWrapper.mRegisteredListener.onDisplayAdded(2);
+        });
+
+        List<Display> validDisplays = mA11yms.getValidDisplayList();
+        assertThat(validDisplays).hasSize(2);
+        assertThat(validDisplays)
+                .comparingElementsUsing(
+                        Correspondence.transforming(Display::getType, "has a type of"))
+                .doesNotContain(Display.TYPE_VIRTUAL);
+    }
+
+    @Test
+    public void displayListReturnsDisplays_includesVirtualSystemUIPrivate() {
+        // Add a private virtual display whose uid is systemui.
+        final List<Display> displays = createFakeDisplayList(Display.TYPE_INTERNAL,
+                Display.TYPE_EXTERNAL);
+        displays.add(createFakeVirtualPrivateDisplay(/* displayId= */ 2, FAKE_SYSTEMUI_UID));
+        mTestDisplayManagerWrapper.mDisplays = displays;
+        InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
+            mTestDisplayManagerWrapper.mRegisteredListener.onDisplayAdded(2);
+        });
+
+        List<Display> validDisplays = mA11yms.getValidDisplayList();
+        assertThat(validDisplays).hasSize(3);
+        assertThat(validDisplays)
+                .comparingElementsUsing(
+                        Correspondence.transforming(Display::getType, "has a type of"))
+                .contains(Display.TYPE_VIRTUAL);
+    }
+
     private Set<String> readStringsFromSetting(String setting) {
         final Set<String> result = new ArraySet<>();
         mA11yms.readColonDelimitedSettingToSet(
@@ -2422,6 +2501,27 @@
                 });
     }
 
+    private static List<Display> createFakeDisplayList(int... types) {
+        final ArrayList<Display> displays = new ArrayList<>();
+        for (int i = 0; i < types.length; i++) {
+            final DisplayInfo info = new DisplayInfo();
+            info.type = types[i];
+            final Display display = new Display(DisplayManagerGlobal.getInstance(),
+                    i, info, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+            displays.add(display);
+        }
+        return displays;
+    }
+
+    private static Display createFakeVirtualPrivateDisplay(int displayId, int uid) {
+        final DisplayInfo info = new DisplayInfo();
+        info.type = Display.TYPE_VIRTUAL;
+        info.flags |= Display.FLAG_PRIVATE;
+        info.ownerUid = uid;
+        return new Display(DisplayManagerGlobal.getInstance(),
+                displayId, info, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS);
+    }
+
     public static class FakeInputFilter extends AccessibilityInputFilter {
         FakeInputFilter(Context context,
                 AccessibilityManagerService service) {
@@ -2506,4 +2606,35 @@
         Set<String> setting = readStringsFromSetting(ShortcutUtils.convertToKey(shortcutType));
         assertThat(setting).containsExactlyElementsIn(value);
     }
+
+    private static class TestDisplayManagerWrapper extends
+            AccessibilityDisplayListener.DisplayManagerWrapper {
+        List<Display> mDisplays;
+        DisplayManager.DisplayListener mRegisteredListener;
+
+        TestDisplayManagerWrapper(Context context) {
+            super(context);
+        }
+
+        @Override
+        public Display[] getDisplays() {
+            return mDisplays.toArray(new Display[0]);
+        }
+
+        @Override
+        public Display getDisplay(int displayId) {
+            for (final Display display : mDisplays) {
+                if (display.getDisplayId() == displayId) {
+                    return display;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public void registerDisplayListener(@NonNull DisplayManager.DisplayListener listener,
+                @Nullable Handler handler) {
+            mRegisteredListener = listener;
+        }
+    }
 }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureControllerTest.java
index 96ae102e5..d0dc2cb 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/FingerprintGestureControllerTest.java
@@ -24,7 +24,7 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.accessibilityservice.FingerprintGestureController;
@@ -86,7 +86,7 @@
                 mMockFingerprintGestureCallback);
         mFingerprintGestureController.onGestureDetectionActiveChanged(true);
         mFingerprintGestureController.onGestureDetectionActiveChanged(false);
-        verifyZeroInteractions(mMockFingerprintGestureCallback);
+        verifyNoMoreInteractions(mMockFingerprintGestureCallback);
     }
 
     @Test
@@ -118,7 +118,7 @@
         mFingerprintGestureController.onGestureDetectionActiveChanged(true);
         mFingerprintGestureController.onGestureDetectionActiveChanged(false);
         assertFalse(messageCapturingHandler.hasMessages());
-        verifyZeroInteractions(mMockFingerprintGestureCallback);
+        verifyNoMoreInteractions(mMockFingerprintGestureCallback);
 
         messageCapturingHandler.removeAllMessages();
     }
@@ -135,7 +135,7 @@
         mFingerprintGestureController.unregisterFingerprintGestureCallback(
                 mMockFingerprintGestureCallback);
         mFingerprintGestureController.onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
-        verifyZeroInteractions(mMockFingerprintGestureCallback);
+        verifyNoMoreInteractions(mMockFingerprintGestureCallback);
     }
 
     @Test
@@ -159,7 +159,7 @@
                 mMockFingerprintGestureCallback);
         mFingerprintGestureController.onGesture(FINGERPRINT_GESTURE_SWIPE_DOWN);
         assertFalse(messageCapturingHandler.hasMessages());
-        verifyZeroInteractions(mMockFingerprintGestureCallback);
+        verifyNoMoreInteractions(mMockFingerprintGestureCallback);
 
         messageCapturingHandler.removeAllMessages();
     }
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java
index 63c572a..33529c3 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/HearingDevicePhoneCallNotificationControllerTest.java
@@ -25,6 +25,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
@@ -36,6 +37,8 @@
 import android.media.AudioDeviceInfo;
 import android.media.AudioDevicePort;
 import android.media.AudioManager;
+import android.platform.test.annotations.EnableFlags;
+import android.platform.test.flag.junit.SetFlagsRule;
 import android.telephony.TelephonyCallback;
 import android.telephony.TelephonyManager;
 
@@ -67,6 +70,8 @@
 public class HearingDevicePhoneCallNotificationControllerTest {
     @Rule
     public MockitoRule mockito = MockitoJUnit.rule();
+    @Rule
+    public SetFlagsRule mSetFlagsRule = new SetFlagsRule();
 
     private static final String TEST_ADDRESS = "55:66:77:88:99:AA";
 
@@ -118,6 +123,7 @@
                 AudioManager.DEVICE_OUT_BLE_HEADSET);
         when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
                 new AudioDeviceInfo[]{hapDeviceInfo});
+        when(mAudioManager.getCommunicationDevice()).thenReturn(hapDeviceInfo);
         when(mAudioManager.getAvailableCommunicationDevices()).thenReturn(List.of(hapDeviceInfo));
 
         mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
@@ -132,6 +138,7 @@
                 AudioManager.DEVICE_OUT_BLUETOOTH_A2DP);
         when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
                 new AudioDeviceInfo[]{a2dpDeviceInfo});
+        when(mAudioManager.getCommunicationDevice()).thenReturn(a2dpDeviceInfo);
         when(mAudioManager.getAvailableCommunicationDevices()).thenReturn(List.of(a2dpDeviceInfo));
 
         mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
@@ -146,6 +153,7 @@
                 AudioManager.DEVICE_OUT_BLE_HEADSET);
         when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
                 new AudioDeviceInfo[]{hapDeviceInfo});
+        when(mAudioManager.getCommunicationDevice()).thenReturn(hapDeviceInfo);
         when(mAudioManager.getAvailableCommunicationDevices()).thenReturn(List.of(hapDeviceInfo));
 
         mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
@@ -155,6 +163,68 @@
                 eq(SystemMessageProto.SystemMessage.NOTE_HEARING_DEVICE_INPUT_SWITCH));
     }
 
+    @Test
+    @EnableFlags(Flags.FLAG_HEARING_INPUT_CHANGE_WHEN_COMM_DEVICE)
+    public void onCallStateChanged_nonHearingDevice_offHookThenIdle_callAddAndRemoveListener() {
+        final ArgumentCaptor<AudioManager.OnCommunicationDeviceChangedListener> listenerCaptor =
+                ArgumentCaptor.forClass(AudioManager.OnCommunicationDeviceChangedListener.class);
+        AudioDeviceInfo a2dpDeviceInfo = createAudioDeviceInfo(TEST_ADDRESS,
+                AudioManager.DEVICE_OUT_BLUETOOTH_A2DP);
+        when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
+                new AudioDeviceInfo[]{a2dpDeviceInfo});
+        when(mAudioManager.getCommunicationDevice()).thenReturn(a2dpDeviceInfo);
+
+        mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
+        mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_IDLE);
+
+        verify(mAudioManager).addOnCommunicationDeviceChangedListener(any(Executor.class),
+                listenerCaptor.capture());
+        verify(mAudioManager).removeOnCommunicationDeviceChangedListener(
+                eq(listenerCaptor.getValue()));
+    }
+
+
+    @Test
+    @EnableFlags(Flags.FLAG_HEARING_INPUT_CHANGE_WHEN_COMM_DEVICE)
+    public void onCallStateChanged_hearingDeviceFromCommunicationDeviceChanged_showNotification() {
+        final ArgumentCaptor<AudioManager.OnCommunicationDeviceChangedListener> listenerCaptor =
+                ArgumentCaptor.forClass(AudioManager.OnCommunicationDeviceChangedListener.class);
+        AudioDeviceInfo hapDeviceInfo = createAudioDeviceInfo(TEST_ADDRESS,
+                AudioManager.DEVICE_OUT_BLE_HEADSET);
+        AudioDeviceInfo a2dpDeviceInfo = createAudioDeviceInfo(TEST_ADDRESS,
+                AudioManager.DEVICE_OUT_BLUETOOTH_A2DP);
+        when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
+                new AudioDeviceInfo[]{a2dpDeviceInfo});
+        when(mAudioManager.getCommunicationDevice()).thenReturn(a2dpDeviceInfo);
+
+        mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
+        verify(mAudioManager).addOnCommunicationDeviceChangedListener(any(Executor.class),
+                listenerCaptor.capture());
+        when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
+                new AudioDeviceInfo[]{hapDeviceInfo});
+        listenerCaptor.getValue().onCommunicationDeviceChanged(hapDeviceInfo);
+
+        verify(mNotificationManager).notify(
+                eq(SystemMessageProto.SystemMessage.NOTE_HEARING_DEVICE_INPUT_SWITCH), any());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_HEARING_INPUT_CHANGE_WHEN_COMM_DEVICE)
+    public void onCallStateChanged_offHookMultiple_addListenerOnlyOneTime() {
+        AudioDeviceInfo a2dpDeviceInfo = createAudioDeviceInfo(TEST_ADDRESS,
+                AudioManager.DEVICE_OUT_BLUETOOTH_A2DP);
+        when(mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS)).thenReturn(
+                new AudioDeviceInfo[]{a2dpDeviceInfo});
+        when(mAudioManager.getCommunicationDevice()).thenReturn(a2dpDeviceInfo);
+
+        mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
+        mTestCallStateListener.onCallStateChanged(TelephonyManager.CALL_STATE_OFFHOOK);
+
+        verify(mAudioManager, times(1)).addOnCommunicationDeviceChangedListener(
+                any(Executor.class),
+                any(AudioManager.OnCommunicationDeviceChangedListener.class));
+    }
+
     private AudioDeviceInfo createAudioDeviceInfo(String address, int type) {
         AudioDevicePort audioDevicePort = mock(AudioDevicePort.class);
         doReturn(type).when(audioDevicePort).type();
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/KeyEventDispatcherTest.java b/services/tests/servicestests/src/com/android/server/accessibility/KeyEventDispatcherTest.java
index c3256ca..186f742 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/KeyEventDispatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/KeyEventDispatcherTest.java
@@ -27,7 +27,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 
@@ -159,7 +159,7 @@
                 mFilter1SequenceCaptor.getValue());
 
         assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT));
-        verifyZeroInteractions(mMockPowerManagerService);
+        verifyNoMoreInteractions(mMockPowerManagerService);
         assertFalse(isTimeoutPending(mMessageCapturingHandler));
     }
 
@@ -189,7 +189,7 @@
                 mFilter2SequenceCaptor.getValue());
 
         assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT));
-        verifyZeroInteractions(mMockPowerManagerService);
+        verifyNoMoreInteractions(mMockPowerManagerService);
         assertFalse(isTimeoutPending(mMessageCapturingHandler));
     }
 
@@ -261,7 +261,7 @@
         mKeyEventDispatcher.setOnKeyEventResult(mKeyEventFilter2, false,
                 mFilter2SequenceCaptor.getValue());
         assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT));
-        verifyZeroInteractions(mMockPowerManagerService);
+        verifyNoMoreInteractions(mMockPowerManagerService);
         assertFalse(isTimeoutPending(mMessageCapturingHandler));
     }
 
@@ -278,7 +278,7 @@
         mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0));
 
         assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT));
-        verifyZeroInteractions(mMockPowerManagerService);
+        verifyNoMoreInteractions(mMockPowerManagerService);
     }
 
     @Test
@@ -293,7 +293,7 @@
         mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0));
 
         assertTrue(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT));
-        verifyZeroInteractions(mMockPowerManagerService);
+        verifyNoMoreInteractions(mMockPowerManagerService);
     }
 
     @Test
@@ -327,7 +327,7 @@
                 mFilter1SequenceCaptor.getValue());
 
         assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT));
-        verifyZeroInteractions(mMockPowerManagerService);
+        verifyNoMoreInteractions(mMockPowerManagerService);
     }
 
     @Test
@@ -344,7 +344,7 @@
         mKeyEventDispatcher.handleMessage(getTimedMessage(mMessageCapturingHandler, 0));
 
         assertFalse(mInputEventsHandler.hasMessages(SEND_FRAMEWORK_KEY_EVENT));
-        verifyZeroInteractions(mMockPowerManagerService);
+        verifyNoMoreInteractions(mMockPowerManagerService);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
index 9b8e619..367f2d1 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/MotionEventInjectorTest.java
@@ -37,7 +37,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 
 import android.accessibilityservice.GestureDescription.GestureStep;
@@ -223,7 +222,7 @@
         verifyNoMoreInteractions(next);
         reset(next);
 
-        verifyZeroInteractions(mServiceInterface);
+        verifyNoMoreInteractions(mServiceInterface);
 
         mMessageCapturingHandler.sendOneMessage(); // Send a motion event
         verify(next).onMotionEvent(argThat(allOf(mIsLineEnd, hasRightDownTime)),
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
index a048238..99c922c 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickControllerTest.java
@@ -75,12 +75,13 @@
 
     private static class MotionEventCaptor extends BaseEventStreamTransformation {
         public MotionEvent downEvent;
-
+        public int eventCount = 0;
         @Override
         public void onMotionEvent(MotionEvent event, MotionEvent rawEvent, int policyFlags) {
             switch (event.getAction()) {
                 case MotionEvent.ACTION_DOWN:
                     downEvent = event;
+                    eventCount++;
                     break;
             }
         }
@@ -922,6 +923,41 @@
         mController.onKeyEvent(keyEvent, /* policyFlags= */ 0);
     }
 
+    @Test
+    @EnableFlags(com.android.server.accessibility.Flags.FLAG_ENABLE_AUTOCLICK_INDICATOR)
+    public void sendClick_clickType_doubleclick_triggerClickTwice() {
+        MotionEventCaptor motionEventCaptor = new MotionEventCaptor();
+        mController.setNext(motionEventCaptor);
+
+        injectFakeMouseActionHoverMoveEvent();
+        // Set delay to zero so click is scheduled to run immediately.
+        mController.mClickScheduler.updateDelay(0);
+
+        // Set click type to double click.
+        mController.clickPanelController.handleAutoclickTypeChange(
+                AutoclickTypePanel.AUTOCLICK_TYPE_DOUBLE_CLICK);
+        AutoclickTypePanel mockAutoclickTypePanel = mock(AutoclickTypePanel.class);
+        mController.mAutoclickTypePanel = mockAutoclickTypePanel;
+
+        // Send hover move event.
+        MotionEvent hoverMove = MotionEvent.obtain(
+                /* downTime= */ 0,
+                /* eventTime= */ 100,
+                /* action= */ MotionEvent.ACTION_HOVER_MOVE,
+                /* x= */ 30f,
+                /* y= */ 0f,
+                /* metaState= */ 0);
+        hoverMove.setSource(InputDevice.SOURCE_MOUSE);
+        mController.onMotionEvent(hoverMove, hoverMove, /* policyFlags= */ 0);
+        mTestableLooper.processAllMessages();
+
+        // Verify left click sent.
+        assertThat(motionEventCaptor.downEvent).isNotNull();
+        assertThat(motionEventCaptor.downEvent.getButtonState()).isEqualTo(
+                MotionEvent.BUTTON_PRIMARY);
+        assertThat(motionEventCaptor.eventCount).isEqualTo(2);
+    }
+
     private MotionEvent getFakeMotionHoverMoveEvent() {
         return MotionEvent.obtain(
                 /* downTime= */ 0,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickScrollPanelTest.java b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickScrollPanelTest.java
index 02361ff..4c71f7e 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickScrollPanelTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/autoclick/AutoclickScrollPanelTest.java
@@ -21,8 +21,12 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.never;
 
 import android.content.Context;
 import android.testing.AndroidTestingRunner;
@@ -125,37 +129,107 @@
     }
 
     @Test
-    public void directionButtons_onHover_callsHandleScroll() {
-        // Test up button.
-        triggerHoverEvent(mUpButton);
-        verify(mMockScrollPanelController).handleScroll(AutoclickScrollPanel.DIRECTION_UP);
+    public void directionButtons_hoverEvents_callsHoverButtonChange() {
+        // Test hover enter on direction button.
+        triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_ENTER);
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_UP), eq(/* hovered= */ true));
 
-        // Test down button.
-        triggerHoverEvent(mDownButton);
-        verify(mMockScrollPanelController).handleScroll(AutoclickScrollPanel.DIRECTION_DOWN);
+        // Test hover move.
+        reset(mMockScrollPanelController);
+        triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_MOVE);
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_UP), eq(/* hovered= */ true));
 
-        // Test left button.
-        triggerHoverEvent(mLeftButton);
-        verify(mMockScrollPanelController).handleScroll(AutoclickScrollPanel.DIRECTION_LEFT);
-
-        // Test right button.
-        triggerHoverEvent(mRightButton);
-        verify(mMockScrollPanelController).handleScroll(AutoclickScrollPanel.DIRECTION_RIGHT);
+        // Test hover exit.
+        reset(mMockScrollPanelController);
+        triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_EXIT);
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_UP), eq(/* hovered= */ false));
     }
 
     @Test
-    public void exitButton_onHover_callsExitScrollMode() {
-        // Test exit button.
-        triggerHoverEvent(mExitButton);
-        verify(mMockScrollPanelController).exitScrollMode();
+    public void exitButton_hoverEvents_callsHoverButtonChange() {
+        // Test hover enter on exit button.
+        triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_ENTER);
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ true));
+
+        // Test hover exit - should call the hover change method with false.
+        reset(mMockScrollPanelController);
+        triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_EXIT);
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ false));
+
+        // Test exit button hover move - should be ignored.
+        reset(mMockScrollPanelController);
+        triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_MOVE);
+        verify(mMockScrollPanelController, never()).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_EXIT), anyBoolean());
+    }
+
+    @Test
+    public void hoverOnButtonSequence_handledCorrectly() {
+        // Test a realistic sequence of events.
+        // Case 1. Hover enter on up button, then hover move with in up button twice.
+        reset(mMockScrollPanelController);
+        triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_ENTER);
+        triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_MOVE);
+        triggerHoverEvent(mUpButton, MotionEvent.ACTION_HOVER_MOVE);
+        verify(mMockScrollPanelController, times(3)).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_UP), eq(true));
+
+        // Case 2. Move from left button to exit button.
+        reset(mMockScrollPanelController);
+        triggerHoverEvent(mLeftButton, MotionEvent.ACTION_HOVER_ENTER);
+        triggerHoverEvent(mLeftButton, MotionEvent.ACTION_HOVER_MOVE);
+        triggerHoverEvent(mLeftButton, MotionEvent.ACTION_HOVER_EXIT);
+        triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_MOVE);
+        triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_ENTER);
+        triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_EXIT);
+
+        // Verify left button events - 2 'true' calls (enter+move) and 1 'false' call (exit).
+        verify(mMockScrollPanelController, times(2)).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_LEFT), eq(/* hovered= */ true));
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_LEFT), eq(/* hovered= */ false));
+        // Verify exit button events - hover_move is ignored so 1 'true' call (enter) and 1
+        // 'false' call (exit).
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ true));
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ false));
+
+        // Case 3. Quick transitions between buttons: left → right → down → exit
+        reset(mMockScrollPanelController);
+        triggerHoverEvent(mLeftButton, MotionEvent.ACTION_HOVER_EXIT);
+        triggerHoverEvent(mRightButton, MotionEvent.ACTION_HOVER_ENTER);
+        triggerHoverEvent(mRightButton, MotionEvent.ACTION_HOVER_EXIT);
+        triggerHoverEvent(mDownButton, MotionEvent.ACTION_HOVER_ENTER);
+        triggerHoverEvent(mDownButton, MotionEvent.ACTION_HOVER_EXIT);
+        triggerHoverEvent(mExitButton, MotionEvent.ACTION_HOVER_ENTER);
+
+        // Verify all hover enter/exit events were properly handled
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_LEFT), eq(/* hovered= */ false));
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_RIGHT), eq(/* hovered= */ true));
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_RIGHT), eq(/* hovered= */ false));
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_DOWN), eq(/* hovered= */ true));
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_DOWN), eq(/* hovered= */ false));
+        verify(mMockScrollPanelController).onHoverButtonChange(
+                eq(AutoclickScrollPanel.DIRECTION_EXIT), eq(/* hovered= */ true));
     }
 
     // Helper method to simulate a hover event on a view.
-    private void triggerHoverEvent(View view) {
+    private void triggerHoverEvent(View view, int action) {
         MotionEvent event = MotionEvent.obtain(
                 /* downTime= */ 0,
                 /* eventTime= */ 0,
-                /* action= */ MotionEvent.ACTION_HOVER_ENTER,
+                /* action= */ action,
                 /* x= */ 0,
                 /* y= */ 0,
                 /* metaState= */ 0);
diff --git a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
index 3475c8f..20a95e9 100644
--- a/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/attention/AttentionManagerServiceTest.java
@@ -34,7 +34,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.attention.AttentionManagerInternal.AttentionCallbackInternal;
 import android.attention.AttentionManagerInternal.ProximityUpdateCallbackInternal;
@@ -196,7 +195,7 @@
     @Test
     public void testUnregisterProximityUpdates_noCrashWhenNoCallbackIsRegistered() {
         mSpyAttentionManager.onStopProximityUpdates(mMockProximityUpdateCallbackInternal);
-        verifyZeroInteractions(mMockProximityUpdateCallbackInternal);
+        verifyNoMoreInteractions(mMockProximityUpdateCallbackInternal);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
index 7a77033..f4e8717 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/sensors/face/aidl/FaceDetectClientTest.java
@@ -24,7 +24,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.same;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.hardware.biometrics.BiometricFaceConstants;
@@ -172,7 +172,7 @@
         client.onInteractionDetected();
         client.stopHalOperation();
 
-        verifyZeroInteractions(mVibrator);
+        verifyNoMoreInteractions(mVibrator);
     }
 
     private FaceDetectClient createClient() throws RemoteException {
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/SensorControllerTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/SensorControllerTest.java
index 67fc564..2e07cd8a 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/SensorControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/SensorControllerTest.java
@@ -22,18 +22,25 @@
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyFloat;
 import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.ArgumentMatchers.isNull;
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.inOrder;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
 
 import android.companion.virtual.IVirtualDevice;
 import android.companion.virtual.sensor.IVirtualSensorCallback;
 import android.companion.virtual.sensor.VirtualSensor;
+import android.companion.virtual.sensor.VirtualSensorAdditionalInfo;
 import android.companion.virtual.sensor.VirtualSensorConfig;
 import android.companion.virtual.sensor.VirtualSensorEvent;
 import android.content.AttributionSource;
 import android.hardware.Sensor;
+import android.hardware.SensorAdditionalInfo;
 import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
@@ -49,6 +56,7 @@
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.InOrder;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -65,6 +73,9 @@
 
     private static final int VIRTUAL_SENSOR_TYPE = Sensor.TYPE_ACCELEROMETER;
 
+    private static final float[] ADDITIONAL_INFO_VALUES_1 = new float[] {1.2f, 3.4f};
+    private static final float[] ADDITIONAL_INFO_VALUES_2 = new float[] {5.6f, 7.8f};
+
     @Mock
     private SensorManagerInternal mSensorManagerInternalMock;
     @Mock
@@ -155,6 +166,53 @@
     }
 
     @Test
+    public void sendSensorAdditionalInfo_invalidToken_throwsException() throws Exception {
+        SensorController sensorController = doCreateSensorSuccessfully();
+
+        final VirtualSensorAdditionalInfo info =
+                new VirtualSensorAdditionalInfo.Builder(SensorAdditionalInfo.TYPE_UNTRACKED_DELAY)
+                        .addValues(ADDITIONAL_INFO_VALUES_1)
+                        .addValues(ADDITIONAL_INFO_VALUES_2)
+                        .build();
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> sensorController.sendSensorAdditionalInfo(
+                        new Binder("invalidSensorToken"), info));
+    }
+
+    @Test
+    public void sendSensorAdditionalInfo_success() throws Exception {
+        SensorController sensorController = doCreateSensorSuccessfully();
+
+        clearInvocations(mSensorManagerInternalMock);
+        when(mSensorManagerInternalMock.sendSensorAdditionalInfo(
+                anyInt(), anyInt(), anyInt(), anyLong(), any()))
+                .thenReturn(true);
+        IBinder token = Iterables.getOnlyElement(sensorController.getSensorDescriptors().keySet());
+
+        final VirtualSensorAdditionalInfo info =
+                new VirtualSensorAdditionalInfo.Builder(SensorAdditionalInfo.TYPE_UNTRACKED_DELAY)
+                        .addValues(ADDITIONAL_INFO_VALUES_1)
+                        .addValues(ADDITIONAL_INFO_VALUES_2)
+                        .build();
+        sensorController.sendSensorAdditionalInfo(token, info);
+
+        InOrder inOrder = inOrder(mSensorManagerInternalMock);
+        inOrder.verify(mSensorManagerInternalMock).sendSensorAdditionalInfo(
+                eq(SENSOR_HANDLE), eq(SensorAdditionalInfo.TYPE_FRAME_BEGIN),
+                /*serial=*/ eq(0), /* timestamp= */ anyLong(), /*values=*/ isNull());
+        inOrder.verify(mSensorManagerInternalMock).sendSensorAdditionalInfo(
+                eq(SENSOR_HANDLE), eq(SensorAdditionalInfo.TYPE_UNTRACKED_DELAY),
+                /*serial=*/ eq(0), /* timestamp= */ anyLong(), eq(ADDITIONAL_INFO_VALUES_1));
+        inOrder.verify(mSensorManagerInternalMock).sendSensorAdditionalInfo(
+                eq(SENSOR_HANDLE), eq(SensorAdditionalInfo.TYPE_UNTRACKED_DELAY),
+                /*serial=*/ eq(1), /* timestamp= */ anyLong(), eq(ADDITIONAL_INFO_VALUES_2));
+        inOrder.verify(mSensorManagerInternalMock).sendSensorAdditionalInfo(
+                eq(SENSOR_HANDLE), eq(SensorAdditionalInfo.TYPE_FRAME_END),
+                /*serial=*/ eq(0), /* timestamp= */ anyLong(), /*values=*/ isNull());
+    }
+
+    @Test
     public void close_unregistersSensors() throws Exception {
         SensorController sensorController = doCreateSensorSuccessfully();
 
diff --git a/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
index b445226..4fa75b9 100644
--- a/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/contentcapture/ContentCaptureManagerServiceTest.java
@@ -23,7 +23,7 @@
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.annotation.NonNull;
@@ -132,8 +132,8 @@
         assertThat(mContentProtectionAllowlistManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockContentProtectionAllowlistManager);
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionAllowlistManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -147,7 +147,7 @@
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         verify(mMockContentProtectionAllowlistManager).start(anyLong());
         verify(mMockContentProtectionAllowlistManager, never()).stop();
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -157,8 +157,8 @@
         assertThat(mContentProtectionAllowlistManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockContentProtectionAllowlistManager);
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionAllowlistManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -172,7 +172,7 @@
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         verify(mMockContentProtectionAllowlistManager).start(anyLong());
         verify(mMockContentProtectionAllowlistManager, never()).stop();
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -187,7 +187,7 @@
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         verify(mMockContentProtectionAllowlistManager).start(anyLong());
         verify(mMockContentProtectionAllowlistManager, never()).stop();
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -203,7 +203,7 @@
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         verify(mMockContentProtectionAllowlistManager).start(anyLong());
         verify(mMockContentProtectionAllowlistManager).stop();
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -216,8 +216,8 @@
         assertThat(mContentProtectionAllowlistManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockContentProtectionAllowlistManager);
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionAllowlistManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -230,8 +230,8 @@
         assertThat(mContentProtectionAllowlistManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionConsentManagersCreated).isEqualTo(0);
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockContentProtectionAllowlistManager);
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionAllowlistManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -248,7 +248,7 @@
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         verify(mMockContentProtectionAllowlistManager).start(anyLong());
         verify(mMockContentProtectionAllowlistManager).stop();
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -265,7 +265,7 @@
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         verify(mMockContentProtectionAllowlistManager).start(anyLong());
         verify(mMockContentProtectionAllowlistManager).stop();
-        verifyZeroInteractions(mMockContentProtectionConsentManager);
+        verifyNoMoreInteractions(mMockContentProtectionConsentManager);
     }
 
     @Test
@@ -513,7 +513,7 @@
 
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(0);
         assertThat(mRemoteContentProtectionServicesCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
     }
 
     @Test
@@ -528,7 +528,7 @@
 
         assertThat(mContentProtectionServiceInfosCreated).isEqualTo(1);
         assertThat(mRemoteContentProtectionServicesCreated).isEqualTo(0);
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java
index 195ab68..9d37b99 100644
--- a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionAllowlistManagerTest.java
@@ -24,7 +24,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.os.Handler;
@@ -98,10 +98,10 @@
     @Test
     public void constructor() {
         assertThat(mHandler.hasMessagesOrCallbacks()).isFalse();
-        verifyZeroInteractions(mMockContentCaptureManagerService);
-        verifyZeroInteractions(mMockPackageMonitor);
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockContentCaptureManagerService);
+        verifyNoMoreInteractions(mMockPackageMonitor);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -110,10 +110,10 @@
         mTestLooper.dispatchAll();
 
         assertThat(mHandler.hasMessagesOrCallbacks()).isTrue();
-        verifyZeroInteractions(mMockContentCaptureManagerService);
-        verifyZeroInteractions(mMockPackageMonitor);
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockContentCaptureManagerService);
+        verifyNoMoreInteractions(mMockPackageMonitor);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -126,8 +126,8 @@
         verify(mMockContentCaptureManagerService).createRemoteContentProtectionService();
         verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler));
         verify(mMockPackageMonitor, never()).unregister();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -142,8 +142,8 @@
         verify(mMockContentCaptureManagerService).createRemoteContentProtectionService();
         verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler));
         verify(mMockPackageMonitor, never()).unregister();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -153,11 +153,11 @@
         mContentProtectionAllowlistManager.stop();
 
         assertThat(mHandler.hasMessagesOrCallbacks()).isFalse();
-        verifyZeroInteractions(mMockContentCaptureManagerService);
+        verifyNoMoreInteractions(mMockContentCaptureManagerService);
         verify(mMockPackageMonitor, never()).register(any(), any(), any());
         verify(mMockPackageMonitor).unregister();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -169,11 +169,11 @@
         mContentProtectionAllowlistManager.stop();
 
         assertThat(mHandler.hasMessagesOrCallbacks()).isFalse();
-        verifyZeroInteractions(mMockContentCaptureManagerService);
+        verifyNoMoreInteractions(mMockContentCaptureManagerService);
         verify(mMockPackageMonitor, never()).register(any(), any(), any());
         verify(mMockPackageMonitor).unregister();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -188,8 +188,8 @@
         verify(mMockContentCaptureManagerService).createRemoteContentProtectionService();
         verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler));
         verify(mMockPackageMonitor).unregister();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -205,8 +205,8 @@
         assertThat(mHandler.hasMessagesOrCallbacks()).isFalse();
         verify(mMockPackageMonitor).register(any(), eq(UserHandle.ALL), eq(mHandler));
         verify(mMockPackageMonitor).unregister();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -223,8 +223,8 @@
         assertThat(mHandler.hasMessagesOrCallbacks()).isFalse();
         verify(mMockPackageMonitor, times(2)).register(any(), eq(UserHandle.ALL), eq(mHandler));
         verify(mMockPackageMonitor).unregister();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -232,10 +232,10 @@
         boolean actual = mContentProtectionAllowlistManager.isAllowed(FIRST_PACKAGE_NAME);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockContentCaptureManagerService);
-        verifyZeroInteractions(mMockPackageMonitor);
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockContentCaptureManagerService);
+        verifyNoMoreInteractions(mMockPackageMonitor);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -248,9 +248,9 @@
         boolean actual = manager.isAllowed(SECOND_PACKAGE_NAME);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockContentCaptureManagerService);
-        verifyZeroInteractions(mMockPackageMonitor);
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockContentCaptureManagerService);
+        verifyNoMoreInteractions(mMockPackageMonitor);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
     }
 
     @Test
@@ -263,9 +263,9 @@
         boolean actual = manager.isAllowed(FIRST_PACKAGE_NAME);
 
         assertThat(actual).isTrue();
-        verifyZeroInteractions(mMockContentCaptureManagerService);
-        verifyZeroInteractions(mMockPackageMonitor);
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockContentCaptureManagerService);
+        verifyNoMoreInteractions(mMockPackageMonitor);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
     }
 
     @Test
@@ -276,8 +276,8 @@
         manager.mPackageMonitor.onSomePackagesChanged();
 
         verify(mMockContentCaptureManagerService).createRemoteContentProtectionService();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -291,7 +291,7 @@
 
         verify(mMockRemoteContentProtectionService)
                 .onUpdateAllowlistRequest(mMockAllowlistCallback);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -309,7 +309,7 @@
         // Does not rethrow
         verify(mMockRemoteContentProtectionService)
                 .onUpdateAllowlistRequest(mMockAllowlistCallback);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -321,8 +321,8 @@
         manager.mPackageMonitor.onSomePackagesChanged();
 
         verify(mMockContentCaptureManagerService, times(2)).createRemoteContentProtectionService();
-        verifyZeroInteractions(mMockRemoteContentProtectionService);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockRemoteContentProtectionService);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -338,7 +338,7 @@
         verify(mMockContentCaptureManagerService).createRemoteContentProtectionService();
         verify(mMockRemoteContentProtectionService)
                 .onUpdateAllowlistRequest(mMockAllowlistCallback);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
@@ -355,7 +355,7 @@
         verify(mMockContentCaptureManagerService, times(2)).createRemoteContentProtectionService();
         verify(mMockRemoteContentProtectionService, times(2))
                 .onUpdateAllowlistRequest(mMockAllowlistCallback);
-        verifyZeroInteractions(mMockAllowlistCallback);
+        verifyNoMoreInteractions(mMockAllowlistCallback);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java
index b012aaa..cd36a18 100644
--- a/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/ContentProtectionConsentManagerTest.java
@@ -27,7 +27,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.admin.DevicePolicyCache;
@@ -112,8 +112,8 @@
         boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyManagerInternal);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -125,8 +125,8 @@
         boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyManagerInternal);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -138,8 +138,8 @@
         boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyManagerInternal);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -152,7 +152,7 @@
 
         assertThat(actual).isTrue();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -166,7 +166,7 @@
         boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -179,7 +179,7 @@
 
         assertThat(actual).isFalse();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -192,7 +192,7 @@
 
         assertThat(actual).isTrue();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -289,8 +289,8 @@
         boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyManagerInternal);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -302,8 +302,8 @@
         boolean actual = manager.isConsentGranted(TEST_USER_ID);
 
         assertThat(actual).isFalse();
-        verifyZeroInteractions(mMockDevicePolicyManagerInternal);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyManagerInternal);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -316,7 +316,7 @@
 
         assertThat(actual).isTrue();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -339,7 +339,7 @@
         assertThat(thirdActual).isTrue();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
 
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -362,7 +362,7 @@
         assertThat(thirdActual).isTrue();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
 
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -385,7 +385,7 @@
         assertThat(thirdActual).isTrue();
         verify(mMockDevicePolicyManagerInternal).isUserOrganizationManaged(TEST_USER_ID);
 
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     @Test
@@ -408,7 +408,7 @@
         assertThat(thirdActual).isTrue();
         verify(mMockDevicePolicyManagerInternal, times(3)).isUserOrganizationManaged(TEST_USER_ID);
 
-        verifyZeroInteractions(mMockDevicePolicyCache);
+        verifyNoMoreInteractions(mMockDevicePolicyCache);
     }
 
     private void putGlobalSettings(String key, int value) {
diff --git a/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java
index 6a7e286..563a679 100644
--- a/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/contentprotection/RemoteContentProtectionServiceTest.java
@@ -20,7 +20,7 @@
 
 import static org.junit.Assert.fail;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.annotation.NonNull;
@@ -87,7 +87,7 @@
     @Test
     public void doesNotAutoConnect() {
         assertThat(mConnectCallCount).isEqualTo(0);
-        verifyZeroInteractions(mMockContentProtectionService);
+        verifyNoMoreInteractions(mMockContentProtectionService);
     }
 
     @Test
@@ -124,7 +124,7 @@
         mRemoteContentProtectionService.onServiceConnectionStatusChanged(
                 mMockContentProtectionService, /* isConnected= */ true);
 
-        verifyZeroInteractions(mMockContentProtectionService);
+        verifyNoMoreInteractions(mMockContentProtectionService);
         assertThat(mConnectCallCount).isEqualTo(0);
     }
 
@@ -133,7 +133,7 @@
         mRemoteContentProtectionService.onServiceConnectionStatusChanged(
                 mMockContentProtectionService, /* isConnected= */ false);
 
-        verifyZeroInteractions(mMockContentProtectionService);
+        verifyNoMoreInteractions(mMockContentProtectionService);
         assertThat(mConnectCallCount).isEqualTo(0);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/credentials/ProviderRegistryGetSessionTest.java b/services/tests/servicestests/src/com/android/server/credentials/ProviderRegistryGetSessionTest.java
index 0f3f27a..9e98af3 100644
--- a/services/tests/servicestests/src/com/android/server/credentials/ProviderRegistryGetSessionTest.java
+++ b/services/tests/servicestests/src/com/android/server/credentials/ProviderRegistryGetSessionTest.java
@@ -21,7 +21,7 @@
 import static org.mockito.ArgumentMatchers.anySet;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
@@ -207,7 +207,7 @@
                 ProviderRegistryGetSession.CREDENTIAL_ENTRY_KEY,
                 "unsupportedKey", providerPendingIntentResponse);
 
-        verifyZeroInteractions(mGetRequestSession);
+        verifyNoMoreInteractions(mGetRequestSession);
     }
 
     @Test
@@ -216,7 +216,7 @@
                 ProviderRegistryGetSession.CREDENTIAL_ENTRY_KEY,
                 ProviderRegistryGetSession.CREDENTIAL_ENTRY_KEY, null);
 
-        verifyZeroInteractions(mGetRequestSession);
+        verifyNoMoreInteractions(mGetRequestSession);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 01bcc25..c50c623 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -88,7 +88,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 import static org.mockito.hamcrest.MockitoHamcrest.argThat;
 import static org.testng.Assert.assertThrows;
@@ -5305,7 +5304,7 @@
         // both the user restriction and the policy were set by the PO.
         verify(getServices().userManagerInternal).removeUserEvenWhenDisallowed(
                 MANAGED_PROFILE_USER_ID);
-        verifyZeroInteractions(getServices().recoverySystem);
+        verifyNoMoreInteractions(getServices().recoverySystem);
     }
 
     @Test
@@ -5339,7 +5338,7 @@
         // not wiped.
         verify(getServices().userManagerInternal, never())
                 .removeUserEvenWhenDisallowed(anyInt());
-        verifyZeroInteractions(getServices().recoverySystem);
+        verifyNoMoreInteractions(getServices().recoverySystem);
     }
 
     @Test
@@ -5380,7 +5379,7 @@
         dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
 
         // DISALLOW_FACTORY_RESET was set by the system, not the DO, so the device is not wiped.
-        verifyZeroInteractions(getServices().recoverySystem);
+        verifyNoMoreInteractions(getServices().recoverySystem);
         verify(getServices().userManagerInternal, never())
                 .removeUserEvenWhenDisallowed(anyInt());
     }
@@ -7535,7 +7534,7 @@
         verify(getServices().notificationManager, never())
                 .notify(anyInt(), any(Notification.class));
         // Apps shouldn't be suspended.
-        verifyZeroInteractions(getServices().ipackageManager);
+        verifyNoMoreInteractions(getServices().ipackageManager);
         clearInvocations(getServices().alarmManager);
 
         setUserUnlocked(CALLER_USER_HANDLE, false);
@@ -7548,7 +7547,7 @@
         verify(getServices().notificationManager, never())
                 .notify(anyInt(), any(Notification.class));
         // Apps shouldn't be suspended.
-        verifyZeroInteractions(getServices().ipackageManager);
+        verifyNoMoreInteractions(getServices().ipackageManager);
         clearInvocations(getServices().alarmManager);
 
         // Pretend the alarm went off.
@@ -7561,7 +7560,7 @@
         verify(getServices().notificationManager, times(1))
                 .notifyAsUser(any(), anyInt(), any(), any());
         // Apps shouldn't be suspended yet.
-        verifyZeroInteractions(getServices().ipackageManager);
+        verifyNoMoreInteractions(getServices().ipackageManager);
         clearInvocations(getServices().alarmManager);
         clearInvocations(getServices().notificationManager);
 
@@ -7570,7 +7569,7 @@
         sendBroadcastWithUser(dpms, ACTION_PROFILE_OFF_DEADLINE, CALLER_USER_HANDLE);
 
         // Verify the alarm was not set.
-        verifyZeroInteractions(getServices().alarmManager);
+        verifyNoMoreInteractions(getServices().alarmManager);
         // Now the user should see a notification about suspended apps.
         verify(getServices().notificationManager, times(1))
                 .notifyAsUser(any(), anyInt(), any(), any());
@@ -8754,7 +8753,7 @@
         sendBroadcastWithUser(dpms, Intent.ACTION_MANAGED_PROFILE_REMOVED, CALLER_USER_HANDLE);
 
         // Verify that EuiccManager was not called to delete the subscription.
-        verifyZeroInteractions(getServices().euiccManager);
+        verifyNoMoreInteractions(getServices().euiccManager);
     }
 
     private void setupVpnAuthorization(String userVpnPackage, int userVpnUid) {
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
index b2d48a7..2349120 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseAbsoluteVolumeBehaviorTest.java
@@ -226,13 +226,16 @@
      */
     protected void adoptFullVolumeBehaviorOnAvbCapableAudioOutputDevices() {
         if (getDeviceType() == HdmiDeviceInfo.DEVICE_PLAYBACK) {
-            mAudioManager.setDeviceVolumeBehavior(HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI,
-                    AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+            mAudioDeviceVolumeManager.setDeviceVolumeBehavior(
+                    HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI,
+                    AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
         } else if (getDeviceType() == HdmiDeviceInfo.DEVICE_TV) {
-            mAudioManager.setDeviceVolumeBehavior(HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_ARC,
-                    AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
-            mAudioManager.setDeviceVolumeBehavior(HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_EARC,
-                    AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+            mAudioDeviceVolumeManager.setDeviceVolumeBehavior(
+                    HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_ARC,
+                    AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+            mAudioDeviceVolumeManager.setDeviceVolumeBehavior(
+                    HdmiControlService.AUDIO_OUTPUT_DEVICE_HDMI_EARC,
+                    AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
         }
     }
 
@@ -307,8 +310,9 @@
                 INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume(),
                 INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute());
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
     }
 
     protected void enableAdjustOnlyAbsoluteVolumeBehavior() {
@@ -320,8 +324,9 @@
                 INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getVolume(),
                 INITIAL_SYSTEM_AUDIO_DEVICE_STATUS.getMute());
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
     }
 
     protected void verifyGiveAudioStatusNeverSent() {
@@ -419,14 +424,16 @@
         receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
 
         // AVB should not be enabled before receiving <Report Audio Status>
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
 
         receiveReportAudioStatus(60, false);
 
         // Check that absolute volume behavior was the last one adopted
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
 
         // Check that the volume and mute status received were included when setting AVB
         verify(mAudioDeviceVolumeManager).setDeviceAbsoluteVolumeBehavior(
@@ -447,19 +454,22 @@
         enableSystemAudioModeIfNeeded();
         receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_SUPPORTED);
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
         receiveReportAudioStatus(127, false);
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
     }
 
     @Test
     public void avbEnabled_standby_avbDisabled() {
         enableAbsoluteVolumeBehavior();
         mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
     }
 
     @Test
@@ -468,8 +478,9 @@
 
         setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_DISABLED);
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
     }
 
     @Test
@@ -477,8 +488,9 @@
         enableAbsoluteVolumeBehavior();
 
         receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_NOT_SUPPORTED);
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
     }
 
     @Test
@@ -489,8 +501,9 @@
                 getSystemAudioDeviceLogicalAddress(), getLogicalAddress(),
                 Constants.MESSAGE_SET_AUDIO_VOLUME_LEVEL, Constants.ABORT_UNRECOGNIZED_OPCODE));
         mTestLooper.dispatchAll();
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
     }
 
     @Test
@@ -501,8 +514,9 @@
         enableAbsoluteVolumeBehavior();
 
         receiveSetSystemAudioMode(false);
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java
index 4c12e436..7c7e220 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BasePlaybackDeviceAvbTest.java
@@ -20,7 +20,7 @@
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
 import android.media.AudioDeviceAttributes;
-import android.media.AudioManager;
+import android.media.AudioDeviceVolumeManager;
 
 import org.junit.Test;
 
@@ -60,8 +60,8 @@
      */
     @Test
     public void savlNotSupported_allOtherConditionsMet_giveAudioStatusNotSent() {
-        mAudioManager.setDeviceVolumeBehavior(getAudioOutputDevice(),
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        mAudioDeviceVolumeManager.setDeviceVolumeBehavior(getAudioOutputDevice(),
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
         setCecVolumeControlSetting(HdmiControlManager.VOLUME_CONTROL_ENABLED);
         enableSystemAudioModeIfNeeded();
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
index f44517a..7a43598 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/BaseTvToAudioSystemAvbTest.java
@@ -96,13 +96,15 @@
         receiveSetAudioVolumeLevelSupport(DeviceFeatures.FEATURE_NOT_SUPPORTED);
 
         // Adjust-only AVB should not be enabled before receiving <Report Audio Status>
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
 
         receiveReportAudioStatus(20, false);
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
 
         verify(mAudioDeviceVolumeManager).setDeviceAbsoluteVolumeAdjustOnlyBehavior(
                 eq(getAudioOutputDevice()),
@@ -124,8 +126,9 @@
 
         receiveReportAudioStatus(40, true);
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
 
         verify(mAudioDeviceVolumeManager).setDeviceAbsoluteVolumeAdjustOnlyBehavior(
                 eq(getAudioOutputDevice()),
@@ -149,8 +152,9 @@
 
         receiveReportAudioStatus(40, true);
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
 
         verify(mAudioDeviceVolumeManager).setDeviceAbsoluteVolumeAdjustOnlyBehavior(
                 eq(getAudioOutputDevice()),
@@ -283,13 +287,15 @@
         verifyGiveAudioStatusSent();
 
         // The device should use adjust-only AVB while waiting for <Report Audio Status>
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
 
         // The device should switch to AVB upon receiving <Report Audio Status>
         receiveReportAudioStatus(60, false);
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
 
     }
 
@@ -321,8 +327,9 @@
         mTestLooper.dispatchAll();
 
         // The device should not switch away from adjust-only AVB
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
 
         // The device should query support for <Set Audio Volume Level> again
         assertThat(mNativeWrapper.getResultMessages()).contains(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
index a4c71bd..2227eeb 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionFromTvTest.java
@@ -251,6 +251,35 @@
     }
 
     @Test
+    public void testDeviceSelect_DeviceAssertsActiveSource_singleSetStreamPathMessage() {
+        // TV was watching playback2 device connected at port 2, and wants to select
+        // playback1.
+        TestActionTimer actionTimer = new TestActionTimer();
+        TestCallback callback = new TestCallback();
+        DeviceSelectActionFromTv action = createDeviceSelectAction(actionTimer, callback,
+                /*isCec20=*/false);
+        mHdmiCecLocalDeviceTv.updateActiveSource(ADDR_PLAYBACK_2, PHYSICAL_ADDRESS_PLAYBACK_2,
+                "testDeviceSelect");
+        action.start();
+        mTestLooper.dispatchAll();
+
+        assertThat(mNativeWrapper.getResultMessages()).contains(SET_STREAM_PATH);
+        mNativeWrapper.clearResultMessages();
+        mHdmiCecLocalDeviceTv.updateActiveSource(ADDR_PLAYBACK_1, PHYSICAL_ADDRESS_PLAYBACK_1,
+                "testDeviceSelect");
+        mTestLooper.dispatchAll();
+
+        assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_POWER_STATE_CHANGE);
+        action.handleTimerEvent(STATE_WAIT_FOR_POWER_STATE_CHANGE);
+        assertThat(actionTimer.getState()).isEqualTo(STATE_WAIT_FOR_REPORT_POWER_STATUS);
+        action.processCommand(REPORT_POWER_STATUS_ON);
+        mTestLooper.dispatchAll();
+
+        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(SET_STREAM_PATH);
+        assertThat(callback.getResult()).isEqualTo(HdmiControlManager.RESULT_SUCCESS);
+    }
+
+    @Test
     public void testDeviceSelect_DeviceInStandbyStatus_Cec14b() {
         mHdmiCecLocalDeviceTv.updateActiveSource(ADDR_PLAYBACK_2, PHYSICAL_ADDRESS_PLAYBACK_2,
                                                  "testDeviceSelect");
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java b/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
index 90f94cb..e07f4f9 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/FakeAudioFramework.java
@@ -23,6 +23,7 @@
 import android.annotation.NonNull;
 import android.media.AudioAttributes;
 import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceVolumeManager;
 import android.media.AudioManager;
 import android.media.AudioSystem;
 import android.media.VolumeInfo;
@@ -137,18 +138,6 @@
             // Do nothing
         }
 
-
-        @Override
-        @AudioManager.DeviceVolumeBehavior
-        public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
-            return mDeviceVolumeBehaviors.getOrDefault(device, DEFAULT_DEVICE_VOLUME_BEHAVIOR);
-        }
-
-        public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
-                @AudioManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
-            setVolumeBehaviorHelper(device, deviceVolumeBehavior);
-        }
-
         @Override
         @NonNull
         public List<AudioDeviceAttributes> getDevicesForAttributes(
@@ -186,7 +175,8 @@
                 boolean handlesVolumeAdjustment,
                 @NonNull @CallbackExecutor Executor executor,
                 @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
-            setVolumeBehaviorHelper(device, AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+            setVolumeBehaviorHelper(device,
+                    AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
         }
 
         @Override
@@ -197,7 +187,19 @@
                 @NonNull @CallbackExecutor Executor executor,
                 @NonNull OnAudioDeviceVolumeChangedListener vclistener) {
             setVolumeBehaviorHelper(device,
-                    AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+                    AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_ADJUST_ONLY);
+        }
+
+        @Override
+        @AudioDeviceVolumeManager.DeviceVolumeBehavior
+        public int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
+            return mDeviceVolumeBehaviors.getOrDefault(device, DEFAULT_DEVICE_VOLUME_BEHAVIOR);
+        }
+
+        @Override
+        public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+                @AudioDeviceVolumeManager.DeviceVolumeBehavior int deviceVolumeBehavior) {
+            setVolumeBehaviorHelper(device, deviceVolumeBehavior);
         }
     }
 
@@ -222,7 +224,7 @@
      * Helper method for changing an audio device's volume behavior. Notifies listeners.
      */
     private void setVolumeBehaviorHelper(AudioDeviceAttributes device,
-            @AudioManager.DeviceVolumeBehavior int newVolumeBehavior) {
+            @AudioDeviceVolumeManager.DeviceVolumeBehavior int newVolumeBehavior) {
 
         int currentVolumeBehavior = mDeviceVolumeBehaviors.getOrDefault(
                 device, DEFAULT_DEVICE_VOLUME_BEHAVIOR);
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index aa1d583..aacef3f 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -341,18 +341,9 @@
         HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
                 ADDR_TV,
                 ADDR_AUDIO_SYSTEM);
-        // <Report ARC Initiated> should only be sent after SAD querying is done
-        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated);
-
-        // Finish querying SADs
-        for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) {
-            assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
-            mNativeWrapper.clearResultMessages();
-            mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
-            mTestLooper.dispatchAll();
-        }
-
         assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
+        // But we need to check SADs started to be queried at this time
+        assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
         mNativeWrapper.clearResultMessages();
     }
 
@@ -752,17 +743,6 @@
         HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
                 ADDR_TV,
                 ADDR_AUDIO_SYSTEM);
-        // <Report ARC Initiated> should only be sent after SAD querying is done
-        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated);
-
-        // Finish querying SADs
-        for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) {
-            assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
-            mNativeWrapper.clearResultMessages();
-            mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
-            mTestLooper.dispatchAll();
-        }
-
         assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
     }
 
@@ -1067,16 +1047,6 @@
         HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
             ADDR_TV,
             ADDR_AUDIO_SYSTEM);
-        // <Report ARC Initiated> should only be sent after SAD querying is done
-        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated);
-        // Finish querying SADs
-        for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) {
-            assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
-            mNativeWrapper.clearResultMessages();
-            mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
-            mTestLooper.dispatchAll();
-        }
-
         assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
         mNativeWrapper.clearResultMessages();
 
@@ -1268,16 +1238,6 @@
 
         mNativeWrapper.onCecMessage(initiateArc);
         mTestLooper.dispatchAll();
-
-        // Finish querying SADs
-        for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) {
-            assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
-            mNativeWrapper.clearResultMessages();
-            mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
-            mTestLooper.dispatchAll();
-        }
-
-        // ARC should be established after RequestSadAction is finished
         assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
 
         mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
@@ -1421,17 +1381,6 @@
         HdmiCecMessage reportArcInitiated = HdmiCecMessageBuilder.buildReportArcInitiated(
                 ADDR_TV,
                 ADDR_AUDIO_SYSTEM);
-        // <Report ARC Initiated> should only be sent after SAD querying is done
-        assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportArcInitiated);
-
-        // Finish querying SADs
-        for (int i = 0; i <= RETRY_COUNTER_MAX; ++i) {
-            assertThat(mNativeWrapper.getResultMessages()).contains(SAD_QUERY);
-            mNativeWrapper.clearResultMessages();
-            mTestLooper.moveTimeForward(HdmiConfig.TIMEOUT_MS);
-            mTestLooper.dispatchAll();
-        }
-
         assertThat(mNativeWrapper.getResultMessages()).contains(reportArcInitiated);
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java
index 43ab804..ffc1c62 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToAudioSystemAvbTest.java
@@ -21,7 +21,7 @@
 import android.hardware.hdmi.DeviceFeatures;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
-import android.media.AudioManager;
+import android.media.AudioDeviceVolumeManager;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -64,8 +64,9 @@
 
         // Audio System disables System Audio Mode. AVB should be disabled.
         receiveSetSystemAudioMode(false);
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
 
         // TV reports support for <Set Audio Volume Level>
         mNativeWrapper.onCecMessage(ReportFeaturesMessage.build(
@@ -85,7 +86,8 @@
                 false));
         mTestLooper.dispatchAll();
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java
index 9b343e3..0926180 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PlaybackDeviceToTvAvbTest.java
@@ -23,7 +23,7 @@
 import android.hardware.hdmi.DeviceFeatures;
 import android.hardware.hdmi.HdmiControlManager;
 import android.hardware.hdmi.HdmiDeviceInfo;
-import android.media.AudioManager;
+import android.media.AudioDeviceVolumeManager;
 import android.platform.test.annotations.Presubmit;
 
 import androidx.test.filters.SmallTest;
@@ -65,8 +65,9 @@
 
         // Audio System enables System Audio Mode. AVB should be disabled.
         receiveSetSystemAudioMode(true);
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_FULL);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_FULL);
 
         clearInvocations(mAudioManager, mAudioDeviceVolumeManager);
 
@@ -88,7 +89,8 @@
                 false));
         mTestLooper.dispatchAll();
 
-        assertThat(mAudioManager.getDeviceVolumeBehavior(getAudioOutputDevice())).isEqualTo(
-                AudioManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
+        assertThat(mAudioDeviceVolumeManager.getDeviceVolumeBehavior(
+                getAudioOutputDevice())).isEqualTo(
+                AudioDeviceVolumeManager.DEVICE_VOLUME_BEHAVIOR_ABSOLUTE);
     }
 }
diff --git a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
index e20f1e7..a39f071 100644
--- a/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
+++ b/services/tests/servicestests/src/com/android/server/locales/SystemAppUpdateTrackerTest.java
@@ -31,7 +31,7 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import android.app.ActivityManagerInternal;
 import android.content.Context;
@@ -226,7 +226,7 @@
 
         assertTrue(!mSystemAppUpdateTracker.getUpdatedApps().contains(DEFAULT_PACKAGE_NAME_2));
         // getApplicationLocales should be never be invoked if not a system app.
-        verifyZeroInteractions(mMockActivityTaskManager);
+        verifyNoMoreInteractions(mMockActivityTaskManager);
         // Broadcast should be never sent if not a system app.
         verify(mMockContext, never()).sendBroadcastAsUser(any(), any());
         // It shouldn't write to the file if not a system app.
@@ -244,7 +244,7 @@
                 Binder.getCallingUid());
 
         // getApplicationLocales should be never be invoked if not installer is not present.
-        verifyZeroInteractions(mMockActivityTaskManager);
+        verifyNoMoreInteractions(mMockActivityTaskManager);
         // Broadcast should be never sent if installer is not present.
         verify(mMockContext, never()).sendBroadcastAsUser(any(), any());
         // It shouldn't write to file if no installer present.
diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java
index 4d2dcf6..43b1ec3 100644
--- a/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java
+++ b/services/tests/servicestests/src/com/android/server/location/contexthub/ContextHubEndpointTest.java
@@ -20,6 +20,7 @@
 
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.timeout;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -67,12 +68,15 @@
     private static final int SESSION_ID_RANGE = ContextHubEndpointManager.SERVICE_SESSION_RANGE;
     private static final int MIN_SESSION_ID = 0;
     private static final int MAX_SESSION_ID = MIN_SESSION_ID + SESSION_ID_RANGE - 1;
+    private static final int SESSION_ID_FOR_OPEN_REQUEST = MAX_SESSION_ID + 1;
+    private static final int INVALID_SESSION_ID_FOR_OPEN_REQUEST = MIN_SESSION_ID + 1;
 
     private static final String ENDPOINT_NAME = "Example test endpoint";
     private static final int ENDPOINT_ID = 1;
     private static final String ENDPOINT_PACKAGE_NAME = "com.android.server.location.contexthub";
 
     private static final String TARGET_ENDPOINT_NAME = "Example target endpoint";
+    private static final String ENDPOINT_SERVICE_DESCRIPTOR = "serviceDescriptor";
     private static final int TARGET_ENDPOINT_ID = 1;
 
     private static final int SAMPLE_MESSAGE_TYPE = 1234;
@@ -225,6 +229,105 @@
     }
 
     @Test
+    public void testEndpointSessionOpenRequest() throws RemoteException {
+        assertThat(mEndpointManager.getNumAvailableSessions()).isEqualTo(SESSION_ID_RANGE);
+        IContextHubEndpoint endpoint = registerExampleEndpoint();
+
+        HubEndpointInfo targetInfo =
+                new HubEndpointInfo(
+                        TARGET_ENDPOINT_NAME,
+                        TARGET_ENDPOINT_ID,
+                        ENDPOINT_PACKAGE_NAME,
+                        Collections.emptyList());
+        mHubInfoRegistry.onEndpointStarted(new HubEndpointInfo[] {targetInfo});
+        mEndpointManager.onEndpointSessionOpenRequest(
+                SESSION_ID_FOR_OPEN_REQUEST,
+                endpoint.getAssignedHubEndpointInfo().getIdentifier(),
+                targetInfo.getIdentifier(),
+                ENDPOINT_SERVICE_DESCRIPTOR);
+
+        verify(mMockCallback)
+                .onSessionOpenRequest(
+                        SESSION_ID_FOR_OPEN_REQUEST, targetInfo, ENDPOINT_SERVICE_DESCRIPTOR);
+
+        // Accept
+        endpoint.openSessionRequestComplete(SESSION_ID_FOR_OPEN_REQUEST);
+        verify(mMockEndpointCommunications)
+                .endpointSessionOpenComplete(SESSION_ID_FOR_OPEN_REQUEST);
+
+        unregisterExampleEndpoint(endpoint);
+    }
+
+    @Test
+    public void testEndpointSessionOpenRequestWithInvalidSessionId() throws RemoteException {
+        assertThat(mEndpointManager.getNumAvailableSessions()).isEqualTo(SESSION_ID_RANGE);
+        IContextHubEndpoint endpoint = registerExampleEndpoint();
+
+        HubEndpointInfo targetInfo =
+                new HubEndpointInfo(
+                        TARGET_ENDPOINT_NAME,
+                        TARGET_ENDPOINT_ID,
+                        ENDPOINT_PACKAGE_NAME,
+                        Collections.emptyList());
+        mHubInfoRegistry.onEndpointStarted(new HubEndpointInfo[] {targetInfo});
+        mEndpointManager.onEndpointSessionOpenRequest(
+                INVALID_SESSION_ID_FOR_OPEN_REQUEST,
+                endpoint.getAssignedHubEndpointInfo().getIdentifier(),
+                targetInfo.getIdentifier(),
+                ENDPOINT_SERVICE_DESCRIPTOR);
+        verify(mMockEndpointCommunications)
+                .closeEndpointSession(
+                        INVALID_SESSION_ID_FOR_OPEN_REQUEST,
+                        Reason.OPEN_ENDPOINT_SESSION_REQUEST_REJECTED);
+        verify(mMockCallback, never())
+                .onSessionOpenRequest(
+                        INVALID_SESSION_ID_FOR_OPEN_REQUEST,
+                        targetInfo,
+                        ENDPOINT_SERVICE_DESCRIPTOR);
+
+        unregisterExampleEndpoint(endpoint);
+    }
+
+    @Test
+    public void testEndpointSessionOpenRequest_duplicatedSessionId_noopWhenSessionIsActive()
+            throws RemoteException {
+        assertThat(mEndpointManager.getNumAvailableSessions()).isEqualTo(SESSION_ID_RANGE);
+        IContextHubEndpoint endpoint = registerExampleEndpoint();
+
+        HubEndpointInfo targetInfo =
+                new HubEndpointInfo(
+                        TARGET_ENDPOINT_NAME,
+                        TARGET_ENDPOINT_ID,
+                        ENDPOINT_PACKAGE_NAME,
+                        Collections.emptyList());
+        mHubInfoRegistry.onEndpointStarted(new HubEndpointInfo[] {targetInfo});
+        mEndpointManager.onEndpointSessionOpenRequest(
+                SESSION_ID_FOR_OPEN_REQUEST,
+                endpoint.getAssignedHubEndpointInfo().getIdentifier(),
+                targetInfo.getIdentifier(),
+                ENDPOINT_SERVICE_DESCRIPTOR);
+        endpoint.openSessionRequestComplete(SESSION_ID_FOR_OPEN_REQUEST);
+        // Now session with id SESSION_ID_FOR_OPEN_REQUEST is active
+
+        // Duplicated session open request
+        mEndpointManager.onEndpointSessionOpenRequest(
+                SESSION_ID_FOR_OPEN_REQUEST,
+                endpoint.getAssignedHubEndpointInfo().getIdentifier(),
+                targetInfo.getIdentifier(),
+                ENDPOINT_SERVICE_DESCRIPTOR);
+
+        // Client API is only invoked once
+        verify(mMockCallback, times(1))
+                .onSessionOpenRequest(
+                        SESSION_ID_FOR_OPEN_REQUEST, targetInfo, ENDPOINT_SERVICE_DESCRIPTOR);
+        // HAL still receives two open complete notifications
+        verify(mMockEndpointCommunications, times(2))
+                .endpointSessionOpenComplete(SESSION_ID_FOR_OPEN_REQUEST);
+
+        unregisterExampleEndpoint(endpoint);
+    }
+
+    @Test
     public void testMessageTransaction() throws RemoteException {
         IContextHubEndpoint endpoint = registerExampleEndpoint();
         testMessageTransactionInternal(endpoint, /* deliverMessageStatus= */ true);
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 2868e55..f312a1b 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -17,8 +17,7 @@
 package com.android.server.locksettings;
 
 import static android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION;
-import static android.security.Flags.FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL;
-import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS;
+import static android.security.Flags.FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL;
 
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
@@ -265,7 +264,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+    @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
     public void setLockCredential_forPrimaryUser_clearsStrongAuthWhenFlagIsOn()
             throws Exception {
         setCredential(PRIMARY_USER_ID, newPassword("password"));
@@ -274,7 +273,7 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+    @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
     public void setLockCredential_forPrimaryUser_leavesStrongAuthWhenFlagIsOff()
             throws Exception {
         setCredential(PRIMARY_USER_ID, newPassword("password"));
@@ -313,7 +312,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+    @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
     public void setLockCredential_profileWithNewSeparateChallenge_clearsStrongAuthWhenFlagIsOn()
             throws Exception {
         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, true, null);
@@ -324,7 +323,7 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+    @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
     public void setLockCredential_profileWithNewSeparateChallenge_leavesStrongAuthWhenFlagIsOff()
             throws Exception {
         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, true, null);
@@ -378,7 +377,7 @@
     }
 
     @Test
-    @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+    @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
     public void setLockCredential_primaryWithUnifiedProfile_clearsStrongAuthForBothWhenFlagIsOn()
             throws Exception {
         final LockscreenCredential credential = newPassword("oldPassword");
@@ -394,7 +393,7 @@
     }
 
     @Test
-    @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL)
+    @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADDING_PRIMARY_CREDENTIAL)
     public void setLockCredential_primaryWithUnifiedProfile_leavesStrongAuthForBothWhenFlagIsOff()
             throws Exception {
         final LockscreenCredential credential = newPassword("oldPassword");
@@ -558,7 +557,6 @@
     @Test
     public void testVerifyCredential_notifyLockSettingsStateListeners_whenGoodPassword()
             throws Exception {
-        mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS);
         final LockscreenCredential password = newPassword("password");
         setCredential(PRIMARY_USER_ID, password);
         final LockSettingsStateListener listener = mock(LockSettingsStateListener.class);
@@ -574,7 +572,6 @@
     @Test
     public void testVerifyCredential_notifyLockSettingsStateListeners_whenBadPassword()
             throws Exception {
-        mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS);
         final LockscreenCredential password = newPassword("password");
         setCredential(PRIMARY_USER_ID, password);
         final LockscreenCredential badPassword = newPassword("badPassword");
@@ -590,7 +587,6 @@
 
     @Test
     public void testLockSettingsStateListener_registeredThenUnregistered() throws Exception {
-        mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS);
         final LockscreenCredential password = newPassword("password");
         setCredential(PRIMARY_USER_ID, password);
         final LockscreenCredential badPassword = newPassword("badPassword");
diff --git a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
index a58a9cd..4a05ea6 100644
--- a/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/media/projection/MediaProjectionManagerServiceTest.java
@@ -48,7 +48,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
@@ -488,7 +488,7 @@
 
         projection.stop(StopReason.STOP_UNKNOWN);
 
-        verifyZeroInteractions(mMediaProjectionMetricsLogger);
+        verifyNoMoreInteractions(mMediaProjectionMetricsLogger);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index d1b2e8e..1fb8411 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -274,7 +274,7 @@
     /** Test UserInfo.canHaveProfile for main user */
     @Test
     public void testCanHaveProfile() throws Exception {
-        UserInfo userInfo = createUser(100, FLAG_MAIN, null);
+        UserInfo userInfo = createUser(100, FLAG_FULL | FLAG_MAIN, null);
         assertTrue("Main users can have profile", userInfo.canHaveProfile());
     }
 
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java
index d55f967..2ed2704 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DynamicCodeLoggerTests.java
@@ -23,7 +23,7 @@
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.pm.ApplicationInfo;
@@ -273,7 +273,7 @@
 
         assertThat(mMessagesForUid).isEmpty();
         assertThat(mWriteTriggered).isFalse();
-        verifyZeroInteractions(mPM);
+        verifyNoMoreInteractions(mPM);
     }
 
     @Test
diff --git a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
index c7a06b8..339bac4 100644
--- a/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/security/advancedprotection/AdvancedProtectionServiceTest.java
@@ -259,7 +259,7 @@
 
         AdvancedProtectionProvider provider = new AdvancedProtectionProvider() {
             @Override
-            public List<AdvancedProtectionFeature> getFeatures() {
+            public List<AdvancedProtectionFeature> getFeatures(Context context) {
                 return List.of(feature2);
             }
         };
@@ -291,7 +291,7 @@
 
         AdvancedProtectionProvider provider = new AdvancedProtectionProvider() {
             @Override
-            public List<AdvancedProtectionFeature> getFeatures() {
+            public List<AdvancedProtectionFeature> getFeatures(Context context) {
                 return List.of(feature2);
             }
         };
diff --git a/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java b/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java
index b76e0bc..c107bd4 100644
--- a/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/security/authenticationpolicy/AuthenticationPolicyServiceTest.java
@@ -18,7 +18,6 @@
 
 import static android.adaptiveauth.Flags.FLAG_ENABLE_ADAPTIVE_AUTH;
 import static android.adaptiveauth.Flags.FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS;
-import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS;
 import static android.security.authenticationpolicy.AuthenticationPolicyManager.ERROR_UNSUPPORTED;
 
 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST;
@@ -112,7 +111,6 @@
         MockitoAnnotations.initMocks(this);
 
         mSetFlagsRule.enableFlags(FLAG_ENABLE_ADAPTIVE_AUTH);
-        mSetFlagsRule.enableFlags(FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS);
         mSetFlagsRule.enableFlags(FLAG_REPORT_BIOMETRIC_AUTH_ATTEMPTS);
 
         mContext = spy(ApplicationProvider.getApplicationContext());
diff --git a/services/tests/timetests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java b/services/tests/timetests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
index c8afb78..630a7e4 100644
--- a/services/tests/timetests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
+++ b/services/tests/timetests/src/com/android/server/timedetector/GnssTimeUpdateServiceTest.java
@@ -23,7 +23,7 @@
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.AlarmManager;
@@ -126,7 +126,7 @@
         locationListener.onLocationChanged(location);
 
         verify(mMockLocationManager).removeUpdates(locationListener);
-        verifyZeroInteractions(mMockTimeDetectorInternal);
+        verifyNoMoreInteractions(mMockTimeDetectorInternal);
         verify(mMockAlarmManager).set(
                 eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
                 anyLong(),
@@ -150,7 +150,7 @@
 
         // Verify the service returned to location listening.
         verify(mMockLocationManager).requestLocationUpdates(any(), any(), any(), any());
-        verifyZeroInteractions(mMockAlarmManager, mMockTimeDetectorInternal);
+        verifyNoMoreInteractions(mMockAlarmManager, mMockTimeDetectorInternal);
     }
 
     // Tests what happens when a call is made to startGnssListeningInternal() when service is
@@ -172,7 +172,7 @@
         // listening again.
         verify(mMockAlarmManager).cancel(alarmListenerCaptor.getValue());
         verify(mMockLocationManager).requestLocationUpdates(any(), any(), any(), any());
-        verifyZeroInteractions(mMockTimeDetectorInternal);
+        verifyNoMoreInteractions(mMockTimeDetectorInternal);
     }
 
     private void advanceServiceToSleepingState(
@@ -190,7 +190,7 @@
                 any(), any(), any(), locationListenerCaptor.capture());
         LocationListener locationListener = locationListenerCaptor.getValue();
         Location location = new Location(LocationManager.GPS_PROVIDER);
-        verifyZeroInteractions(mMockAlarmManager, mMockTimeDetectorInternal);
+        verifyNoMoreInteractions(mMockAlarmManager, mMockTimeDetectorInternal);
 
         locationListener.onLocationChanged(location);
 
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 66d7611..d34d74d 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -11,13 +11,8 @@
     default_applicable_licenses: ["frameworks_base_license"],
 }
 
-android_test {
-    name: "FrameworksUiServicesTests",
-
-    // Include test java files
-    srcs: [
-        "src/**/*.java",
-    ],
+java_defaults {
+    name: "FrameworksUiServicesTests-defaults",
 
     static_libs: [
         "compatibility-device-util-axt-minus-dexmaker",
@@ -95,12 +90,72 @@
     javacflags: ["-parameters"],
 }
 
-test_module_config {
-    name: "FrameworksUiServicesTests_notification",
-    base: "FrameworksUiServicesTests",
-    test_suites: [
-        "automotive-tests",
-        "device-tests",
+// Utility files used by multiple tests
+filegroup {
+    name: "shared-srcs",
+    srcs: [
+        "src/android/app/ExampleActivity.java",
+        "src/android/app/NotificationSystemUtil.java",
+        "src/com/android/frameworks/tests/uiservices/DummyProvider.java",
+        "src/com/android/internal/logging/InstanceIdSequenceFake.java",
+        "src/com/android/server/UiServiceTestCase.java",
+        "src/com/android/server/notification/ZenChangeOrigin.java",
+        "src/com/android/server/notification/ZenModeEventLoggerFake.java",
     ],
-    exclude_annotations: ["androidx.test.filters.LargeTest"],
+    visibility: ["//visibility:private"],
+}
+
+filegroup {
+    name: "notification-srcs",
+    srcs: [
+        "src/**/Notification*.java",
+        "src/com/android/server/notification/*.java",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+filegroup {
+    name: "notification-zen-srcs",
+    srcs: [
+        "src/android/app/NotificationManagerZenTest.java",
+        "src/com/android/server/notification/Zen*Test.java",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+android_test {
+    name: "FrameworksUiServicesTests",
+
+    // Include test java files but not the notification & zen ones which are separated
+    srcs: [
+        "src/**/*.java",
+    ],
+
+    exclude_srcs: [
+        ":notification-srcs",
+        ":notification-zen-srcs",
+    ],
+
+    defaults: ["FrameworksUiServicesTests-defaults"],
+}
+
+android_test {
+    name: "FrameworksUiServicesNotificationTests",
+    srcs: [
+        ":notification-srcs",
+        ":shared-srcs",
+    ],
+    exclude_srcs: [":notification-zen-srcs"],
+    defaults: ["FrameworksUiServicesTests-defaults"],
+    test_config: "notification-tests.xml",
+}
+
+android_test {
+    name: "FrameworksUiServicesZenTests",
+    srcs: [
+        ":notification-zen-srcs",
+        ":shared-srcs",
+    ],
+    defaults: ["FrameworksUiServicesTests-defaults"],
+    test_config: "notification-zen-tests.xml",
 }
diff --git a/services/tests/uiservicestests/AndroidTest.xml b/services/tests/uiservicestests/AndroidTest.xml
index 11e8f09..93c8c72 100644
--- a/services/tests/uiservicestests/AndroidTest.xml
+++ b/services/tests/uiservicestests/AndroidTest.xml
@@ -15,6 +15,7 @@
 -->
 <configuration description="Runs Frameworks UI Services Tests.">
     <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="cleanup-apks" value="true" />
         <option name="test-file-name" value="FrameworksUiServicesTests.apk" />
     </target_preparer>
 
diff --git a/services/tests/uiservicestests/notification-tests.xml b/services/tests/uiservicestests/notification-tests.xml
new file mode 100644
index 0000000..acfd844
--- /dev/null
+++ b/services/tests/uiservicestests/notification-tests.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs Frameworks UI Services Tests (notifications subset).">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="FrameworksUiServicesNotificationTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
+    <option name="test-tag" value="FrameworksUiServicesNotificationTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.frameworks.tests.uiservices" />
+        <option name="runner" value="android.testing.TestableInstrumentation" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/services/tests/uiservicestests/notification-zen-tests.xml b/services/tests/uiservicestests/notification-zen-tests.xml
new file mode 100644
index 0000000..01d8aab
--- /dev/null
+++ b/services/tests/uiservicestests/notification-zen-tests.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2025 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs Frameworks UI Services Tests (zen mode subset).">
+    <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+        <option name="cleanup-apks" value="true" />
+        <option name="test-file-name" value="FrameworksUiServicesZenTests.apk" />
+    </target_preparer>
+
+    <option name="test-suite-tag" value="apct" />
+    <option name="test-suite-tag" value="framework-base-presubmit" />
+    <option name="test-tag" value="FrameworksUiServicesZenTests" />
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="com.android.frameworks.tests.uiservices" />
+        <option name="runner" value="android.testing.TestableInstrumentation" />
+        <option name="hidden-api-checks" value="false"/>
+    </test>
+</configuration>
diff --git a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
index 9930c9f..7b1ce44 100644
--- a/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/UiModeManagerServiceTest.java
@@ -62,7 +62,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 import static org.testng.Assert.assertThrows;
 
@@ -992,7 +991,7 @@
                 () -> mService.requestProjection(mBinder, PROJECTION_TYPE_NONE, PACKAGE_NAME));
         verify(mContext, never()).enforceCallingPermission(
                 eq(Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION), any());
-        verifyZeroInteractions(mBinder);
+        verifyNoMoreInteractions(mBinder);
         assertEquals(PROJECTION_TYPE_NONE, mService.getActiveProjectionTypes());
     }
 
@@ -1008,7 +1007,7 @@
                 () -> mService.requestProjection(mBinder, multipleProjectionTypes, PACKAGE_NAME));
         verify(mContext, never()).enforceCallingPermission(
                 eq(Manifest.permission.TOGGLE_AUTOMOTIVE_PROJECTION), any());
-        verifyZeroInteractions(mBinder);
+        verifyNoMoreInteractions(mBinder);
         assertEquals(PROJECTION_TYPE_NONE, mService.getActiveProjectionTypes());
     }
 
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ConditionProvidersTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ConditionProvidersTest.java
index 6b989cb..b332331 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ConditionProvidersTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ConditionProvidersTest.java
@@ -38,7 +38,6 @@
 import android.platform.test.flag.junit.SetFlagsRule;
 import android.service.notification.Condition;
 
-import com.android.internal.R;
 import com.android.server.UiServiceTestCase;
 
 import org.junit.Before;
@@ -47,8 +46,6 @@
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
-import java.util.List;
-
 public class ConditionProvidersTest extends UiServiceTestCase {
 
     private ConditionProviders mProviders;
@@ -172,15 +169,4 @@
 
         assertTrue(mProviders.getApproved(userId, true).isEmpty());
     }
-
-    @Test
-    public void getDefaultDndAccessPackages_returnsPackages() {
-        mContext.getOrCreateTestableResources().addOverride(
-                R.string.config_defaultDndAccessPackages,
-                "com.example.a:com.example.b::::com.example.c");
-
-        List<String> packages = ConditionProviders.getDefaultDndAccessPackages(mContext);
-
-        assertThat(packages).containsExactly("com.example.a", "com.example.b", "com.example.c");
-    }
 }
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 5ce9a3e..8023bdd 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java
@@ -36,7 +36,6 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.KeyguardManager;
@@ -184,7 +183,7 @@
         mApplier.apply(noEffects, ORIGIN_USER_IN_SYSTEMUI);
 
         verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(false));
-        verifyZeroInteractions(mColorDisplayManager, mWallpaperManager, mUiModeManager);
+        verifyNoMoreInteractions(mColorDisplayManager, mWallpaperManager, mUiModeManager);
     }
 
     @Test
@@ -252,8 +251,8 @@
         // Wallpaper dimming was undone, Grayscale was applied, nothing else was touched.
         verify(mWallpaperManager).setWallpaperDimAmount(eq(0.0f));
         verify(mColorDisplayManager).setSaturationLevel(eq(0));
-        verifyZeroInteractions(mPowerManager);
-        verifyZeroInteractions(mUiModeManager);
+        verifyNoMoreInteractions(mPowerManager);
+        verifyNoMoreInteractions(mUiModeManager);
     }
 
     @Test
@@ -269,7 +268,7 @@
                 ORIGIN_APP);
 
         // Effect was not yet applied, but a broadcast receiver was registered.
-        verifyZeroInteractions(mUiModeManager);
+        verifyNoMoreInteractions(mUiModeManager);
         verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(),
                 intentFilterCaptor.capture(), anyInt());
         assertThat(intentFilterCaptor.getValue().getAction(0)).isEqualTo(Intent.ACTION_SCREEN_OFF);
@@ -337,7 +336,7 @@
                 origin.value());
 
         // Effect was not applied, will be on next screen-off.
-        verifyZeroInteractions(mUiModeManager);
+        verifyNoMoreInteractions(mUiModeManager);
         verify(mContext).registerReceiver(any(),
                 argThat(filter -> Intent.ACTION_SCREEN_OFF.equals(filter.getAction(0))),
                 anyInt());
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 46be9a5..1114365 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -60,7 +60,7 @@
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.annotation.SuppressLint;
@@ -313,7 +313,7 @@
                 getNotificationRecord(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
                 false);
         }
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -327,7 +327,7 @@
         }
         mGroupHelper.onNotificationPosted(
             getNotificationRecord(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -340,7 +340,7 @@
         }
         mGroupHelper.onNotificationPosted(
             getNotificationRecord(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.of(7)), false);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -353,7 +353,7 @@
         mGroupHelper.onNotificationPosted(
             getNotificationRecord(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a", false),
             false);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -1744,7 +1744,7 @@
             notificationList.add(r);
             mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
         }
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -1759,7 +1759,7 @@
             notificationList.add(r);
             mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
         }
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -1775,7 +1775,7 @@
             notificationList.add(r);
             mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
         }
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -1791,7 +1791,7 @@
             notificationList.add(r);
             mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
         }
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -1811,7 +1811,7 @@
                 String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.SYSTEM, "testGrp", true);
         notificationList.add(r);
         mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -1830,7 +1830,7 @@
                 String.valueOf(AUTOGROUP_AT_COUNT), UserHandle.of(7), "testGrp", true);
         notificationList.add(r);
         mGroupHelper.onNotificationPostedWithDelay(r, notificationList, summaryByGroup);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -1853,7 +1853,7 @@
             String.valueOf(AUTOGROUP_AT_COUNT + 1), UserHandle.SYSTEM, "testGrp", false);
         notificationList.add(child);
         mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -1877,7 +1877,7 @@
         notificationList.add(child);
         summaryByGroup.put(summary.getGroupKey(), summary);
         mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -2209,7 +2209,7 @@
             childrenToRemove.add(child);
         }
         mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
 
         // Remove all child notifications from the valid group => summary without children
         Mockito.reset(mCallback);
@@ -2273,7 +2273,7 @@
             }
         }
         mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
 
         // Remove some child notifications from the valid group, transform into a singleton group
         Mockito.reset(mCallback);
@@ -2329,7 +2329,7 @@
             notificationList.add(child);
         }
         mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
 
         // Remove all child notifications from the valid group => summary without children
         Mockito.reset(mCallback);
@@ -2343,7 +2343,7 @@
         mGroupHelper.onGroupedNotificationRemovedWithDelay(summary, notificationList,
                 summaryByGroup);
         // Check that nothing was force grouped
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -3837,7 +3837,7 @@
             mGroupHelper.onNotificationPostedWithDelay(child, notificationList, summaryByGroup);
             mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
         }
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
 
@@ -3861,7 +3861,7 @@
             mGroupHelper.onNotificationPostedWithDelay(summary, notificationList, summaryByGroup);
         }
         // FLAG_NOTIFICATION_FORCE_GROUP_SINGLETONS is disabled => don't force group
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
@@ -4498,7 +4498,7 @@
         mGroupHelper.onNotificationPostedWithDelay(extra, notifList, summaryByGroupKey);
 
         // no autogrouping should have occurred
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index bc8b7be..902171d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -16844,22 +16844,22 @@
     public void updateAutomaticZenRule_implicitRuleWithoutCPS_disallowedFromApp() throws Exception {
         setUpRealZenTest();
         mService.setCallerIsNormalPackage();
-        assertThat(mBinderService.getAutomaticZenRules()).isEmpty();
+        assertThat(mBinderService.getAutomaticZenRules().getList()).isEmpty();
 
         // Create an implicit zen rule by calling setNotificationPolicy from an app.
         mBinderService.setNotificationPolicy(mPkg, new NotificationManager.Policy(0, 0, 0), false);
-        assertThat(mBinderService.getAutomaticZenRules()).hasSize(1);
-        Map.Entry<String, AutomaticZenRule> rule = getOnlyElement(
-                mBinderService.getAutomaticZenRules().entrySet());
-        assertThat(rule.getValue().getOwner()).isNull();
-        assertThat(rule.getValue().getConfigurationActivity()).isNull();
+        assertThat(mBinderService.getAutomaticZenRules().getList()).hasSize(1);
+        AutomaticZenRule.AzrWithId rule = getOnlyElement(
+                (List<AutomaticZenRule.AzrWithId>) mBinderService.getAutomaticZenRules().getList());
+        assertThat(rule.mRule.getOwner()).isNull();
+        assertThat(rule.mRule.getConfigurationActivity()).isNull();
 
         // Now try to update said rule (e.g. disable it). Should fail.
         // We also validate the exception message because NPE could be thrown by all sorts of test
         // issues (e.g. misconfigured mocks).
-        rule.getValue().setEnabled(false);
+        rule.mRule.setEnabled(false);
         NullPointerException e = assertThrows(NullPointerException.class,
-                () -> mBinderService.updateAutomaticZenRule(rule.getKey(), rule.getValue(), false));
+                () -> mBinderService.updateAutomaticZenRule(rule.mId, rule.mRule, false));
         assertThat(e.getMessage()).isEqualTo(
                 "Rule must have a ConditionProviderService and/or configuration activity");
     }
@@ -16869,24 +16869,24 @@
     public void updateAutomaticZenRule_implicitRuleWithoutCPS_allowedFromSystem() throws Exception {
         setUpRealZenTest();
         mService.setCallerIsNormalPackage();
-        assertThat(mBinderService.getAutomaticZenRules()).isEmpty();
+        assertThat(mBinderService.getAutomaticZenRules().getList()).isEmpty();
 
         // Create an implicit zen rule by calling setNotificationPolicy from an app.
         mBinderService.setNotificationPolicy(mPkg, new NotificationManager.Policy(0, 0, 0), false);
-        assertThat(mBinderService.getAutomaticZenRules()).hasSize(1);
-        Map.Entry<String, AutomaticZenRule> rule = getOnlyElement(
-                mBinderService.getAutomaticZenRules().entrySet());
-        assertThat(rule.getValue().getOwner()).isNull();
-        assertThat(rule.getValue().getConfigurationActivity()).isNull();
+        assertThat(mBinderService.getAutomaticZenRules().getList()).hasSize(1);
+        AutomaticZenRule.AzrWithId rule = getOnlyElement(
+                (List<AutomaticZenRule.AzrWithId>) mBinderService.getAutomaticZenRules().getList());
+        assertThat(rule.mRule.getOwner()).isNull();
+        assertThat(rule.mRule.getConfigurationActivity()).isNull();
 
         // Now update said rule from Settings (e.g. disable it). Should work!
         mService.isSystemUid = true;
-        rule.getValue().setEnabled(false);
-        mBinderService.updateAutomaticZenRule(rule.getKey(), rule.getValue(), false);
+        rule.mRule.setEnabled(false);
+        mBinderService.updateAutomaticZenRule(rule.mId, rule.mRule, false);
 
-        Map.Entry<String, AutomaticZenRule> updatedRule = getOnlyElement(
-                mBinderService.getAutomaticZenRules().entrySet());
-        assertThat(updatedRule.getValue().isEnabled()).isFalse();
+        AutomaticZenRule.AzrWithId updatedRule = getOnlyElement(
+                (List<AutomaticZenRule.AzrWithId>) mBinderService.getAutomaticZenRules().getList());
+        assertThat(updatedRule.mRule.isEnabled()).isFalse();
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index a02f628..43228f4 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -96,7 +96,7 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.app.AppOpsManager;
@@ -6372,7 +6372,7 @@
         NotificationChannel same = new NotificationChannel("id", "Bah", IMPORTANCE_DEFAULT);
         mHelper.createNotificationChannel(PKG_P, 0, same, true, false, 0, false);
 
-        verifyZeroInteractions(mHandler);
+        verifyNoMoreInteractions(mHandler);
     }
 
     @Test
@@ -6398,7 +6398,7 @@
 
         mHelper.updateNotificationChannel(PKG_P, 0, same, false, 0, false);
 
-        verifyZeroInteractions(mHandler);
+        verifyNoMoreInteractions(mHandler);
     }
 
     @Test
@@ -6412,7 +6412,7 @@
     public void setShowBadge_same_doesNotRequestSort() {
         mHelper.setShowBadge(PKG_P, 0, true); // true == DEFAULT_SHOW_BADGE
 
-        verifyZeroInteractions(mHandler);
+        verifyNoMoreInteractions(mHandler);
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenConfigTrimmerTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenConfigTrimmerTest.java
deleted file mode 100644
index 154a905..0000000
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenConfigTrimmerTest.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2025 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.notification;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.os.Parcel;
-import android.service.notification.ZenModeConfig;
-import android.service.notification.ZenModeConfig.ZenRule;
-
-import androidx.test.ext.junit.runners.AndroidJUnit4;
-
-import com.android.internal.R;
-import com.android.server.UiServiceTestCase;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class ZenConfigTrimmerTest extends UiServiceTestCase {
-
-    private static final String TRUSTED_PACKAGE = "com.trust.me";
-    private static final int ONE_PERCENT = 1_500;
-
-    private ZenConfigTrimmer mTrimmer;
-
-    @Before
-    public void setUp() {
-        mContext.getOrCreateTestableResources().addOverride(
-                R.string.config_defaultDndAccessPackages, TRUSTED_PACKAGE);
-
-        mTrimmer = new ZenConfigTrimmer(mContext);
-    }
-
-    @Test
-    public void trimToMaximumSize_belowMax_untouched() {
-        ZenModeConfig config = new ZenModeConfig();
-        addZenRule(config, "1", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "2", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "3", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "4", "pkg2", 20 * ONE_PERCENT);
-        addZenRule(config, "5", "pkg2", 20 * ONE_PERCENT);
-
-        mTrimmer.trimToMaximumSize(config);
-
-        assertThat(config.automaticRules.keySet()).containsExactly("1", "2", "3", "4", "5");
-    }
-
-    @Test
-    public void trimToMaximumSize_exceedsMax_removesAllRulesOfLargestPackages() {
-        ZenModeConfig config = new ZenModeConfig();
-        addZenRule(config, "1", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "2", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "3", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "4", "pkg2", 20 * ONE_PERCENT);
-        addZenRule(config, "5", "pkg2", 20 * ONE_PERCENT);
-        addZenRule(config, "6", "pkg3", 35 * ONE_PERCENT);
-        addZenRule(config, "7", "pkg4", 38 * ONE_PERCENT);
-
-        mTrimmer.trimToMaximumSize(config);
-
-        assertThat(config.automaticRules.keySet()).containsExactly("1", "2", "3", "6");
-        assertThat(config.automaticRules.values().stream().map(r -> r.pkg).distinct())
-                .containsExactly("pkg1", "pkg3");
-    }
-
-    @Test
-    public void trimToMaximumSize_keepsRulesFromTrustedPackages() {
-        ZenModeConfig config = new ZenModeConfig();
-        addZenRule(config, "1", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "2", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "3", "pkg1", 10 * ONE_PERCENT);
-        addZenRule(config, "4", TRUSTED_PACKAGE, 60 * ONE_PERCENT);
-        addZenRule(config, "5", "pkg2", 20 * ONE_PERCENT);
-        addZenRule(config, "6", "pkg3", 35 * ONE_PERCENT);
-
-        mTrimmer.trimToMaximumSize(config);
-
-        assertThat(config.automaticRules.keySet()).containsExactly("4", "5");
-        assertThat(config.automaticRules.values().stream().map(r -> r.pkg).distinct())
-                .containsExactly(TRUSTED_PACKAGE, "pkg2");
-    }
-
-    /**
-     * Create a ZenRule that, when serialized to a Parcel, will take <em>approximately</em>
-     * {@code desiredSize} bytes (within 100 bytes). Try to make the tests not rely on a very tight
-     * fit.
-     */
-    private static void addZenRule(ZenModeConfig config, String id, String pkg, int desiredSize) {
-        ZenRule rule = new ZenRule();
-        rule.id = id;
-        rule.pkg = pkg;
-        config.automaticRules.put(id, rule);
-
-        // Make the ZenRule as large as desired. Not to the exact byte, because otherwise this
-        // test would have to be adjusted whenever we change the parceling of ZenRule in any way.
-        // (Still might need adjustment if we change the serialization _significantly_).
-        int nameLength = desiredSize - id.length() - pkg.length() - 232;
-        rule.name = "A".repeat(nameLength);
-
-        Parcel verification = Parcel.obtain();
-        try {
-            verification.writeParcelable(rule, 0);
-            assertThat(verification.dataSize()).isWithin(100).of(desiredSize);
-        } finally {
-            verification.recycle();
-        }
-    }
-}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index 5377102..bfce647 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -90,7 +90,6 @@
 import static com.android.os.dnd.DNDProtoEnums.ROOT_CONFIG;
 import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW;
 import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW;
-import static com.android.server.notification.Flags.FLAG_LIMIT_ZEN_CONFIG_SIZE;
 import static com.android.server.notification.Flags.FLAG_PREVENT_ZEN_DEVICE_EFFECTS_WHILE_DRIVING;
 import static com.android.server.notification.ZenModeEventLogger.ACTIVE_RULE_TYPE_MANUAL;
 import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE;
@@ -238,7 +237,6 @@
 @SmallTest
 @SuppressLint("GuardedBy") // It's ok for this test to access guarded methods from the service.
 @RunWith(ParameterizedAndroidJunit4.class)
-@EnableFlags(FLAG_LIMIT_ZEN_CONFIG_SIZE) // Should be parameterization, but off path does nothing.
 @TestableLooper.RunWithLooper
 public class ZenModeHelperTest extends UiServiceTestCase {
 
@@ -7485,45 +7483,6 @@
         assertThat(getZenRule(ruleId).lastActivation).isNull();
     }
 
-    @Test
-    @EnableFlags(FLAG_LIMIT_ZEN_CONFIG_SIZE)
-    public void addAutomaticZenRule_trimsConfiguration() {
-        mZenModeHelper.mConfig.automaticRules.clear();
-        AutomaticZenRule smallRule = new AutomaticZenRule.Builder("Reasonable", CONDITION_ID)
-                .setConfigurationActivity(new ComponentName(mPkg, "cls"))
-                .build();
-        AutomaticZenRule systemRule = new AutomaticZenRule.Builder("System", CONDITION_ID)
-                .setOwner(new ComponentName("android", "ScheduleConditionProvider"))
-                .build();
-
-        AutomaticZenRule bigRule = new AutomaticZenRule.Builder("Yuge", CONDITION_ID)
-                .setConfigurationActivity(new ComponentName("evil.package", "cls"))
-                .setTriggerDescription("0123456789".repeat(6000)) // ~60k bytes utf16.
-                .build();
-
-        String systemRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "android",
-                systemRule, ORIGIN_SYSTEM, "add", SYSTEM_UID);
-        String smallRuleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, smallRule,
-                ORIGIN_APP, "add", CUSTOM_PKG_UID);
-        String bigRuleId1 =  mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "evil.package",
-                bigRule, ORIGIN_APP, "add", CUSTOM_PKG_UID);
-        assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly(
-                systemRuleId, smallRuleId, bigRuleId1);
-
-        String bigRuleId2 =  mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "evil.package",
-                bigRule, ORIGIN_APP, "add", CUSTOM_PKG_UID);
-        assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly(
-                systemRuleId, smallRuleId, bigRuleId1, bigRuleId2);
-
-        // This should go over the threshold
-        String bigRuleId3 = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, "evil.package",
-                bigRule, ORIGIN_APP, "add", CUSTOM_PKG_UID);
-
-        // Rules from evil.package are gone.
-        assertThat(mZenModeHelper.mConfig.automaticRules.keySet()).containsExactly(
-                systemRuleId, smallRuleId);
-    }
-
     private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode,
             @Nullable ZenPolicy zenPolicy) {
         ZenRule rule = new ZenRule();
diff --git a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java
index 79e272b..01698b5 100644
--- a/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java
+++ b/services/tests/vibrator/src/com/android/server/vibrator/VibratorControlServiceTest.java
@@ -33,7 +33,6 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.ComponentName;
@@ -133,7 +132,7 @@
         mVibratorControlService.registerVibratorController(controller1);
         mVibratorControlService.unregisterVibratorController(controller2);
 
-        verifyZeroInteractions(mMockVibrationScaler);
+        verifyNoMoreInteractions(mMockVibrationScaler);
         assertThat(controller1.isLinkedToDeath).isTrue();
     }
 
@@ -187,7 +186,7 @@
         verify(mStatsLoggerMock).logVibrationParamResponseIgnored();
         verifyNoMoreInteractions(mStatsLoggerMock);
 
-        verifyZeroInteractions(mMockVibrationScaler);
+        verifyNoMoreInteractions(mMockVibrationScaler);
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -242,7 +241,7 @@
                 mFakeVibratorController);
 
         verify(mStatsLoggerMock, never()).logVibrationParamScale(anyFloat());
-        verifyZeroInteractions(mMockVibrationScaler);
+        verifyNoMoreInteractions(mMockVibrationScaler);
     }
 
     @Test(expected = IllegalArgumentException.class)
@@ -280,7 +279,7 @@
                 mFakeVibratorController);
 
         verify(mStatsLoggerMock, never()).logVibrationParamScale(anyFloat());
-        verifyZeroInteractions(mMockVibrationScaler);
+        verifyNoMoreInteractions(mMockVibrationScaler);
     }
 
     @Test
diff --git a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java
index 9a59ede..011971d 100644
--- a/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java
+++ b/services/tests/voiceinteractiontests/src/com/android/server/soundtrigger_middleware/SoundTriggerHalConcurrentCaptureHandlerTest.java
@@ -28,7 +28,6 @@
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyNoMoreInteractions;
-import static org.mockito.Mockito.verifyZeroInteractions;
 
 import android.media.soundtrigger.RecognitionStatus;
 import android.media.soundtrigger_middleware.RecognitionEventSys;
@@ -76,7 +75,7 @@
         assertEquals(event.halEventReceivedMillis, -1);
         assertEquals(event.recognitionEvent.status, RecognitionStatus.ABORTED);
         assertFalse(event.recognitionEvent.recognitionStillActive);
-        verifyZeroInteractions(mGlobalCallback);
+        verifyNoMoreInteractions(mGlobalCallback);
         clearInvocations(callback, mUnderlying);
 
         mNotifier.setActive(false);
diff --git a/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java b/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
index 036e03c..e473a06 100644
--- a/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/CombinationKeyTests.java
@@ -49,6 +49,7 @@
     @Before
     public void setUp() {
         setUpPhoneWindowManager();
+        mPhoneWindowManager.overrideStatusBarManagerInternal();
     }
 
     /**
diff --git a/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java b/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java
index 9e59bce..4ecf6ab 100644
--- a/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/policy/WindowWakeUpPolicyTests.java
@@ -145,8 +145,8 @@
         // Verify the policy wake up call succeeds because of the call on the delegate, and not
         // because of a PowerManager wake up.
         assertThat(mPolicy.wakeUpFromMotion(
-                mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true)).isTrue();
-        verify(mInputWakeUpDelegate).wakeUpFromMotion(200, SOURCE_TOUCHSCREEN, true);
+                mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true, false)).isTrue();
+        verify(mInputWakeUpDelegate).wakeUpFromMotion(200, SOURCE_TOUCHSCREEN, true, false);
         verifyNoPowerManagerWakeUp();
 
         setDelegatedMotionWakeUpResult(false);
@@ -154,8 +154,8 @@
         // Verify the policy wake up call succeeds because of the PowerManager wake up, since the
         // delegate would not handle the wake up request.
         assertThat(mPolicy.wakeUpFromMotion(
-                mDefaultDisplay.getDisplayId(), 300, SOURCE_ROTARY_ENCODER, false)).isTrue();
-        verify(mInputWakeUpDelegate).wakeUpFromMotion(300, SOURCE_ROTARY_ENCODER, false);
+                mDefaultDisplay.getDisplayId(), 300, SOURCE_ROTARY_ENCODER, false, false)).isTrue();
+        verify(mInputWakeUpDelegate).wakeUpFromMotion(300, SOURCE_ROTARY_ENCODER, false, false);
         verify(mPowerManager).wakeUp(300, WAKE_REASON_WAKE_MOTION, "android.policy:MOTION");
     }
 
@@ -214,8 +214,9 @@
 
         // Check that the wake up does not happen because the theater mode policy check fails.
         assertThat(mPolicy.wakeUpFromMotion(
-                mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true)).isFalse();
-        verify(mInputWakeUpDelegate, never()).wakeUpFromMotion(anyLong(), anyInt(), anyBoolean());
+                mDefaultDisplay.getDisplayId(), 200, SOURCE_TOUCHSCREEN, true, false)).isFalse();
+        verify(mInputWakeUpDelegate, never())
+                .wakeUpFromMotion(anyLong(), anyInt(), anyBoolean(), anyBoolean());
     }
 
     @Test
@@ -227,7 +228,8 @@
         setBooleanRes(config_allowTheaterModeWakeFromMotion, false);
         mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);
 
-        mPolicy.wakeUpFromMotion(mDefaultDisplay.getDisplayId(), 200L, SOURCE_TOUCHSCREEN, true);
+        mPolicy.wakeUpFromMotion(
+                mDefaultDisplay.getDisplayId(), 200L, SOURCE_TOUCHSCREEN, true, false);
 
         verify(mPowerManager).wakeUp(200L, WAKE_REASON_WAKE_MOTION, "android.policy:MOTION");
     }
@@ -237,7 +239,7 @@
     public void testWakeUpFromMotion() {
         runPowerManagerUpChecks(
                 () -> mPolicy.wakeUpFromMotion(mDefaultDisplay.getDisplayId(),
-                        mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, true),
+                        mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, true, false),
                 config_allowTheaterModeWakeFromMotion,
                 WAKE_REASON_WAKE_MOTION,
                 "android.policy:MOTION");
@@ -251,7 +253,8 @@
         mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);
 
         boolean displayWokeUp = mPolicy.wakeUpFromMotion(
-                displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true);
+                displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true,
+                /* deviceGoingToSleep= */ false);
 
         // Verify that display is woken up
         assertThat(displayWokeUp).isTrue();
@@ -267,7 +270,8 @@
         mPolicy = new WindowWakeUpPolicy(mContextSpy, mClock);
 
         boolean displayWokeUp = mPolicy.wakeUpFromMotion(
-                displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true);
+                displayId, mClock.uptimeMillis(), SOURCE_TOUCHSCREEN, /* isDown= */ true,
+                /* deviceGoingToSleep= */ false);
 
         // Verify that power is woken up and display isn't woken up individually
         assertThat(displayWokeUp).isTrue();
@@ -442,7 +446,7 @@
     }
 
     private void setDelegatedMotionWakeUpResult(boolean result) {
-        when(mInputWakeUpDelegate.wakeUpFromMotion(anyLong(), anyInt(), anyBoolean()))
+        when(mInputWakeUpDelegate.wakeUpFromMotion(anyLong(), anyInt(), anyBoolean(), anyBoolean()))
                 .thenReturn(result);
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 8992c2e..7f242de 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -2021,8 +2021,6 @@
         display.setFixedRotationLaunchingAppUnchecked(activity);
         displayRotation.updateRotationUnchecked(true /* forceUpdate */);
 
-        assertTrue(displayRotation.isRotatingSeamlessly());
-
         // The launching rotated app should not be cleared when waiting for remote rotation.
         display.continueUpdateOrientationForDiffOrienLaunchingApp();
         assertTrue(display.isFixedRotationLaunchingApp(activity));
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java
index fa7dcc8..81d753b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopAppCompatAspectRatioPolicyTests.java
@@ -35,6 +35,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 
 import android.compat.testing.PlatformCompatChangeRule;
 import android.content.pm.ActivityInfo;
@@ -413,7 +414,7 @@
 
         void setDesiredAspectRatio(float aspectRatio) {
             doReturn(aspectRatio).when(getDesktopAppCompatAspectRatioPolicy())
-                    .getDesiredAspectRatio(any());
+                    .getDesiredAspectRatio(any(), anyBoolean());
         }
 
         DesktopAppCompatAspectRatioPolicy getDesktopAppCompatAspectRatioPolicy() {
@@ -422,7 +423,7 @@
 
         float calculateAspectRatio() {
             return getDesktopAppCompatAspectRatioPolicy().calculateAspectRatio(
-                    getTopActivity().getTask());
+                    getTopActivity().getTask(), /* hasOrientationMismatch */ true);
         }
 
         ActivityRecord getTopActivity() {
diff --git a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
index 48731cb..f587d6e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DesktopModeLaunchParamsModifierTests.java
@@ -52,6 +52,7 @@
 
 import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.when;
@@ -383,7 +384,7 @@
         spyOn(mActivity.mAppCompatController.getAspectRatioOverrides());
         doReturn(true).when(
                         mActivity.mAppCompatController.getAspectRatioOverrides())
-                .isUserFullscreenOverrideEnabled();
+                .hasFullscreenOverride();
 
         final int desiredWidth =
                 (int) (LANDSCAPE_DISPLAY_BOUNDS.width() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
@@ -411,7 +412,7 @@
         spyOn(mActivity.mAppCompatController.getAspectRatioOverrides());
         doReturn(true).when(
                         mActivity.mAppCompatController.getAspectRatioOverrides())
-                .isSystemOverrideToFullscreenEnabled();
+                .hasFullscreenOverride();
 
         final int desiredWidth =
                 (int) (LANDSCAPE_DISPLAY_BOUNDS.width() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
@@ -437,7 +438,7 @@
 
         spyOn(activity.mAppCompatController.getDesktopAspectRatioPolicy());
         doReturn(LETTERBOX_ASPECT_RATIO).when(activity.mAppCompatController
-                .getDesktopAspectRatioPolicy()).calculateAspectRatio(any());
+                .getDesktopAspectRatioPolicy()).calculateAspectRatio(any(), anyBoolean());
 
         final int desiredWidth =
                 (int) ((LANDSCAPE_DISPLAY_BOUNDS.height() / LETTERBOX_ASPECT_RATIO) + 0.5f);
@@ -933,7 +934,7 @@
 
         spyOn(activity.mAppCompatController.getDesktopAspectRatioPolicy());
         doReturn(LETTERBOX_ASPECT_RATIO).when(activity.mAppCompatController
-                .getDesktopAspectRatioPolicy()).calculateAspectRatio(any());
+                .getDesktopAspectRatioPolicy()).calculateAspectRatio(any(), anyBoolean());
 
         final int desiredHeight =
                 (int) (LANDSCAPE_DISPLAY_BOUNDS.height() * DESKTOP_MODE_INITIAL_BOUNDS_SCALE);
@@ -1060,7 +1061,7 @@
 
         spyOn(activity.mAppCompatController.getDesktopAspectRatioPolicy());
         doReturn(LETTERBOX_ASPECT_RATIO).when(activity.mAppCompatController
-                .getDesktopAspectRatioPolicy()).calculateAspectRatio(any());
+                .getDesktopAspectRatioPolicy()).calculateAspectRatio(any(), anyBoolean());
 
         final int desiredWidth = PORTRAIT_DISPLAY_BOUNDS.width()
                 - (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2);
@@ -1115,7 +1116,7 @@
 
         spyOn(activity.mAppCompatController.getDesktopAspectRatioPolicy());
         doReturn(LETTERBOX_ASPECT_RATIO).when(activity.mAppCompatController
-                .getDesktopAspectRatioPolicy()).calculateAspectRatio(any());
+                .getDesktopAspectRatioPolicy()).calculateAspectRatio(any(), anyBoolean());
 
         final int desiredWidth = PORTRAIT_DISPLAY_BOUNDS.width()
                 - (DESKTOP_MODE_LANDSCAPE_APP_PADDING * 2);
@@ -1170,6 +1171,32 @@
     @Test
     @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
             Flags.FLAG_ENABLE_SHELL_INITIAL_BOUNDS_REGRESSION_BUG_FIX})
+    public void testOptionsBoundsSet_flexibleLaunchSizeWithFullscreenOverride_noModifications() {
+        setupDesktopModeLaunchParamsModifier();
+
+        final TestDisplayContent display = createNewDisplayContent(WINDOWING_MODE_FULLSCREEN);
+        final Task task = new TaskBuilder(mSupervisor).setActivityType(
+                ACTIVITY_TYPE_STANDARD).setDisplay(display).build();
+        final ActivityOptions options = ActivityOptions.makeBasic()
+                .setLaunchBounds(new Rect(
+                        DISPLAY_STABLE_BOUNDS.left,
+                        DISPLAY_STABLE_BOUNDS.top,
+                        /* right = */ 500,
+                        /* bottom = */ 500))
+                .setFlexibleLaunchSize(true);
+        spyOn(mActivity.mAppCompatController.getAspectRatioOverrides());
+        doReturn(true).when(
+                        mActivity.mAppCompatController.getAspectRatioOverrides())
+                .hasFullscreenOverride();
+
+        assertEquals(RESULT_DONE,
+                new CalculateRequestBuilder().setTask(task).setOptions(options).calculate());
+        assertEquals(options.getLaunchBounds(), mResult.mBounds);
+    }
+
+    @Test
+    @EnableFlags({Flags.FLAG_ENABLE_DESKTOP_WINDOWING_MODE,
+            Flags.FLAG_ENABLE_SHELL_INITIAL_BOUNDS_REGRESSION_BUG_FIX})
     public void testOptionsBoundsSet_flexibleLaunchSize_boundsSizeModified() {
         setupDesktopModeLaunchParamsModifier();
 
@@ -1543,7 +1570,7 @@
                 activity.mAppCompatController.getDesktopAspectRatioPolicy();
         spyOn(desktopAppCompatAspectRatioPolicy);
         doReturn(aspectRatio).when(desktopAppCompatAspectRatioPolicy)
-                .getDesiredAspectRatio(any());
+                .getDesiredAspectRatio(any(), anyBoolean());
     }
 
     private void applyUserMinAspectRatioOverride(ActivityRecord activity, int overrideCode,
@@ -1553,7 +1580,7 @@
                 activity.mAppCompatController.getDesktopAspectRatioPolicy();
         spyOn(desktopAppCompatAspectRatioPolicy);
         doReturn(1f).when(desktopAppCompatAspectRatioPolicy)
-                .getDesiredAspectRatio(any());
+                .getDesiredAspectRatio(any(), anyBoolean());
 
         // Enable user aspect ratio settings
         final AppCompatConfiguration appCompatConfiguration =
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
index 0af41ea..89aa3b9 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayAreaTest.java
@@ -56,7 +56,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.pm.ActivityInfo;
@@ -174,7 +174,7 @@
         da1.reduceOnAllTaskDisplayAreas(callback2, 0);
         da1.getItemFromTaskDisplayAreas(callback3);
 
-        verifyZeroInteractions(da2);
+        verifyNoMoreInteractions(da2);
 
         // Traverse the child if the current DA has type ANY
         final DisplayArea<WindowContainer> da3 = new DisplayArea<>(mWm, ANY, "DA3");
@@ -207,7 +207,7 @@
         da5.reduceOnAllTaskDisplayAreas(callback2, 0);
         da5.getItemFromTaskDisplayAreas(callback3);
 
-        verifyZeroInteractions(da6);
+        verifyNoMoreInteractions(da6);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index 4c81f73..ed00a9e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -30,7 +30,10 @@
 import static android.os.Build.VERSION_CODES.P;
 import static android.os.Build.VERSION_CODES.Q;
 import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.FLAG_ALLOWS_CONTENT_MODE_SWITCH;
 import static android.view.Display.FLAG_PRIVATE;
+import static android.view.Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
+import static android.view.Display.FLAG_TRUSTED;
 import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
 import static android.view.DisplayCutout.fromBoundingRect;
 import static android.view.Surface.ROTATION_0;
@@ -1706,8 +1709,6 @@
         app.setVisible(true);
         doReturn(false).when(app).inTransition();
         mDisplayContent.mFixedRotationTransitionListener.onAppTransitionFinishedLocked(app.token);
-        mStatusBarWindow.finishSeamlessRotation(t);
-        mNavBarWindow.finishSeamlessRotation(t);
 
         // The fixed rotation should be cleared and the new rotation is applied to display.
         assertFalse(app.hasFixedRotationTransform());
@@ -2925,6 +2926,63 @@
         assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
     }
 
+    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+    @Test
+    public void testSetShouldShowSystemDecorations_shouldShowSystemDecorationsDisplay() {
+        // Set up a non-default display with FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS enabled
+        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
+        displayInfo.displayId = DEFAULT_DISPLAY + 1;
+        displayInfo.flags = FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
+        final DisplayContent dc = createNewDisplay(displayInfo);
+
+        dc.onDisplayInfoChangeApplied();
+        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+    }
+
+    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+    @Test
+    public void testSetShouldShowSystemDecorations_notAllowContentModeSwitchDisplay() {
+        // Set up a non-default display without FLAG_ALLOWS_CONTENT_MODE_SWITCH enabled
+        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
+        displayInfo.displayId = DEFAULT_DISPLAY + 1;
+        displayInfo.flags = FLAG_TRUSTED;
+        final DisplayContent dc = createNewDisplay(displayInfo);
+
+        dc.onDisplayInfoChangeApplied();
+        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+    }
+
+    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+    @Test
+    public void testSetShouldShowSystemDecorations_untrustedDisplay() {
+        // Set up a non-default display without FLAG_TRUSTED enabled
+        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
+        displayInfo.displayId = DEFAULT_DISPLAY + 1;
+        displayInfo.flags = FLAG_ALLOWS_CONTENT_MODE_SWITCH;
+        final DisplayContent dc = createNewDisplay(displayInfo);
+
+        dc.onDisplayInfoChangeApplied();
+        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+    }
+
+    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
+    @Test
+    public void testSetShouldShowSystemDecorations_nonDefaultNonPrivateDisplay() {
+        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
+        displayInfo.displayId = DEFAULT_DISPLAY + 1;
+        displayInfo.flags = (FLAG_ALLOWS_CONTENT_MODE_SWITCH | FLAG_TRUSTED);
+        final DisplayContent dc = createNewDisplay(displayInfo);
+
+        spyOn(dc.mDisplay);
+        doReturn(false).when(dc.mDisplay).canHostTasks();
+        dc.onDisplayInfoChangeApplied();
+        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+
+        doReturn(true).when(dc.mDisplay).canHostTasks();
+        dc.onDisplayInfoChangeApplied();
+        assertTrue(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
+    }
+
     @EnableFlags(FLAG_ENABLE_PERSISTING_DISPLAY_SIZE_FOR_CONNECTED_DISPLAYS)
     @Test
     public void testForcedDensityRatioSetForExternalDisplays_persistDensityScaleFlagEnabled() {
@@ -2993,23 +3051,6 @@
         assertEquals(320, displayContent.mBaseDisplayDensity);
     }
 
-    @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT)
-    @Test
-    public void testSetShouldShowSystemDecorations_nonDefaultNonPrivateDisplay() {
-        final DisplayInfo displayInfo = new DisplayInfo(mDisplayInfo);
-        displayInfo.displayId = DEFAULT_DISPLAY + 1;
-        final DisplayContent dc = createNewDisplay(displayInfo);
-
-        spyOn(dc.mDisplay);
-        doReturn(false).when(dc.mDisplay).canHostTasks();
-        dc.onDisplayInfoChangeApplied();
-        assertFalse(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
-
-        doReturn(true).when(dc.mDisplay).canHostTasks();
-        dc.onDisplayInfoChangeApplied();
-        assertTrue(dc.mWmService.mDisplayWindowSettings.shouldShowSystemDecorsLocked(dc));
-    }
-
     private void removeRootTaskTests(Runnable runnable) {
         final TaskDisplayArea taskDisplayArea = mRootWindowContainer.getDefaultTaskDisplayArea();
         final Task rootTask1 = taskDisplayArea.createRootTask(WINDOWING_MODE_FULLSCREEN,
diff --git a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
index eb6d5cf..aa794b2d 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ImeInsetsSourceProviderTest.java
@@ -19,10 +19,15 @@
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
 
+import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
+import static com.android.server.wm.WindowStateAnimator.NO_SURFACE;
+
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
@@ -244,4 +249,52 @@
         verify(displayWindowInsetsController, times(1)).setImeInputTargetRequestedVisibility(
                 eq(true), any());
     }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
+    public void testOnPostLayout_resetServerVisibilityWhenImeIsNotDrawn() {
+        final WindowState ime = newWindowBuilder("ime", TYPE_INPUT_METHOD).build();
+        final WindowState inputTarget = newWindowBuilder("app", TYPE_APPLICATION).build();
+        makeWindowVisibleAndDrawn(ime);
+        mImeProvider.setWindowContainer(ime, null, null);
+        mImeProvider.setServerVisible(true);
+        mImeProvider.setClientVisible(true);
+        mImeProvider.updateVisibility();
+        mImeProvider.updateControlForTarget(inputTarget, true /* force */, null /* statsToken */);
+
+        // Calling onPostLayout, as the drawn state is initially false.
+        mImeProvider.onPostLayout();
+        assertTrue(mImeProvider.isSurfaceVisible());
+
+        // Reset window's drawn state
+        ime.mWinAnimator.mDrawState = NO_SURFACE;
+        mImeProvider.onPostLayout();
+        assertFalse(mImeProvider.isServerVisible());
+        assertFalse(mImeProvider.isSurfaceVisible());
+
+        // Set it back to drawn
+        ime.mWinAnimator.mDrawState = HAS_DRAWN;
+        mImeProvider.onPostLayout();
+        assertTrue(mImeProvider.isServerVisible());
+        assertTrue(mImeProvider.isSurfaceVisible());
+    }
+
+    @Test
+    @RequiresFlagsEnabled(Flags.FLAG_REFACTOR_INSETS_CONTROLLER)
+    public void testUpdateControlForTarget_differentControlTarget() throws RemoteException {
+        final WindowState oldTarget = newWindowBuilder("app", TYPE_APPLICATION).build();
+        final WindowState newTarget = newWindowBuilder("newapp", TYPE_APPLICATION).build();
+
+        oldTarget.setRequestedVisibleTypes(
+                WindowInsets.Type.defaultVisible() | WindowInsets.Type.ime());
+        mDisplayContent.setImeControlTarget(oldTarget);
+        mDisplayContent.setImeInputTarget(newTarget);
+
+        // Having a null windowContainer will early return in updateControlForTarget
+        mImeProvider.setWindowContainer(null, null, null);
+
+        clearInvocations(mDisplayContent);
+        mImeProvider.updateControlForTarget(newTarget, false /* force */, ImeTracker.Token.empty());
+        verify(mDisplayContent, never()).getImeInputTarget();
+    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 8a7e743..2c6884e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -52,7 +52,7 @@
 import static org.mockito.Mockito.reset;
 import static org.mockito.Mockito.times;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 
 import static java.lang.Integer.MAX_VALUE;
 
@@ -1293,7 +1293,7 @@
 
         // Add secondTask to top again
         mRecentTasks.add(secondTask);
-        verifyZeroInteractions(controller);
+        verifyNoMoreInteractions(controller);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
index d3f3269..0101c3c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RefreshRatePolicyTest.java
@@ -284,7 +284,7 @@
         assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
         assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
 
-        overrideWindow.setAnimatingTypes(WindowInsets.Type.statusBars());
+        overrideWindow.setAnimatingTypes(WindowInsets.Type.statusBars(), null /* statsToken */);
         assertEquals(LOW_MODE_ID, mPolicy.getPreferredModeId(overrideWindow));
         assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
         assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote);
@@ -304,7 +304,7 @@
         assertEquals(0, mPolicy.getPreferredMinRefreshRate(overrideWindow), FLOAT_TOLERANCE);
         assertEquals(0, mPolicy.getPreferredMaxRefreshRate(overrideWindow), FLOAT_TOLERANCE);
 
-        overrideWindow.setAnimatingTypes(WindowInsets.Type.statusBars());
+        overrideWindow.setAnimatingTypes(WindowInsets.Type.statusBars(), null /* statsToken */);
         assertEquals(0, mPolicy.getPreferredModeId(overrideWindow));
         assertTrue(mPolicy.updateFrameRateVote(overrideWindow));
         assertEquals(FRAME_RATE_VOTE_NONE, overrideWindow.mFrameRateVote);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 71e84c0..73102c4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -1147,7 +1147,8 @@
                 argThat(h -> (h.inputConfig & InputConfig.SPY) == 0));
 
         assertThrows(IllegalArgumentException.class, () ->
-                mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+                mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */,
+                        DEFAULT_DISPLAY, surfaceControl,
                         FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY,
                         null /* region */));
     }
@@ -1217,7 +1218,8 @@
                 eq(surfaceControl),
                 argThat(h -> (h.inputConfig & InputConfig.SPY) == 0));
 
-        mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+        mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */,
+                DEFAULT_DISPLAY, surfaceControl,
                 FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY,
                 null /* region */);
         verify(mTransaction).setInputWindowInfo(
@@ -1244,7 +1246,8 @@
                 eq(surfaceControl),
                 argThat(h -> (h.inputConfig & InputConfig.SENSITIVE_FOR_PRIVACY) == 0));
 
-        mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+        mWm.updateInputChannel(inputChannel.getToken(), null /* hostInputToken */,
+                DEFAULT_DISPLAY, surfaceControl,
                 FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
                 INPUT_FEATURE_SENSITIVE_FOR_PRIVACY,
                 null /* region */);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
index 9dc7026..5347f9a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowProcessControllerTests.java
@@ -382,12 +382,17 @@
         assertFalse(tracker.hasResumedActivity(mWpc.mUid));
         assertTrue(mWpc.hasForegroundActivities());
 
-        activity.setVisibility(false);
         activity.setVisibleRequested(false);
-        activity.setState(STOPPED, "test");
-
+        if (com.android.window.flags.Flags.useVisibleRequestedForProcessTracker()) {
+            assertTrue("PAUSING is visible", mWpc.hasVisibleActivities());
+            activity.setState(PAUSED, "test");
+        } else {
+            activity.setVisible(false);
+        }
         verify(tracker).onAllActivitiesInvisible(mWpc);
         assertFalse(mWpc.hasVisibleActivities());
+
+        activity.setState(STOPPED, "test");
         assertFalse(mWpc.hasForegroundActivities());
     }
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
index 59ee2f5..5624677 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowStateTests.java
@@ -23,9 +23,6 @@
 import static android.permission.flags.Flags.FLAG_SENSITIVE_NOTIFICATION_APP_PROTECTION;
 import static android.view.Display.DEFAULT_DISPLAY;
 import static android.view.InsetsSource.ID_IME;
-import static android.view.Surface.ROTATION_0;
-import static android.view.Surface.ROTATION_270;
-import static android.view.Surface.ROTATION_90;
 import static android.view.WindowInsets.Type.ime;
 import static android.view.WindowInsets.Type.navigationBars;
 import static android.view.WindowInsets.Type.statusBars;
@@ -88,7 +85,6 @@
 import android.content.ContentResolver;
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
-import android.graphics.Matrix;
 import android.graphics.Point;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -673,56 +669,6 @@
     }
 
     @Test
-    public void testSeamlesslyRotateWindow() {
-        final WindowState app = newWindowBuilder("app", TYPE_APPLICATION).build();
-        final SurfaceControl.Transaction t = spy(StubTransaction.class);
-
-        makeWindowVisible(app);
-        app.mSurfaceControl = mock(SurfaceControl.class);
-        final Rect frame = app.getFrame();
-        frame.set(10, 20, 60, 80);
-        app.updateSurfacePosition(t);
-        assertTrue(app.mLastSurfacePosition.equals(frame.left, frame.top));
-        app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_90, true /* requested */);
-        assertTrue(app.mSeamlesslyRotated);
-
-        // Verify we un-rotate the window state surface.
-        final Matrix matrix = new Matrix();
-        // Un-rotate 90 deg.
-        matrix.setRotate(270);
-        // Translate it back to origin.
-        matrix.postTranslate(0, mDisplayInfo.logicalWidth);
-        verify(t).setMatrix(eq(app.mSurfaceControl), eq(matrix), any(float[].class));
-
-        // Verify we update the position as well.
-        final float[] curSurfacePos = {app.mLastSurfacePosition.x, app.mLastSurfacePosition.y};
-        matrix.mapPoints(curSurfacePos);
-        verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1]));
-
-        app.finishSeamlessRotation(t);
-        assertFalse(app.mSeamlesslyRotated);
-        assertNull(app.mPendingSeamlessRotate);
-
-        // Simulate the case with deferred layout and animation.
-        app.resetSurfacePositionForAnimationLeash(t);
-        clearInvocations(t);
-        mWm.mWindowPlacerLocked.deferLayout();
-        app.updateSurfacePosition(t);
-        // Because layout is deferred, the position should keep the reset value.
-        assertTrue(app.mLastSurfacePosition.equals(0, 0));
-
-        app.seamlesslyRotateIfAllowed(t, ROTATION_0, ROTATION_270, true /* requested */);
-        // The last position must be updated so the surface can be unrotated properly.
-        assertTrue(app.mLastSurfacePosition.equals(frame.left, frame.top));
-        matrix.setRotate(90);
-        matrix.postTranslate(mDisplayInfo.logicalHeight, 0);
-        curSurfacePos[0] = frame.left;
-        curSurfacePos[1] = frame.top;
-        matrix.mapPoints(curSurfacePos);
-        verify(t).setPosition(eq(app.mSurfaceControl), eq(curSurfacePos[0]), eq(curSurfacePos[1]));
-    }
-
-    @Test
     public void testVisibilityChangeSwitchUser() {
         final WindowState window = newWindowBuilder("app", TYPE_APPLICATION).build();
         window.mHasSurface = true;
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
index a02c3db..8907a72 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTokenTests.java
@@ -17,6 +17,8 @@
 package com.android.server.wm;
 
 import static android.view.InsetsSource.ID_IME;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_90;
 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
 import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -35,16 +37,19 @@
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 import android.content.res.Configuration;
+import android.graphics.Matrix;
 import android.os.Bundle;
 import android.os.IBinder;
 import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
+import android.view.SurfaceControl;
 import android.view.WindowInsets;
 import android.window.WindowContext;
 
@@ -335,6 +340,31 @@
     }
 
     @Test
+    public void testSeamlesslyRotate() {
+        final SurfaceControl.Transaction t = mTransaction;
+        final TestWindowToken token = createTestWindowToken(0, mDisplayContent);
+        token.mLastSurfacePosition.x = 10;
+        token.mLastSurfacePosition.y = 20;
+        final SeamlessRotator rotator = new SeamlessRotator(ROTATION_0, ROTATION_90,
+                mDisplayContent.getDisplayInfo(), false /* applyFixedTransformationHint */);
+        clearInvocations(t);
+        rotator.unrotate(t, token);
+
+        // Verify surface is un-rotated.
+        final Matrix matrix = new Matrix();
+        // Un-rotate 90 deg.
+        matrix.setRotate(270);
+        // Translate it back to origin.
+        matrix.postTranslate(0, mDisplayInfo.logicalWidth);
+        verify(t).setMatrix(eq(token.mSurfaceControl), eq(matrix), any(float[].class));
+
+        final float[] curSurfacePos = {token.mLastSurfacePosition.x, token.mLastSurfacePosition.y};
+        matrix.mapPoints(curSurfacePos);
+        verify(t).setPosition(eq(token.mSurfaceControl),
+                eq(curSurfacePos[0]), eq(curSurfacePos[1]));
+    }
+
+    @Test
     @EnableFlags(Flags.FLAG_REPARENT_WINDOW_TOKEN_API)
     public void onDisplayChanged_differentDisplay_reparented() {
         final TestWindowToken token = createTestWindowToken(0, mDisplayContent);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingLegacyTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingLegacyTest.java
index a1d35a7..0749c0b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingLegacyTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingLegacyTest.java
@@ -22,7 +22,7 @@
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
@@ -118,7 +118,7 @@
     @Test
     public void trace_discared_whenNotTracing() {
         mWindowTracing.logState("where");
-        verifyZeroInteractions(mWmMock);
+        verifyNoMoreInteractions(mWmMock);
     }
 
     @Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTracingPerfettoTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingPerfettoTest.java
index 9367941..3da279b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTracingPerfettoTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingPerfettoTest.java
@@ -22,7 +22,7 @@
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.times;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
-import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyZeroInteractions;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
@@ -128,7 +128,7 @@
     @Test
     public void trace_ignoresLogStateCalls_ifTracingIsDisabled() {
         sWindowTracing.logState("where");
-        verifyZeroInteractions(sWmMock);
+        verifyNoMoreInteractions(sWmMock);
     }
 
     @Test
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index 9e57fd3..c244168 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -23,6 +23,7 @@
 import android.annotation.SystemApi;
 import android.annotation.TestApi;
 import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Intent;
 import android.content.pm.ServiceInfo;
 import android.net.Uri;
 import android.os.BadParcelableException;
@@ -1174,6 +1175,10 @@
                 int callerNumberVerificationStatus,
                 Uri contactPhotoUri,
                 UserHandle originatingUser) {
+            if (extras == null) {
+                extras = new Bundle();
+            }
+            extras.putParcelable(Intent.EXTRA_USER_HANDLE, originatingUser);
             mState = state;
             mTelecomCallId = telecomCallId;
             mHandle = handle;
diff --git a/telecomm/java/android/telecom/ParcelableCall.java b/telecomm/java/android/telecom/ParcelableCall.java
index bd004e5..07278e7 100644
--- a/telecomm/java/android/telecom/ParcelableCall.java
+++ b/telecomm/java/android/telecom/ParcelableCall.java
@@ -19,7 +19,6 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.compat.annotation.UnsupportedAppUsage;
-import android.content.Intent;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -687,9 +686,6 @@
             source.readList(conferenceableCallIds, classLoader, java.lang.String.class);
             Bundle intentExtras = source.readBundle(classLoader);
             Bundle extras = source.readBundle(classLoader);
-            if (extras == null) {
-                extras = new Bundle();
-            }
             int supportedAudioRoutes = source.readInt();
             boolean isRttCallChanged = source.readByte() == 1;
             ParcelableRttCall rttCall = source.readParcelable(classLoader, android.telecom.ParcelableRttCall.class);
@@ -700,7 +696,6 @@
             String activeChildCallId = source.readString();
             Uri contactPhotoUri = source.readParcelable(classLoader, Uri.class);
             UserHandle associatedUser = source.readParcelable(classLoader, UserHandle.class);
-            extras.putParcelable(Intent.EXTRA_USER_HANDLE, associatedUser);
             return new ParcelableCallBuilder()
                     .setId(id)
                     .setState(state)
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 50c5a6b6..1491510 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -3918,6 +3918,22 @@
             "5g_icon_display_secondary_grace_period_string";
 
     /**
+     * When an NR advanced connection is lost and a Physical Cell ID (PCI) change occurs within
+     * the primary timer{@link #KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING}, delay updating the network
+     * icon.
+     *
+     * <p>This delay is implemented because a rapid PCI change often indicates the device is
+     * switching to a nearby cell tower to quickly restore the NR advanced connection. Displaying
+     * an intermediate network icon (like 4G/LTE) might be misleading if the 5G connection is
+     * restored shortly after. This value sets the delay in seconds; 0 disables the feature.</p>
+     *
+     * @hide
+     */
+    public static final String KEY_NR_ADVANCED_PCI_CHANGE_SECONDARY_TIMER_SECONDS_INT =
+            "nr_advanced_pci_change_secondary_timer_seconds_int";
+
+
+    /**
      * The secondary grace periods in seconds to use if NR advanced icon was shown due to connecting
      * to bands specified in {@link #KEY_ADDITIONAL_NR_ADVANCED_BANDS_INT_ARRAY}.
      *
@@ -11222,6 +11238,7 @@
                         + "not_restricted_rrc_con:5G");
         sDefaults.putString(KEY_5G_ICON_DISPLAY_GRACE_PERIOD_STRING, "");
         sDefaults.putString(KEY_5G_ICON_DISPLAY_SECONDARY_GRACE_PERIOD_STRING, "");
+        sDefaults.putInt(KEY_NR_ADVANCED_PCI_CHANGE_SECONDARY_TIMER_SECONDS_INT, 0);
         sDefaults.putInt(KEY_NR_ADVANCED_BANDS_SECONDARY_TIMER_SECONDS_INT, 0);
         sDefaults.putBoolean(KEY_NR_TIMERS_RESET_IF_NON_ENDC_AND_RRC_IDLE_BOOL, false);
         sDefaults.putBoolean(KEY_NR_TIMERS_RESET_ON_VOICE_QOS_BOOL, false);
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index f528263..6e23edf 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -614,7 +614,7 @@
 
     /** @hide */
     public static int convertRssiAsuToDBm(int rssiAsu) {
-        if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
+        if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN || rssiAsu == Integer.MAX_VALUE) {
             return CellInfo.UNAVAILABLE;
         }
         if ((rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
diff --git a/telephony/java/android/telephony/PreciseDataConnectionState.java b/telephony/java/android/telephony/PreciseDataConnectionState.java
index e6515f13..850ce3e 100644
--- a/telephony/java/android/telephony/PreciseDataConnectionState.java
+++ b/telephony/java/android/telephony/PreciseDataConnectionState.java
@@ -16,7 +16,6 @@
 
 package android.telephony;
 
-import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
@@ -39,7 +38,6 @@
 import android.telephony.data.DataCallResponse;
 import android.telephony.data.Qos;
 
-import com.android.internal.telephony.flags.Flags;
 import com.android.internal.telephony.util.TelephonyUtils;
 
 import java.lang.annotation.Retention;
@@ -89,35 +87,30 @@
      * Unsupported. The unsupported state is used when the data network cannot support the network
      * validation function for the current data connection state.
      */
-    @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
     public static final int NETWORK_VALIDATION_UNSUPPORTED = 0;
 
     /**
      * Not Requested. The not requested status is used when the data network supports the network
      * validation function, but no network validation is being performed yet.
      */
-    @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
     public static final int NETWORK_VALIDATION_NOT_REQUESTED = 1;
 
     /**
      * In progress. The in progress state is used when the network validation process for the data
      * network is in progress. This state is followed by either success or failure.
      */
-    @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
     public static final int NETWORK_VALIDATION_IN_PROGRESS = 2;
 
     /**
      * Success. The Success status is used when network validation has been completed for the data
      * network and the result is successful.
      */
-    @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
     public static final int NETWORK_VALIDATION_SUCCESS = 3;
 
     /**
      * Failure. The Failure status is used when network validation has been completed for the data
      * network and the result is failure.
      */
-    @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
     public static final int NETWORK_VALIDATION_FAILURE = 4;
 
     /**
@@ -360,7 +353,6 @@
      *
      * @return the network validation status of the data call
      */
-    @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
     public @NetworkValidationStatus int getNetworkValidationStatus() {
         return mNetworkValidationStatus;
     }
@@ -615,7 +607,6 @@
          * @param networkValidationStatus the network validation status of the data call
          * @return The builder
          */
-        @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
         public @NonNull Builder setNetworkValidationStatus(
                 @NetworkValidationStatus int networkValidationStatus) {
             mNetworkValidationStatus = networkValidationStatus;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 14d567d..7b2e6c2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -691,7 +691,7 @@
             case UNKNOWN:
                 modemCount = 1;
                 // check for voice and data support, 0 if not supported
-                if (!isVoiceCapable() && !isSmsCapable() && !isDataCapable()) {
+                if (!isDeviceVoiceCapable() && !isSmsCapable() && !isDataCapable()) {
                     modemCount = 0;
                 }
                 break;
@@ -2814,7 +2814,7 @@
      */
     @RequiresFeature(PackageManager.FEATURE_TELEPHONY)
     public int getPhoneType() {
-        if (!isVoiceCapable() && !isDataCapable()) {
+        if (!isDeviceVoiceCapable() && !isDataCapable()) {
             return PHONE_TYPE_NONE;
         }
         return getCurrentPhoneType();
@@ -15347,11 +15347,15 @@
      * {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE}
      *
      * @throws UnsupportedOperationException If the device does not have
-     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING}.
+     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING} or
+     *          {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}.
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+    @RequiresFeature(anyOf = {
+        PackageManager.FEATURE_TELEPHONY_CALLING,
+        PackageManager.FEATURE_TELEPHONY_MESSAGING
+    })
     @SystemApi
     public void notifyOtaEmergencyNumberDbInstalled() {
         try {
@@ -15376,11 +15380,15 @@
      * {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION}
      *
      * @throws UnsupportedOperationException If the device does not have
-     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING}.
+     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING} or
+     *          {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}.
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+    @RequiresFeature(anyOf = {
+        PackageManager.FEATURE_TELEPHONY_CALLING,
+        PackageManager.FEATURE_TELEPHONY_MESSAGING
+    })
     @SystemApi
     public void updateOtaEmergencyNumberDbFilePath(
             @NonNull ParcelFileDescriptor otaParcelFileDescriptor) {
@@ -15404,11 +15412,15 @@
      * {@link android.Manifest.permission#READ_ACTIVE_EMERGENCY_SESSION}
      *
      * @throws UnsupportedOperationException If the device does not have
-     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING}.
+     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING} or
+     *          {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}.
      * @hide
      */
     @RequiresPermission(android.Manifest.permission.READ_ACTIVE_EMERGENCY_SESSION)
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+    @RequiresFeature(anyOf = {
+        PackageManager.FEATURE_TELEPHONY_CALLING,
+        PackageManager.FEATURE_TELEPHONY_MESSAGING
+    })
     @SystemApi
     public void resetOtaEmergencyNumberDbFilePath() {
         try {
@@ -15490,11 +15502,15 @@
      * or throw a SecurityException if the caller does not have the permission.
      *
      * @throws UnsupportedOperationException If the device does not have
-     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING}.
+     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING} or
+     *          {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}.
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     @NonNull
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+    @RequiresFeature(anyOf = {
+        PackageManager.FEATURE_TELEPHONY_CALLING,
+        PackageManager.FEATURE_TELEPHONY_MESSAGING
+    })
     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList() {
         Map<Integer, List<EmergencyNumber>> emergencyNumberList = new HashMap<>();
         try {
@@ -15548,11 +15564,15 @@
      * or throw a SecurityException if the caller does not have the permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
      * @throws UnsupportedOperationException If the device does not have
-     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING}.
+     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING} or
+     *          {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}.
      */
     @RequiresPermission(android.Manifest.permission.READ_PHONE_STATE)
     @NonNull
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+    @RequiresFeature(anyOf = {
+        PackageManager.FEATURE_TELEPHONY_CALLING,
+        PackageManager.FEATURE_TELEPHONY_MESSAGING
+    })
     public Map<Integer, List<EmergencyNumber>> getEmergencyNumberList(
             @EmergencyServiceCategories int categories) {
         Map<Integer, List<EmergencyNumber>> emergencyNumberListForCategories = new HashMap<>();
@@ -15618,9 +15638,13 @@
      * SIM card(s), Android database, modem, network or defaults; {@code false} otherwise.
      * @throws IllegalStateException if the Telephony process is not currently available.
      * @throws UnsupportedOperationException If the device does not have
-     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING}.
+     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING} or
+     *          {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}.
      */
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+    @RequiresFeature(anyOf = {
+        PackageManager.FEATURE_TELEPHONY_CALLING,
+        PackageManager.FEATURE_TELEPHONY_MESSAGING
+    })
     public boolean isEmergencyNumber(@NonNull String number) {
         try {
             ITelephony telephony = getITelephony();
@@ -15657,7 +15681,8 @@
      * have the required permission/privileges
      * @throws IllegalStateException if the Telephony process is not currently available.
      * @throws UnsupportedOperationException If the device does not have
-     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING}.
+     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING} or
+     *          {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}.
      *
      * @deprecated Please use {@link TelephonyManager#isEmergencyNumber(String)} instead.
      * @hide
@@ -15665,7 +15690,10 @@
     @Deprecated
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+    @RequiresFeature(anyOf = {
+        PackageManager.FEATURE_TELEPHONY_CALLING,
+        PackageManager.FEATURE_TELEPHONY_MESSAGING
+    })
     public boolean isPotentialEmergencyNumber(@NonNull String number) {
         try {
             ITelephony telephony = getITelephony();
@@ -15685,15 +15713,19 @@
      * Returns the emergency number database version.
      *
      * <p>Requires Permission:
-     *   {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE READ_PRIVILEGED_PHONE_STATE}
+     *   {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE}
      *
      * @throws UnsupportedOperationException If the device does not have
-     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING}.
+     *          {@link PackageManager#FEATURE_TELEPHONY_CALLING} or
+     *          {@link PackageManager#FEATURE_TELEPHONY_MESSAGING}.
      * @hide
      */
     @SystemApi
     @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
-    @RequiresFeature(PackageManager.FEATURE_TELEPHONY_CALLING)
+    @RequiresFeature(anyOf = {
+        PackageManager.FEATURE_TELEPHONY_CALLING,
+        PackageManager.FEATURE_TELEPHONY_MESSAGING
+    })
     public int getEmergencyNumberDbVersion() {
         try {
             ITelephony telephony = getITelephony();
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index b6f9e1f..0e70306 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -17,7 +17,6 @@
 
 package android.telephony.data;
 
-import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -32,7 +31,6 @@
 import android.telephony.data.ApnSetting.ProtocolType;
 
 import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.telephony.flags.Flags;
 import com.android.internal.util.Preconditions;
 
 import java.lang.annotation.Retention;
@@ -455,7 +453,6 @@
      *
      * @return The network validation status of data connection.
      */
-    @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
     public @PreciseDataConnectionState.NetworkValidationStatus int getNetworkValidationStatus() {
         return mNetworkValidationStatus;
     }
@@ -936,7 +933,6 @@
          * @param status The network validation status.
          * @return The same instance of the builder.
          */
-        @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
         public @NonNull Builder setNetworkValidationStatus(
                 @PreciseDataConnectionState.NetworkValidationStatus int status) {
             mNetworkValidationStatus = status;
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index f04e1c9..5baf463 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -17,7 +17,6 @@
 package android.telephony.data;
 
 import android.annotation.CallbackExecutor;
-import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.IntRange;
 import android.annotation.NonNull;
@@ -40,7 +39,6 @@
 
 import com.android.internal.annotations.VisibleForTesting;
 import com.android.internal.telephony.IIntegerConsumer;
-import com.android.internal.telephony.flags.Flags;
 import com.android.internal.util.FunctionalUtils;
 import com.android.telephony.Rlog;
 
@@ -414,7 +412,6 @@
          * @param resultCodeCallback Listener for the {@link DataServiceCallback.ResultCode} that
          *     request validation to the DataService and checks if the request has been submitted.
          */
-        @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
         public void requestNetworkValidation(int cid,
                 @NonNull @CallbackExecutor Executor executor,
                 @NonNull @DataServiceCallback.ResultCode Consumer<Integer> resultCodeCallback) {
diff --git a/telephony/java/android/telephony/data/QualifiedNetworksService.java b/telephony/java/android/telephony/data/QualifiedNetworksService.java
index f775de6..c42b29c1 100644
--- a/telephony/java/android/telephony/data/QualifiedNetworksService.java
+++ b/telephony/java/android/telephony/data/QualifiedNetworksService.java
@@ -17,7 +17,6 @@
 package android.telephony.data;
 
 import android.annotation.CallbackExecutor;
-import android.annotation.FlaggedApi;
 import android.annotation.NonNull;
 import android.annotation.SystemApi;
 import android.app.Service;
@@ -41,7 +40,6 @@
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.flags.FeatureFlags;
 import com.android.internal.telephony.flags.FeatureFlagsImpl;
-import com.android.internal.telephony.flags.Flags;
 import com.android.internal.util.FunctionalUtils;
 import com.android.telephony.Rlog;
 
@@ -290,7 +288,6 @@
          * @param resultCodeCallback A callback to determine whether the request was successfully
          *     submitted or not.
          */
-        @FlaggedApi(Flags.FLAG_NETWORK_VALIDATION)
         public void requestNetworkValidation(
                 @NetCapability int networkCapability,
                 @NonNull @CallbackExecutor Executor executor,
@@ -298,15 +295,6 @@
             Objects.requireNonNull(executor, "executor cannot be null");
             Objects.requireNonNull(resultCodeCallback, "resultCodeCallback cannot be null");
 
-            if (!sFeatureFlag.networkValidation()) {
-                loge("networkValidation feature is disabled");
-                executor.execute(
-                        () ->
-                                resultCodeCallback.accept(
-                                        DataServiceCallback.RESULT_ERROR_UNSUPPORTED));
-                return;
-            }
-
             IIntegerConsumer callback = new IIntegerConsumer.Stub() {
                 @Override
                 public void accept(int result) {
diff --git a/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java b/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java
index c52be7c..8e01259 100644
--- a/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java
+++ b/tests/FsVerityTest/FsVerityTestApp/src/com/android/fsverity/Helper.java
@@ -21,7 +21,10 @@
 import static org.junit.Assert.assertThrows;
 
 import android.content.Context;
+import android.os.Bundle;
 import android.security.FileIntegrityManager;
+import android.system.Os;
+import android.system.OsConstants;
 import android.util.Log;
 
 import androidx.test.core.app.ApplicationProvider;
@@ -35,8 +38,9 @@
 import java.io.FileOutputStream;
 import java.io.IOException;
 import java.io.RandomAccessFile;
-import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
 
 /**
  * Test helper that works with the host-side test to set up a test file, and to verify fs-verity
@@ -47,8 +51,6 @@
 
     private static final String FILENAME = "test.file";
 
-    private static final long BLOCK_SIZE = 4096;
-
     @Rule
     public final AdoptShellPermissionsRule mAdoptShellPermissionsRule =
             new AdoptShellPermissionsRule(
@@ -58,7 +60,7 @@
     @Test
     public void prepareTest() throws Exception {
         Context context = ApplicationProvider.getApplicationContext();
-        android.os.Bundle testArgs = InstrumentationRegistry.getArguments();
+        Bundle testArgs = InstrumentationRegistry.getArguments();
 
         String basename = testArgs.getString("basename");
         context.deleteFile(basename);
@@ -84,31 +86,52 @@
         fim.setupFsVerity(context.getFileStreamPath(basename));
     }
 
+    private static long getPageSize() {
+        String arch = System.getProperty("os.arch");
+        Log.d(TAG, "os.arch=" + arch);
+        if ("x86_64".equals(arch)) {
+            // Override the fake 16K page size from cf_x86_64_pgagnostic.  The real page size on
+            // x86_64 is always 4K.  This test needs the real page size because it is testing I/O
+            // error reporting behavior that is dependent on the real page size.
+            return 4096;
+        }
+        return Os.sysconf(OsConstants._SC_PAGE_SIZE);
+    }
+
     @Test
     public void verifyFileRead() throws Exception {
         Context context = ApplicationProvider.getApplicationContext();
 
-        // Collect indices that the backing blocks are supposed to be corrupted.
-        android.os.Bundle testArgs = InstrumentationRegistry.getArguments();
+        Bundle testArgs = InstrumentationRegistry.getArguments();
         assertThat(testArgs).isNotNull();
         String filePath = testArgs.getString("filePath");
-        String csv = testArgs.getString("brokenBlockIndicesCsv");
-        Log.d(TAG, "brokenBlockIndicesCsv: " + csv);
-        String[] strings = csv.split(",");
-        var corrupted = new ArrayList(strings.length);
-        for (int i = 0; i < strings.length; i++) {
-            corrupted.add(Integer.parseInt(strings[i]));
-        }
+        String csv = testArgs.getString("brokenByteIndicesCsv");
+        Log.d(TAG, "brokenByteIndicesCsv: " + csv);
 
-        // Expect the read to succeed or fail per the prior.
-        try (var file = new RandomAccessFile(filePath, "r")) {
-            long total_blocks = (file.length() + BLOCK_SIZE - 1) / BLOCK_SIZE;
-            for (int i = 0; i < (int) total_blocks; i++) {
-                file.seek(i * BLOCK_SIZE);
-                if (corrupted.contains(i)) {
-                    Log.d(TAG, "Expecting read at block #" + i + " to fail");
+        // Build the set of pages that contain a corrupted byte.
+        final long pageSize = getPageSize();
+        Set<Long> corruptedPageIndices = new HashSet();
+        for (String s : csv.split(",")) {
+            long byteIndex = Long.parseLong(s);
+            long pageIndex = byteIndex / pageSize;
+            corruptedPageIndices.add(pageIndex);
+        }
+        Log.d(TAG, "corruptedPageIndices=" + corruptedPageIndices);
+
+        // Read bytes from the file and verify the expected result based on the containing page.
+        // (The kernel reports fs-verity errors at page granularity.)
+        final long stride = 1024;
+        // Using a stride that is a divisor of the page size ensures that the last page is tested.
+        assertThat(pageSize % stride).isEqualTo(0);
+        try (RandomAccessFile file = new RandomAccessFile(filePath, "r")) {
+            for (long byteIndex = 0; byteIndex < file.length(); byteIndex += stride) {
+                file.seek(byteIndex);
+                long pageIndex = byteIndex / pageSize;
+                if (corruptedPageIndices.contains(pageIndex)) {
+                    Log.d(TAG, "Expecting read at byte #" + byteIndex + " to fail");
                     assertThrows(IOException.class, () -> file.read());
                 } else {
+                    Log.d(TAG, "Expecting read at byte #" + byteIndex + " to succeed");
                     assertThat(file.readByte()).isEqualTo('1');
                 }
             }
diff --git a/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java b/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java
index 1b02792..88d9e9e 100644
--- a/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java
+++ b/tests/FsVerityTest/src/com/android/fsverity/FsVerityHostTest.java
@@ -18,11 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
-import android.platform.test.annotations.RequiresFlagsEnabled;
 import android.platform.test.annotations.RootPermissionTest;
-import android.platform.test.flag.junit.CheckFlagsRule;
-import android.platform.test.flag.junit.host.HostFlagsValueProvider;
-import android.security.Flags;
 
 import com.android.blockdevicewriter.BlockDeviceWriter;
 import com.android.tradefed.device.DeviceNotAvailableException;
@@ -31,33 +27,26 @@
 import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
 import com.android.tradefed.testtype.junit4.DeviceTestRunOptions;
 
-import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 /**
  * This test verifies fs-verity works end-to-end. There is a corresponding helper app.
  *
- * <p>The helper app uses a FileIntegrityManager API to enable fs-verity to a file. The host test
- * here * tampers with the file's backing storage, then tells the helper app to read and expect
+ * <p>The helper app uses a FileIntegrityManager API to enable fs-verity on a file. The host test
+ * here tampers with the file's backing storage, then tells the helper app to read and expect
  * success/failure on read.
  *
- * <p>In order to make sure a block of the file is readable only if the underlying block on disk
- * stay intact, the test needs to bypass the filesystem and tampers with the corresponding physical
- * address against the block device.
+ * <p>Since the filesystem by design provides no way to corrupt fs-verity files itself, the test
+ * needs to bypass the filesystem and write directly to the block device to corrupt the files.
  */
 @RootPermissionTest
 @RunWith(DeviceJUnit4ClassRunner.class)
-@RequiresFlagsEnabled(Flags.FLAG_FSVERITY_API)
 public class FsVerityHostTest extends BaseHostJUnit4Test {
     private static final String TARGET_PACKAGE = "com.android.fsverity";
 
     private static final String BASENAME = "test.file";
 
-    @Rule
-    public final CheckFlagsRule mCheckFlagsRule =
-            HostFlagsValueProvider.createCheckFlagsRule(this::getDevice);
-
     @Test
     public void testFsVeritySmallFile() throws Exception {
         prepareTest(10000);
@@ -67,7 +56,7 @@
         BlockDeviceWriter.damageFileAgainstBlockDevice(device, getTargetFilePath(), 8192);
         BlockDeviceWriter.dropCaches(device);
 
-        verifyRead(getTargetFilePath(), "0,2");
+        verifyRead(getTargetFilePath(), "0,8192");
     }
 
     @Test
@@ -80,7 +69,7 @@
         BlockDeviceWriter.damageFileAgainstBlockDevice(device, getTargetFilePath(), 128 * 4096 + 1);
         BlockDeviceWriter.dropCaches(device);
 
-        verifyRead(getTargetFilePath(), "1,100,128");
+        verifyRead(getTargetFilePath(), "4096,409600,524289");
     }
 
     private String getTargetFilePath() throws DeviceNotAvailableException {
@@ -97,11 +86,17 @@
         assertThat(runDeviceTests(options)).isTrue();
     }
 
+    /**
+     * Verifies the read success/failure expectation given the corrupted byte indices in the file.
+     *
+     * @param path the remote file path to read.
+     * @param indicesCsv a comma-separated list of indices of bytes that were corrupted.
+     */
     private void verifyRead(String path, String indicesCsv) throws Exception {
         DeviceTestRunOptions options = new DeviceTestRunOptions(TARGET_PACKAGE);
         options.setTestClassName(TARGET_PACKAGE + ".Helper");
         options.setTestMethodName("verifyFileRead");
-        options.addInstrumentationArg("brokenBlockIndicesCsv", indicesCsv);
+        options.addInstrumentationArg("brokenByteIndicesCsv", indicesCsv);
         options.addInstrumentationArg("filePath", getTargetFilePath());
         assertThat(runDeviceTests(options)).isTrue();
     }
diff --git a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
index 0c3c7e2..e868a6c 100644
--- a/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
+++ b/tests/TrustTests/src/android/trust/test/GrantAndRevokeTrustTest.kt
@@ -34,7 +34,7 @@
 import org.junit.Test
 import org.junit.rules.RuleChain
 import org.junit.runner.RunWith
-import org.mockito.Mockito.verifyZeroInteractions
+import org.mockito.Mockito.verifyNoMoreInteractions
 
 /**
  * Test for testing revokeTrust & grantTrust for non-renewable trust.
@@ -120,7 +120,7 @@
         trustAgentRule.agent.grantTrust(GRANT_MESSAGE, 0, 0, callback)
         await()
 
-        verifyZeroInteractions(callback)
+        verifyNoMoreInteractions(callback)
     }
 
     companion object {
diff --git a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
index d9bb7db..5419d94 100644
--- a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
+++ b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
@@ -110,7 +110,7 @@
         blockingCallSpeak("foo bar", delegate);
         ArgumentCaptor<SynthesisRequest> req = ArgumentCaptor.forClass(SynthesisRequest.class);
         Mockito.verify(delegate, Mockito.times(1)).onSynthesizeText(req.capture(),
-                Mockito.<SynthesisCallback>anyObject());
+                Mockito.<SynthesisCallback>any());
 
         assertEquals("eng", req.getValue().getLanguage());
         assertEquals("USA", req.getValue().getCountry());
@@ -133,7 +133,7 @@
         blockingCallSpeak("le fou barre", delegate);
         ArgumentCaptor<SynthesisRequest> req2 = ArgumentCaptor.forClass(SynthesisRequest.class);
         Mockito.verify(delegate, Mockito.times(1)).onSynthesizeText(req2.capture(),
-                        Mockito.<SynthesisCallback>anyObject());
+                        Mockito.<SynthesisCallback>any());
 
         // The params are basically unchanged.
         assertEquals("eng", req2.getValue().getLanguage());
@@ -177,7 +177,7 @@
         blockingCallSpeak("foo bar", delegate);
         ArgumentCaptor<SynthesisRequest> req = ArgumentCaptor.forClass(SynthesisRequest.class);
         Mockito.verify(delegate, Mockito.times(1)).onSynthesizeText(req.capture(),
-                Mockito.<SynthesisCallback>anyObject());
+                Mockito.<SynthesisCallback>any());
 
         assertEquals(defaultLocale.getISO3Language(), req.getValue().getLanguage());
         assertEquals(defaultLocale.getISO3Country(), req.getValue().getCountry());
@@ -189,8 +189,8 @@
     private void blockingCallSpeak(String speech, IDelegate mock) throws
             InterruptedException {
         final CountDownLatch latch = new CountDownLatch(1);
-        doCountDown(latch).when(mock).onSynthesizeText(Mockito.<SynthesisRequest>anyObject(),
-                Mockito.<SynthesisCallback>anyObject());
+        doCountDown(latch).when(mock).onSynthesizeText(Mockito.<SynthesisRequest>any(),
+                Mockito.<SynthesisCallback>any());
         mTts.speak(speech, TextToSpeech.QUEUE_ADD, null);
 
         awaitCountDown(latch, 5, TimeUnit.SECONDS);
diff --git a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
index f5d4b0c..cc7eebc 100644
--- a/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
+++ b/tests/UsbTests/src/com/android/server/usb/UsbServiceTest.java
@@ -33,7 +33,7 @@
 import static org.mockito.Mockito.clearInvocations;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.when;
 
 import android.content.Context;
@@ -120,7 +120,7 @@
 
         verify(mUsbPortManager).enableUsbData(TEST_PORT_ID,
                 enable, TEST_TRANSACTION_ID, mCallback, null);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
 
         clearInvocations(mUsbPortManager);
         clearInvocations(mCallback);
@@ -131,7 +131,7 @@
         assertFalse(mUsbService.enableUsbDataInternal(TEST_PORT_ID, enable,
                 TEST_TRANSACTION_ID, mCallback, requester, isInternalRequest));
 
-        verifyZeroInteractions(mUsbPortManager);
+        verifyNoMoreInteractions(mUsbPortManager);
         verify(mCallback).onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
 
         clearInvocations(mUsbPortManager);
@@ -188,7 +188,7 @@
         mUsbService.enableUsbDataWhileDockedInternal(TEST_PORT_ID, TEST_TRANSACTION_ID,
                 mCallback, TEST_SECOND_CALLER_ID, false);
 
-        verifyZeroInteractions(mUsbPortManager);
+        verifyNoMoreInteractions(mUsbPortManager);
         verify(mCallback).onOperationComplete(USB_OPERATION_ERROR_INTERNAL);
     }
 
@@ -203,7 +203,7 @@
 
         verify(mUsbPortManager).enableUsbDataWhileDocked(TEST_PORT_ID, TEST_TRANSACTION_ID,
                         mCallback, null);
-        verifyZeroInteractions(mCallback);
+        verifyNoMoreInteractions(mCallback);
     }
 
     /**
diff --git a/tests/vcn/Android.bp b/tests/vcn/Android.bp
index 5ad1d1dc..205fdb1 100644
--- a/tests/vcn/Android.bp
+++ b/tests/vcn/Android.bp
@@ -17,9 +17,7 @@
     // For access hidden connectivity methods in tests
     defaults: ["framework-connectivity-test-defaults"],
 
-    // Tethering module is released in R so this test needs to be installable
-    // on R
-    min_sdk_version: "30",
+    min_sdk_version: "36",
 
     srcs: [
         "java/**/*.java",
diff --git a/tests/vcn/AndroidManifest.xml b/tests/vcn/AndroidManifest.xml
index 6e8b4ac..c940eef 100644
--- a/tests/vcn/AndroidManifest.xml
+++ b/tests/vcn/AndroidManifest.xml
@@ -16,8 +16,8 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.android.frameworks.tests.vcn">
-    <!-- TODO: b/374174952 Use 36 after Android B finalization -->
-    <uses-sdk android:minSdkVersion="30" android:targetSdkVersion="35" />
+
+    <uses-sdk android:minSdkVersion="36" android:targetSdkVersion="36" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/tests/vcn/AndroidTest.xml b/tests/vcn/AndroidTest.xml
index 9c8362f..ffb79ad 100644
--- a/tests/vcn/AndroidTest.xml
+++ b/tests/vcn/AndroidTest.xml
@@ -27,6 +27,8 @@
             class="com.android.tradefed.testtype.suite.module.MainlineTestModuleController">
         <option name="mainline-module-package-name" value="com.google.android.tethering" />
     </object>
+    <object type="module_controller"
+            class="com.android.tradefed.testtype.suite.module.Sdk36ModuleController" />
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="com.android.frameworks.tests.vcn" />
diff --git a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
index 0fa11ae..95205f4 100644
--- a/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnCellUnderlyingNetworkTemplateTest.java
@@ -23,12 +23,8 @@
 import static org.junit.Assert.assertNotEquals;
 import static org.junit.Assert.fail;
 
-import android.os.Build;
-
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -36,10 +32,7 @@
 import java.util.HashSet;
 import java.util.Set;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnCellUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
     private static final Set<String> ALLOWED_PLMN_IDS = new HashSet<>();
diff --git a/tests/vcn/java/android/net/vcn/VcnConfigTest.java b/tests/vcn/java/android/net/vcn/VcnConfigTest.java
index fa97de0..73a0a61 100644
--- a/tests/vcn/java/android/net/vcn/VcnConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnConfigTest.java
@@ -29,14 +29,11 @@
 
 import android.annotation.NonNull;
 import android.content.Context;
-import android.os.Build;
 import android.os.Parcel;
 import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -45,10 +42,7 @@
 import java.util.Collections;
 import java.util.Set;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnConfigTest {
     private static final String TEST_PACKAGE_NAME = VcnConfigTest.class.getPackage().getName();
diff --git a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
index 990cc74..59dc689 100644
--- a/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnGatewayConnectionConfigTest.java
@@ -34,13 +34,10 @@
 import android.net.ipsec.ike.IkeTunnelConnectionParams;
 import android.net.vcn.persistablebundleutils.IkeSessionParamsUtilsTest;
 import android.net.vcn.persistablebundleutils.TunnelConnectionParamsUtilsTest;
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -52,10 +49,7 @@
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnGatewayConnectionConfigTest {
     // Public for use in VcnGatewayConnectionTest
diff --git a/tests/vcn/java/android/net/vcn/VcnManagerTest.java b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
index 1739fbc..ecb177e 100644
--- a/tests/vcn/java/android/net/vcn/VcnManagerTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnManagerTest.java
@@ -38,13 +38,10 @@
 import android.net.vcn.VcnManager.VcnStatusCallback;
 import android.net.vcn.VcnManager.VcnStatusCallbackBinder;
 import android.net.vcn.VcnManager.VcnUnderlyingNetworkPolicyListener;
-import android.os.Build;
 import android.os.ParcelUuid;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -55,10 +52,7 @@
 import java.util.UUID;
 import java.util.concurrent.Executor;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnManagerTest {
     private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
diff --git a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
index 52952eb..1d57cf2 100644
--- a/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnTransportInfoTest.java
@@ -30,23 +30,17 @@
 import android.net.NetworkCapabilities;
 import android.net.wifi.WifiConfiguration;
 import android.net.wifi.WifiInfo;
-import android.os.Build;
 import android.os.Parcel;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.Arrays;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnTransportInfoTest {
     private static final int SUB_ID = 1;
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
index c82d200..891298a 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkPolicyTest.java
@@ -22,20 +22,14 @@
 import static org.junit.Assert.assertNotEquals;
 
 import android.net.NetworkCapabilities;
-import android.os.Build;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnUnderlyingNetworkPolicyTest {
     private static final VcnUnderlyingNetworkPolicy DEFAULT_NETWORK_POLICY =
diff --git a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
index 22361cc..2110d6e 100644
--- a/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUnderlyingNetworkSpecifierTest.java
@@ -22,20 +22,14 @@
 import static org.junit.Assert.assertTrue;
 
 import android.net.TelephonyNetworkSpecifier;
-import android.os.Build;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnUnderlyingNetworkSpecifierTest {
     private static final int[] TEST_SUB_IDS = new int[] {1, 2, 3, 5};
diff --git a/tests/vcn/java/android/net/vcn/VcnUtilsTest.java b/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
index fb040d8..0c3f9fe 100644
--- a/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnUtilsTest.java
@@ -30,12 +30,9 @@
 import android.net.NetworkCapabilities;
 import android.net.TelephonyNetworkSpecifier;
 import android.net.wifi.WifiInfo;
-import android.os.Build;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -44,10 +41,7 @@
 import java.util.Arrays;
 import java.util.Collections;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnUtilsTest {
     private static final int SUB_ID = 1;
diff --git a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
index 2c072e1..dbbfd83 100644
--- a/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
+++ b/tests/vcn/java/android/net/vcn/VcnWifiUnderlyingNetworkTemplateTest.java
@@ -22,22 +22,15 @@
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
-import android.os.Build;
-
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.util.Set;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnWifiUnderlyingNetworkTemplateTest extends VcnUnderlyingNetworkTemplateTestBase {
     private static final String SSID = "TestWifi";
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
index 01e9ac2..bc8e9d3 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/EapSessionConfigUtilsTest.java
@@ -21,14 +21,11 @@
 import static org.junit.Assert.assertEquals;
 
 import android.net.eap.EapSessionConfig;
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,10 +35,7 @@
 import java.security.cert.CertificateFactory;
 import java.security.cert.X509Certificate;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class EapSessionConfigUtilsTest {
     private static final byte[] EAP_ID = "test@android.net".getBytes(StandardCharsets.US_ASCII);
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
index 821e5a6..4f3930f 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeIdentificationUtilsTest.java
@@ -25,13 +25,10 @@
 import android.net.ipsec.ike.IkeIpv6AddrIdentification;
 import android.net.ipsec.ike.IkeKeyIdIdentification;
 import android.net.ipsec.ike.IkeRfc822AddrIdentification;
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -42,10 +39,7 @@
 
 import javax.security.auth.x500.X500Principal;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IkeIdentificationUtilsTest {
     private static void verifyPersistableBundleEncodeDecodeIsLossless(IkeIdentification id) {
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
index 7200aee..9f7d239 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeSessionParamsUtilsTest.java
@@ -29,16 +29,14 @@
 import android.net.eap.EapSessionConfig;
 import android.net.ipsec.ike.IkeFqdnIdentification;
 import android.net.ipsec.ike.IkeSessionParams;
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.InstrumentationRegistry;
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.internal.org.bouncycastle.util.io.pem.PemObject;
 import com.android.internal.org.bouncycastle.util.io.pem.PemReader;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -54,10 +52,7 @@
 import java.security.interfaces.RSAPrivateKey;
 import java.util.concurrent.TimeUnit;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IkeSessionParamsUtilsTest {
     // Public for use in VcnGatewayConnectionConfigTest, EncryptedTunnelParamsUtilsTest
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
index 957e785d..28cf38a 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/IkeTrafficSelectorUtilsTest.java
@@ -20,23 +20,17 @@
 
 import android.net.InetAddresses;
 import android.net.ipsec.ike.IkeTrafficSelector;
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
 import java.net.InetAddress;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IkeTrafficSelectorUtilsTest {
     private static final int START_PORT = 16;
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
index 1e8f5ff..664044a 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/SaProposalUtilsTest.java
@@ -21,21 +21,15 @@
 import android.net.ipsec.ike.ChildSaProposal;
 import android.net.ipsec.ike.IkeSaProposal;
 import android.net.ipsec.ike.SaProposal;
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class SaProposalUtilsTest {
     /** Package private so that IkeSessionParamsUtilsTest can use it */
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
index 7d17724..f9dc9eb 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelConnectionParamsUtilsTest.java
@@ -20,20 +20,14 @@
 
 import android.net.ipsec.ike.IkeSessionParams;
 import android.net.ipsec.ike.IkeTunnelConnectionParams;
-import android.os.Build;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class TunnelConnectionParamsUtilsTest {
     // Public for use in VcnGatewayConnectionConfigTest
diff --git a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
index 3d7348a..e0b5f0e 100644
--- a/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/persistablebundleutils/TunnelModeChildSessionParamsUtilsTest.java
@@ -25,13 +25,10 @@
 import android.net.ipsec.ike.ChildSaProposal;
 import android.net.ipsec.ike.IkeTrafficSelector;
 import android.net.ipsec.ike.TunnelModeChildSessionParams;
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -40,10 +37,7 @@
 import java.net.Inet6Address;
 import java.util.concurrent.TimeUnit;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class TunnelModeChildSessionParamsUtilsTest {
     // Package private for use in EncryptedTunnelParamsUtilsTest
diff --git a/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java b/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
index 99c7aa7..47638b0 100644
--- a/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/util/MtuUtilsTest.java
@@ -33,12 +33,9 @@
 import static java.util.Collections.emptyList;
 
 import android.net.ipsec.ike.ChildSaProposal;
-import android.os.Build;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -46,10 +43,7 @@
 import java.util.Arrays;
 import java.util.List;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class MtuUtilsTest {
     private void verifyUnderlyingMtuZero(boolean isIpv4) {
diff --git a/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java b/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
index f7786af..c84e600 100644
--- a/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
+++ b/tests/vcn/java/android/net/vcn/util/PersistableBundleUtilsTest.java
@@ -21,13 +21,10 @@
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -38,10 +35,7 @@
 import java.util.List;
 import java.util.Objects;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class PersistableBundleUtilsTest {
     private static final String TEST_KEY = "testKey";
diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
index 3cccbc4..02400ea 100644
--- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
+++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java
@@ -95,6 +95,7 @@
 import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.VcnManagementService.VcnCallback;
 import com.android.server.VcnManagementService.VcnStatusCallbackInfo;
@@ -102,8 +103,6 @@
 import com.android.server.vcn.Vcn;
 import com.android.server.vcn.VcnContext;
 import com.android.server.vcn.VcnNetworkProvider;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Rule;
@@ -120,10 +119,7 @@
 import java.util.Set;
 import java.util.UUID;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnManagementServiceTest {
     @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
index 6276be2..6a4a1bd 100644
--- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java
@@ -54,7 +54,6 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.net.vcn.VcnManager;
-import android.os.Build;
 import android.os.Handler;
 import android.os.ParcelUuid;
 import android.os.PersistableBundle;
@@ -70,10 +69,9 @@
 import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.modules.utils.HandlerExecutor;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -89,10 +87,7 @@
 import java.util.Set;
 import java.util.UUID;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class TelephonySubscriptionTrackerTest {
     private static final String PACKAGE_NAME =
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
index a349080..bf0c46c 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectedStateTest.java
@@ -70,18 +70,16 @@
 import android.net.vcn.VcnManager.VcnErrorCode;
 import android.net.vcn.VcnTransportInfo;
 import android.net.vcn.util.MtuUtils;
-import android.os.Build;
 import android.os.PersistableBundle;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionCallback;
 import com.android.server.vcn.VcnGatewayConnection.VcnChildSessionConfiguration;
 import com.android.server.vcn.VcnGatewayConnection.VcnIkeSession;
 import com.android.server.vcn.VcnGatewayConnection.VcnNetworkAgent;
 import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -96,10 +94,7 @@
 import java.util.List;
 import java.util.function.Consumer;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnGatewayConnectionConnectedStateTest extends VcnGatewayConnectionTestBase {
     private static final int PARALLEL_SA_COUNT = 4;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
index e1a572e..c946680 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionConnectingStateTest.java
@@ -26,22 +26,16 @@
 import static org.mockito.Mockito.verify;
 
 import android.net.ipsec.ike.IkeSessionParams;
-import android.os.Build;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentCaptor;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnGatewayConnectionConnectingStateTest extends VcnGatewayConnectionTestBase {
     private VcnIkeSession mIkeSession;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
index 7cfaf5b..0b470b9 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectedStateTest.java
@@ -30,21 +30,15 @@
 import static org.mockito.Mockito.verify;
 
 import android.net.IpSecManager;
-import android.os.Build;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnGatewayConnectionDisconnectedStateTest extends VcnGatewayConnectionTestBase {
     @Before
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
index 9132d83..bfcc4ca 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionDisconnectingStateTest.java
@@ -23,21 +23,14 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
-import android.os.Build;
-
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnGatewayConnectionDisconnectingStateTest extends VcnGatewayConnectionTestBase {
     @Before
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
index d5ef4e0..e6fe509 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionRetryTimeoutStateTest.java
@@ -27,21 +27,14 @@
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 
-import android.os.Build;
-
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnGatewayConnectionRetryTimeoutStateTest extends VcnGatewayConnectionTestBase {
     private long mFirstRetryInterval;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
index 5283322..2a2d5ba 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnGatewayConnectionTest.java
@@ -61,17 +61,15 @@
 import android.net.vcn.VcnManager;
 import android.net.vcn.VcnTransportInfo;
 import android.net.wifi.WifiInfo;
-import android.os.Build;
 import android.os.ParcelUuid;
 import android.os.Process;
 import android.telephony.SubscriptionInfo;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import com.android.server.vcn.routeselection.UnderlyingNetworkRecord;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -89,10 +87,7 @@
 import java.util.concurrent.Executor;
 import java.util.concurrent.TimeUnit;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnGatewayConnectionTest extends VcnGatewayConnectionTestBase {
     private static final int TEST_UID = Process.myUid() + 1;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
index 0185931..4f705d6 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnNetworkProviderTest.java
@@ -29,14 +29,12 @@
 import android.content.Context;
 import android.net.ConnectivityManager;
 import android.net.NetworkRequest;
-import android.os.Build;
 import android.os.test.TestLooper;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -46,10 +44,7 @@
 import java.util.ArrayList;
 import java.util.List;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnNetworkProviderTest {
     private static final int TEST_SCORE_UNSATISFIED = 0;
diff --git a/tests/vcn/java/com/android/server/vcn/VcnTest.java b/tests/vcn/java/com/android/server/vcn/VcnTest.java
index c12adcb..1853b6b 100644
--- a/tests/vcn/java/com/android/server/vcn/VcnTest.java
+++ b/tests/vcn/java/com/android/server/vcn/VcnTest.java
@@ -49,7 +49,6 @@
 import android.net.vcn.VcnConfig;
 import android.net.vcn.VcnGatewayConnectionConfig;
 import android.net.vcn.VcnGatewayConnectionConfigTest;
-import android.os.Build;
 import android.os.ParcelUuid;
 import android.os.test.TestLooper;
 import android.provider.Settings;
@@ -57,14 +56,13 @@
 import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.VcnManagementService.VcnCallback;
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import com.android.server.vcn.Vcn.VcnGatewayStatusCallback;
 import com.android.server.vcn.Vcn.VcnUserMobileDataStateListener;
 import com.android.server.vcn.VcnNetworkProvider.NetworkRequestListener;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -79,10 +77,7 @@
 import java.util.Set;
 import java.util.UUID;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class VcnTest {
     private static final String PKG_NAME = VcnTest.class.getPackage().getName();
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
index 53a36d3..224b45c 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/IpSecPacketLossDetectorTest.java
@@ -44,18 +44,16 @@
 import android.content.BroadcastReceiver;
 import android.content.Intent;
 import android.net.IpSecTransformState;
-import android.os.Build;
 import android.os.OutcomeReceiver;
 import android.os.PowerManager;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculationResult;
 import com.android.server.vcn.routeselection.IpSecPacketLossDetector.PacketLossCalculator;
 import com.android.server.vcn.routeselection.NetworkMetricMonitor.IpSecTransformWrapper;
 import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -69,10 +67,7 @@
 import java.util.BitSet;
 import java.util.concurrent.TimeUnit;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class IpSecPacketLossDetectorTest extends NetworkEvaluationTestBase {
     private static final String TAG = IpSecPacketLossDetectorTest.class.getSimpleName();
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
index a9c637f..16dbab9 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/NetworkPriorityClassifierTest.java
@@ -42,14 +42,11 @@
 import android.net.vcn.VcnManager;
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
 import android.net.vcn.VcnWifiUnderlyingNetworkTemplate;
-import android.os.Build;
 import android.os.PersistableBundle;
 import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
-
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
+import androidx.test.runner.AndroidJUnit4;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -59,10 +56,7 @@
 import java.util.List;
 import java.util.Set;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class NetworkPriorityClassifierTest extends NetworkEvaluationTestBase {
     private UnderlyingNetworkRecord mWifiNetworkRecord;
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
index 99c508c..b67a2fd 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkControllerTest.java
@@ -58,7 +58,6 @@
 import android.net.vcn.VcnCellUnderlyingNetworkTemplateTest;
 import android.net.vcn.VcnGatewayConnectionConfigTest;
 import android.net.vcn.VcnUnderlyingNetworkTemplate;
-import android.os.Build;
 import android.os.ParcelUuid;
 import android.os.test.TestLooper;
 import android.telephony.CarrierConfigManager;
@@ -67,6 +66,7 @@
 import android.util.ArraySet;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.vcn.TelephonySubscriptionTracker.TelephonySubscriptionSnapshot;
 import com.android.server.vcn.VcnContext;
@@ -76,8 +76,6 @@
 import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkControllerCallback;
 import com.android.server.vcn.routeselection.UnderlyingNetworkController.UnderlyingNetworkListener;
 import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -95,10 +93,7 @@
 import java.util.Set;
 import java.util.UUID;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class UnderlyingNetworkControllerTest {
     private static final ParcelUuid SUB_GROUP = new ParcelUuid(new UUID(0, 0));
diff --git a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
index 3ca84cf..850f9aa 100644
--- a/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
+++ b/tests/vcn/java/com/android/server/vcn/routeselection/UnderlyingNetworkEvaluatorTest.java
@@ -37,15 +37,13 @@
 
 import android.net.IpSecTransform;
 import android.net.vcn.VcnGatewayConnectionConfig;
-import android.os.Build;
 
 import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
 
 import com.android.server.vcn.routeselection.NetworkMetricMonitor.NetworkMetricMonitorCallback;
 import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.Dependencies;
 import com.android.server.vcn.routeselection.UnderlyingNetworkEvaluator.NetworkEvaluatorCallback;
-import com.android.testutils.DevSdkIgnoreRule;
-import com.android.testutils.DevSdkIgnoreRunner;
 
 import org.junit.Before;
 import org.junit.Test;
@@ -56,10 +54,7 @@
 
 import java.util.concurrent.TimeUnit;
 
-// TODO: b/374174952 After B finalization, use Sdk36ModuleController to ensure VCN tests only run on
-// Android B/B+
-@RunWith(DevSdkIgnoreRunner.class)
-@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.VANILLA_ICE_CREAM)
+@RunWith(AndroidJUnit4.class)
 @SmallTest
 public class UnderlyingNetworkEvaluatorTest extends NetworkEvaluationTestBase {
     private static final int PENALTY_TIMEOUT_MIN = 10;