Merge "Improve metrics logic" into main
diff --git a/core/java/android/app/ActivityTaskManager.java b/core/java/android/app/ActivityTaskManager.java
index be8f48d..c8ab260 100644
--- a/core/java/android/app/ActivityTaskManager.java
+++ b/core/java/android/app/ActivityTaskManager.java
@@ -90,13 +90,6 @@
     public static final int RESIZE_MODE_USER = RESIZE_MODE_PRESERVE_WINDOW;
 
     /**
-     * Input parameter to {@link IActivityTaskManager#resizeTask} used by window
-     * manager during a screen rotation.
-     * @hide
-     */
-    public static final int RESIZE_MODE_SYSTEM_SCREEN_ROTATION = RESIZE_MODE_PRESERVE_WINDOW;
-
-    /**
      * Input parameter to {@link IActivityTaskManager#resizeTask} which indicates
      * that the resize should be performed even if the bounds appears unchanged.
      * @hide
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c3bac71..3c402ca 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -6593,12 +6593,7 @@
          * @hide
          */
         public RemoteViews createCompactHeadsUpContentView() {
-            // TODO(b/336225281): re-evaluate custom view usage.
-            if (useExistingRemoteView(mN.headsUpContentView)) {
-                return fullyCustomViewRequiresDecoration(false /* fromStyle */)
-                        ? minimallyDecoratedHeadsUpContentView(mN.headsUpContentView)
-                        : mN.headsUpContentView;
-            } else if (mStyle != null) {
+            if (mStyle != null) {
                 final RemoteViews styleView = mStyle.makeCompactHeadsUpContentView();
                 if (styleView != null) {
                     return styleView;
@@ -6611,7 +6606,7 @@
             // Notification text is shown as secondary header text
             // for the minimal hun when it is provided.
             // Time(when and chronometer) is not shown for the minimal hun.
-            p.headerTextSecondary(p.mText).text(null).hideTime(true);
+            p.headerTextSecondary(p.mText).text(null).hideTime(true).summaryText("");
 
             return applyStandardTemplate(
                     getCompactHeadsUpBaseLayoutResource(), p,
diff --git a/core/java/android/content/pm/multiuser.aconfig b/core/java/android/content/pm/multiuser.aconfig
index cd1913b..83742eb 100644
--- a/core/java/android/content/pm/multiuser.aconfig
+++ b/core/java/android/content/pm/multiuser.aconfig
@@ -240,3 +240,10 @@
     description: "Add entrypoint in Settings Reset options for deleting private space when lock is forgotten"
     bug: "329601751"
 }
+
+flag {
+    name: "allow_main_user_to_access_blocked_number_provider"
+    namespace: "multiuser"
+    description: "Allow MAIN user to access blocked number provider"
+    bug: "338579331"
+}
diff --git a/core/java/android/view/ImeBackAnimationController.java b/core/java/android/view/ImeBackAnimationController.java
index 4530157..9503f49 100644
--- a/core/java/android/view/ImeBackAnimationController.java
+++ b/core/java/android/view/ImeBackAnimationController.java
@@ -38,6 +38,8 @@
 
 import com.android.internal.inputmethod.SoftInputShowHideReason;
 
+import java.io.PrintWriter;
+
 /**
  * Controller for IME predictive back animation
  *
@@ -271,4 +273,24 @@
         return mPostCommitAnimator != null && mTriggerBack;
     }
 
+    /**
+     * Dump information about this ImeBackAnimationController
+     *
+     * @param prefix the prefix that will be prepended to each line of the produced output
+     * @param writer the writer that will receive the resulting text
+     */
+    public void dump(String prefix, PrintWriter writer) {
+        final String innerPrefix = prefix + "    ";
+        writer.println(prefix + "ImeBackAnimationController:");
+        writer.println(innerPrefix + "mLastProgress=" + mLastProgress);
+        writer.println(innerPrefix + "mTriggerBack=" + mTriggerBack);
+        writer.println(innerPrefix + "mIsPreCommitAnimationInProgress="
+                + mIsPreCommitAnimationInProgress);
+        writer.println(innerPrefix + "mStartRootScrollY=" + mStartRootScrollY);
+        writer.println(innerPrefix + "isBackAnimationAllowed=" + isBackAnimationAllowed());
+        writer.println(innerPrefix + "isAdjustPan=" + isAdjustPan());
+        writer.println(innerPrefix + "isHideAnimationInProgress="
+                + isHideAnimationInProgress());
+    }
+
 }
diff --git a/core/java/android/view/InsetsController.java b/core/java/android/view/InsetsController.java
index c545267..f1cb410 100644
--- a/core/java/android/view/InsetsController.java
+++ b/core/java/android/view/InsetsController.java
@@ -1799,8 +1799,11 @@
     }
 
     void dump(String prefix, PrintWriter pw) {
-        pw.print(prefix); pw.println("InsetsController:");
-        mState.dump(prefix + "  ", pw);
+        final String innerPrefix = prefix + "    ";
+        pw.println(prefix + "InsetsController:");
+        mState.dump(innerPrefix, pw);
+        pw.println(innerPrefix + "mIsPredictiveBackImeHideAnimInProgress="
+                + mIsPredictiveBackImeHideAnimInProgress);
     }
 
     void dumpDebug(ProtoOutputStream proto, long fieldId) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index db55a9d..fdf3cb1 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -5300,10 +5300,12 @@
         if (DEBUG_CONTENT_CAPTURE) {
             Log.v(mTag, "performContentCaptureInitialReport() on " + rootView);
         }
+        boolean traceDispatchCapture = false;
         try {
             if (!isContentCaptureEnabled()) return;
 
-            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+            traceDispatchCapture = Trace.isTagEnabled(Trace.TRACE_TAG_VIEW);
+            if (traceDispatchCapture) {
                 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "dispatchContentCapture() for "
                         + getClass().getSimpleName());
             }
@@ -5319,7 +5321,9 @@
             // Content capture is a go!
             rootView.dispatchInitialProvideContentCaptureStructure();
         } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+            if (traceDispatchCapture) {
+                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+            }
         }
     }
 
@@ -5327,10 +5331,12 @@
         if (DEBUG_CONTENT_CAPTURE) {
             Log.v(mTag, "handleContentCaptureFlush()");
         }
+        boolean traceFlushContentCapture = false;
         try {
             if (!isContentCaptureEnabled()) return;
 
-            if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+            traceFlushContentCapture = Trace.isTagEnabled(Trace.TRACE_TAG_VIEW);
+            if (traceFlushContentCapture) {
                 Trace.traceBegin(Trace.TRACE_TAG_VIEW, "flushContentCapture for "
                         + getClass().getSimpleName());
             }
@@ -5342,7 +5348,9 @@
             }
             ccm.flush(ContentCaptureSession.FLUSH_REASON_VIEW_ROOT_ENTERED);
         } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+            if (traceFlushContentCapture) {
+                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+            }
         }
     }
 
@@ -9601,6 +9609,8 @@
 
         mOnBackInvokedDispatcher.dump(prefix, writer);
 
+        mImeBackAnimationController.dump(prefix, writer);
+
         writer.println(prefix + "View Hierarchy:");
         dumpViewHierarchy(innerPrefix, writer, mView);
     }
@@ -12657,10 +12667,12 @@
             view = mFrameRateCategoryView;
         }
 
+        boolean traceFrameRateCategory = false;
         try {
             if (frameRateCategory != FRAME_RATE_CATEGORY_DEFAULT
                     && mLastPreferredFrameRateCategory != frameRateCategory) {
-                if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+                traceFrameRateCategory = Trace.isTagEnabled(Trace.TRACE_TAG_VIEW);
+                if (traceFrameRateCategory) {
                     String reason = reasonToString(frameRateReason);
                     String sourceView = view == null ? "-" : view;
                     String category = categoryToString(frameRateCategory);
@@ -12678,7 +12690,9 @@
         } catch (Exception e) {
             Log.e(mTag, "Unable to set frame rate category", e);
         } finally {
-            Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+            if (traceFrameRateCategory) {
+                Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+            }
         }
     }
 
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5fa13ba..37d39a7 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1346,51 +1346,6 @@
         <attr name="materialColorTertiary" format="color"/>
         <!-- The error color for the app, intended to draw attention to error conditions. @hide -->
         <attr name="materialColorError" format="color"/>
-
-        <!-- System Custom Tokens-->
-        <!-- @hide -->
-        <attr name="customColorWidgetBackground" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorClockHour" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorClockMinute" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorClockSecond" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorThemeApp" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnThemeApp" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorThemeAppRing" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnThemeAppRing" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorBrandA" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorBrandB" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorBrandC" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorBrandD" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorUnderSurface" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorShadeActive" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnShadeActive" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnShadeActiveVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorShadeInactive" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnShadeInactive" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOnShadeInactiveVariant" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorShadeDisabled" format="color"/>
-        <!-- @hide -->
-        <attr name="customColorOverviewBackground" format="color"/>
-
     </declare-styleable>
 
     <!-- **************************************************************** -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 5e039b5..e671919 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -581,51 +581,6 @@
     <color name="system_on_tertiary_fixed">#FFFFFF</color>
     <color name="system_on_tertiary_fixed_variant">#FFFFFF</color>
 
-    <!--Colors used in Android system, from design system. These values can be overlaid at runtime
-     by OverlayManager RROs.-->
-    <color name="system_widget_background_light">#EEF0FF</color>
-    <color name="system_clock_hour_light">#1D2435</color>
-    <color name="system_clock_minute_light">#20386A</color>
-    <color name="system_clock_second_light">#000000</color>
-    <color name="system_theme_app_light">#2F4578</color>
-    <color name="system_on_theme_app_light">#D6DFFF</color>
-    <color name="system_theme_app_ring_light">#94AAE4</color>
-    <color name="system_on_theme_app_ring_light">#FDD7FA</color>
-    <color name="system_brand_a_light">#3A5084</color>
-    <color name="system_brand_b_light">#6E7488</color>
-    <color name="system_brand_c_light">#6076AC</color>
-    <color name="system_brand_d_light">#8C6D8C</color>
-    <color name="system_under_surface_light">#000000</color>
-    <color name="system_shade_active_light">#D9E2FF</color>
-    <color name="system_on_shade_active_light">#152E60</color>
-    <color name="system_on_shade_active_variant_light">#2F4578</color>
-    <color name="system_shade_inactive_light">#2F3036</color>
-    <color name="system_on_shade_inactive_light">#E1E2EC</color>
-    <color name="system_on_shade_inactive_variant_light">#C5C6D0</color>
-    <color name="system_shade_disabled_light">#0C0E13</color>
-    <color name="system_overview_background_light">#50525A</color>
-    <color name="system_widget_background_dark">#152E60</color>
-    <color name="system_clock_hour_dark">#9AA0B6</color>
-    <color name="system_clock_minute_dark">#D8E1FF</color>
-    <color name="system_clock_second_dark">#FFFFFF</color>
-    <color name="system_theme_app_dark">#D9E2FF</color>
-    <color name="system_on_theme_app_dark">#304679</color>
-    <color name="system_theme_app_ring_dark">#94AAE4</color>
-    <color name="system_on_theme_app_ring_dark">#E0BBDD</color>
-    <color name="system_brand_a_dark">#90A6DF</color>
-    <color name="system_brand_b_dark">#A4ABC1</color>
-    <color name="system_brand_c_dark">#7A90C8</color>
-    <color name="system_brand_d_dark">#A886A6</color>
-    <color name="system_under_surface_dark">#000000</color>
-    <color name="system_shade_active_dark">#D9E2FF</color>
-    <color name="system_on_shade_active_dark">#001945</color>
-    <color name="system_on_shade_active_variant_dark">#2F4578</color>
-    <color name="system_shade_inactive_dark">#2F3036</color>
-    <color name="system_on_shade_inactive_dark">#E1E2EC</color>
-    <color name="system_on_shade_inactive_variant_dark">#C5C6D0</color>
-    <color name="system_shade_disabled_dark">#0C0E13</color>
-    <color name="system_overview_background_dark">#C5C6D0</color>
-
     <!-- Accessibility shortcut icon background color -->
     <color name="accessibility_feature_background">#5F6368</color> <!-- Google grey 700 -->
     <color name="accessibility_magnification_background">#F50D60</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 877d11e..edaf8b5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -6093,6 +6093,18 @@
     <!-- Whether displaying letterbox education is enabled for letterboxed fullscreen apps. -->
     <bool name="config_letterboxIsEducationEnabled">false</bool>
 
+    <!-- The width in dp to use to detect vertical thin letterboxing.
+         If W is the available width and w is the letterbox width, an app
+         is thin letterboxed if the value here is < (W - w) / 2
+         If the value is < 0 the thin letterboxing policy is disabled -->
+    <dimen name="config_letterboxThinLetterboxWidthDp">-1dp</dimen>
+
+    <!-- The height in dp to use to detect horizontal thin letterboxing
+         If H is the available height and h is the letterbox height, an app
+         is thin letterboxed if the value here is < (H - h) / 2
+         If the value is < 0 the thin letterboxing policy is disabled -->
+    <dimen name="config_letterboxThinLetterboxHeightDp">-1dp</dimen>
+
     <!-- Default min aspect ratio for unresizable apps which are eligible for size compat mode.
          Values <= 1.0 will be ignored. Activity min/max aspect ratio restrictions will still be
          espected so this override can control the maximum screen area that can be occupied by
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e860f5a..36542ee 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4717,6 +4717,8 @@
   <java-symbol type="integer" name="config_letterboxDefaultPositionForTabletopModeReachability" />
   <java-symbol type="bool" name="config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled" />
   <java-symbol type="bool" name="config_letterboxIsEducationEnabled" />
+  <java-symbol type="dimen" name="config_letterboxThinLetterboxWidthDp" />
+  <java-symbol type="dimen" name="config_letterboxThinLetterboxHeightDp" />
   <java-symbol type="dimen" name="config_letterboxDefaultMinAspectRatioForUnresizableApps" />
   <java-symbol type="bool" name="config_letterboxIsSplitScreenAspectRatioForUnresizableAppsEnabled" />
   <java-symbol type="bool" name="config_letterboxIsDisplayAspectRatioForFixedOrientationLetterboxEnabled" />
@@ -5286,71 +5288,6 @@
   <java-symbol name="materialColorTertiary" type="attr"/>
   <java-symbol name="materialColorError" type="attr"/>
 
-  <java-symbol name="customColorWidgetBackground" type="attr"/>
-  <java-symbol name="customColorClockHour" type="attr"/>
-  <java-symbol name="customColorClockMinute" type="attr"/>
-  <java-symbol name="customColorClockSecond" type="attr"/>
-  <java-symbol name="customColorThemeApp" type="attr"/>
-  <java-symbol name="customColorOnThemeApp" type="attr"/>
-  <java-symbol name="customColorThemeAppRing" type="attr"/>
-  <java-symbol name="customColorOnThemeAppRing" type="attr"/>
-  <java-symbol name="customColorBrandA" type="attr"/>
-  <java-symbol name="customColorBrandB" type="attr"/>
-  <java-symbol name="customColorBrandC" type="attr"/>
-  <java-symbol name="customColorBrandD" type="attr"/>
-  <java-symbol name="customColorUnderSurface" type="attr"/>
-  <java-symbol name="customColorShadeActive" type="attr"/>
-  <java-symbol name="customColorOnShadeActive" type="attr"/>
-  <java-symbol name="customColorOnShadeActiveVariant" type="attr"/>
-  <java-symbol name="customColorShadeInactive" type="attr"/>
-  <java-symbol name="customColorOnShadeInactive" type="attr"/>
-  <java-symbol name="customColorOnShadeInactiveVariant" type="attr"/>
-  <java-symbol name="customColorShadeDisabled" type="attr"/>
-  <java-symbol name="customColorOverviewBackground" type="attr"/>
-
-  <java-symbol name="system_widget_background_light" type="color"/>
-  <java-symbol name="system_clock_hour_light" type="color"/>
-  <java-symbol name="system_clock_minute_light" type="color"/>
-  <java-symbol name="system_clock_second_light" type="color"/>
-  <java-symbol name="system_theme_app_light" type="color"/>
-  <java-symbol name="system_on_theme_app_light" type="color"/>
-  <java-symbol name="system_theme_app_ring_light" type="color"/>
-  <java-symbol name="system_on_theme_app_ring_light" type="color"/>
-  <java-symbol name="system_brand_a_light" type="color"/>
-  <java-symbol name="system_brand_b_light" type="color"/>
-  <java-symbol name="system_brand_c_light" type="color"/>
-  <java-symbol name="system_brand_d_light" type="color"/>
-  <java-symbol name="system_under_surface_light" type="color"/>
-  <java-symbol name="system_shade_active_light" type="color"/>
-  <java-symbol name="system_on_shade_active_light" type="color"/>
-  <java-symbol name="system_on_shade_active_variant_light" type="color"/>
-  <java-symbol name="system_shade_inactive_light" type="color"/>
-  <java-symbol name="system_on_shade_inactive_light" type="color"/>
-  <java-symbol name="system_on_shade_inactive_variant_light" type="color"/>
-  <java-symbol name="system_shade_disabled_light" type="color"/>
-  <java-symbol name="system_overview_background_light" type="color"/>
-  <java-symbol name="system_widget_background_dark" type="color"/>
-  <java-symbol name="system_clock_hour_dark" type="color"/>
-  <java-symbol name="system_clock_minute_dark" type="color"/>
-  <java-symbol name="system_clock_second_dark" type="color"/>
-  <java-symbol name="system_theme_app_dark" type="color"/>
-  <java-symbol name="system_on_theme_app_dark" type="color"/>
-  <java-symbol name="system_theme_app_ring_dark" type="color"/>
-  <java-symbol name="system_on_theme_app_ring_dark" type="color"/>
-  <java-symbol name="system_brand_a_dark" type="color"/>
-  <java-symbol name="system_brand_b_dark" type="color"/>
-  <java-symbol name="system_brand_c_dark" type="color"/>
-  <java-symbol name="system_brand_d_dark" type="color"/>
-  <java-symbol name="system_under_surface_dark" type="color"/>
-  <java-symbol name="system_shade_active_dark" type="color"/>
-  <java-symbol name="system_on_shade_active_dark" type="color"/>
-  <java-symbol name="system_on_shade_active_variant_dark" type="color"/>
-  <java-symbol name="system_shade_inactive_dark" type="color"/>
-  <java-symbol name="system_on_shade_inactive_dark" type="color"/>
-  <java-symbol name="system_on_shade_inactive_variant_dark" type="color"/>
-  <java-symbol name="system_shade_disabled_dark" type="color"/>
-  <java-symbol name="system_overview_background_dark" type="color"/>
-
   <java-symbol type="attr" name="actionModeUndoDrawable" />
   <java-symbol type="attr" name="actionModeRedoDrawable" />
 
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 24d4938..ee19144 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -284,28 +284,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault" parent="Theme.DeviceDefaultBase" />
@@ -402,28 +380,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar.  This theme
@@ -519,28 +475,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with no action bar and no status bar and
@@ -638,28 +572,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} that has no title bar and translucent
@@ -756,28 +668,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for dialog windows and activities. This changes the window to be
@@ -882,28 +772,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} that has a nice minimum width for a
@@ -999,28 +867,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog} without an action bar -->
@@ -1115,28 +961,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Dialog_NoActionBar} that has a nice minimum width
@@ -1232,28 +1056,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -1365,28 +1167,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for a window without an action bar that will be displayed either
@@ -1483,28 +1263,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for a presentation window on a secondary display. -->
@@ -1599,28 +1357,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for panel windows. This removes all extraneous window
@@ -1717,28 +1453,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -1834,28 +1548,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- DeviceDefault theme for windows that want to have the user's selected wallpaper appear
@@ -1951,28 +1643,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -2068,28 +1738,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- DeviceDefault style for input methods, which is used by the
@@ -2185,28 +1833,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.Alert" parent="Theme.Material.Dialog.Alert">
@@ -2302,28 +1928,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Theme for the dialog shown when an app crashes or ANRs. -->
@@ -2424,28 +2028,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.NoFrame" parent="Theme.Material.Dialog.NoFrame">
@@ -2539,28 +2121,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault} with a light-colored style -->
@@ -2792,28 +2352,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of the DeviceDefault (light) theme that has a solid (opaque) action bar with an
@@ -2909,28 +2447,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar -->
@@ -3025,28 +2541,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar.
@@ -3142,28 +2636,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} with no action bar and no status bar
@@ -3261,28 +2733,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light} that has no title bar and translucent
@@ -3379,28 +2829,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
@@ -3503,28 +2931,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} that has a nice minimum width for a
@@ -3623,28 +3029,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog} without an action bar -->
@@ -3742,28 +3126,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Light_Dialog_NoActionBar} that has a nice minimum
@@ -3862,28 +3224,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
@@ -3963,28 +3303,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. -->
@@ -4064,28 +3382,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a window that will be displayed either full-screen on smaller
@@ -4184,28 +3480,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a window without an action bar that will be displayed either
@@ -4305,28 +3579,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for a presentation window on a secondary display. -->
@@ -4424,28 +3676,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- DeviceDefault light theme for panel windows. This removes all extraneous window
@@ -4542,28 +3772,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert" parent="Theme.Material.Light.Dialog.Alert">
@@ -4659,28 +3867,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Dialog.Alert.DayNight" parent="Theme.DeviceDefault.Light.Dialog.Alert" />
@@ -4776,28 +3962,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Voice" parent="Theme.Material.Light.Voice">
@@ -4891,28 +4055,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- DeviceDefault theme for a window that should look like the Settings app.  -->
@@ -5014,28 +4156,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.SystemUI" parent="Theme.DeviceDefault.Light">
@@ -5118,28 +4238,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.SystemUI.Dialog" parent="Theme.DeviceDefault.Light.Dialog">
@@ -5214,28 +4312,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Variant of {@link #Theme_DeviceDefault_Settings_Dark} with no action bar -->
@@ -5331,28 +4407,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.DialogBase" parent="Theme.Material.Light.BaseDialog">
@@ -5432,28 +4486,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog" parent="Theme.DeviceDefault.Settings.DialogBase">
@@ -5573,28 +4605,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.Alert" parent="Theme.Material.Settings.Dialog.Alert">
@@ -5692,28 +4702,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Settings.Dialog.NoActionBar" parent="Theme.DeviceDefault.Light.Dialog.NoActionBar" />
@@ -5837,28 +4825,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <style name="ThemeOverlay.DeviceDefault.Accent.Light">
@@ -5912,28 +4878,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <!-- Theme overlay that replaces colorAccent with the colorAccent from {@link #Theme_DeviceDefault_DayNight}. -->
@@ -5991,28 +4935,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
 
     <style name="Theme.DeviceDefault.Light.Dialog.Alert.UserSwitchingDialog" parent="Theme.DeviceDefault.NoActionBar.Fullscreen">
@@ -6066,28 +4988,6 @@
         <item name="materialColorSecondary">@color/system_secondary_light</item>
         <item name="materialColorTertiary">@color/system_tertiary_light</item>
         <item name="materialColorError">@color/system_error_light</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_light</item>
-        <item name="customColorClockHour">@color/system_clock_hour_light</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_light</item>
-        <item name="customColorClockSecond">@color/system_clock_second_light</item>
-        <item name="customColorThemeApp">@color/system_theme_app_light</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_light</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_light</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_light</item>
-        <item name="customColorBrandA">@color/system_brand_a_light</item>
-        <item name="customColorBrandB">@color/system_brand_b_light</item>
-        <item name="customColorBrandC">@color/system_brand_c_light</item>
-        <item name="customColorBrandD">@color/system_brand_d_light</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_light</item>
-        <item name="customColorShadeActive">@color/system_shade_active_light</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_light</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_light</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_light</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_light</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_light</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_light</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_light</item>
     </style>
 
     <style name="Theme.DeviceDefault.Notification" parent="@style/Theme.Material.Notification">
@@ -6152,28 +5052,6 @@
         <item name="materialColorSecondary">@color/system_secondary_dark</item>
         <item name="materialColorTertiary">@color/system_tertiary_dark</item>
         <item name="materialColorError">@color/system_error_dark</item>
-
-        <item name="customColorWidgetBackground">@color/system_widget_background_dark</item>
-        <item name="customColorClockHour">@color/system_clock_hour_dark</item>
-        <item name="customColorClockMinute">@color/system_clock_minute_dark</item>
-        <item name="customColorClockSecond">@color/system_clock_second_dark</item>
-        <item name="customColorThemeApp">@color/system_theme_app_dark</item>
-        <item name="customColorOnThemeApp">@color/system_on_theme_app_dark</item>
-        <item name="customColorThemeAppRing">@color/system_theme_app_ring_dark</item>
-        <item name="customColorOnThemeAppRing">@color/system_on_theme_app_ring_dark</item>
-        <item name="customColorBrandA">@color/system_brand_a_dark</item>
-        <item name="customColorBrandB">@color/system_brand_b_dark</item>
-        <item name="customColorBrandC">@color/system_brand_c_dark</item>
-        <item name="customColorBrandD">@color/system_brand_d_dark</item>
-        <item name="customColorUnderSurface">@color/system_under_surface_dark</item>
-        <item name="customColorShadeActive">@color/system_shade_active_dark</item>
-        <item name="customColorOnShadeActive">@color/system_on_shade_active_dark</item>
-        <item name="customColorOnShadeActiveVariant">@color/system_on_shade_active_variant_dark</item>
-        <item name="customColorShadeInactive">@color/system_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactive">@color/system_on_shade_inactive_dark</item>
-        <item name="customColorOnShadeInactiveVariant">@color/system_on_shade_inactive_variant_dark</item>
-        <item name="customColorShadeDisabled">@color/system_shade_disabled_dark</item>
-        <item name="customColorOverviewBackground">@color/system_overview_background_dark</item>
     </style>
     <style name="Theme.DeviceDefault.AutofillHalfScreenDialogList" parent="Theme.DeviceDefault.DayNight">
         <item name="colorListDivider">@color/list_divider_opacity_device_default_light</item>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 17121c8..e729c7d 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
@@ -891,13 +891,13 @@
 
     @WMSingleton
     @Provides
-    static Optional<DesktopTasksController> providesDesktopTasksController(
+    static Optional<DesktopTasksController> providesDesktopTasksController(Context context,
             @DynamicOverride Optional<Lazy<DesktopTasksController>> desktopTasksController) {
         // Use optional-of-lazy for the dependency that this provider relies on.
         // Lazy ensures that this provider will not be the cause the dependency is created
         // when it will not be returned due to the condition below.
         return desktopTasksController.flatMap((lazy)-> {
-            if (DesktopModeStatus.isEnabled()) {
+            if (DesktopModeStatus.canEnterDesktopMode(context)) {
                 return Optional.of(lazy.get());
             }
             return Optional.empty();
@@ -910,13 +910,13 @@
 
     @WMSingleton
     @Provides
-    static Optional<DesktopModeTaskRepository> provideDesktopTaskRepository(
+    static Optional<DesktopModeTaskRepository> provideDesktopTaskRepository(Context context,
             @DynamicOverride Optional<Lazy<DesktopModeTaskRepository>> desktopModeTaskRepository) {
         // Use optional-of-lazy for the dependency that this provider relies on.
         // Lazy ensures that this provider will not be the cause the dependency is created
         // when it will not be returned due to the condition below.
         return desktopModeTaskRepository.flatMap((lazy)-> {
-            if (DesktopModeStatus.isEnabled()) {
+            if (DesktopModeStatus.canEnterDesktopMode(context)) {
                 return Optional.of(lazy.get());
             }
             return Optional.empty();
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 b574b81..a1910c5 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
@@ -221,7 +221,7 @@
             Transitions transitions,
             Optional<DesktopTasksController> desktopTasksController,
             RootTaskDisplayAreaOrganizer rootTaskDisplayAreaOrganizer) {
-        if (DesktopModeStatus.isEnabled()) {
+        if (DesktopModeStatus.canEnterDesktopMode(context)) {
             return new DesktopModeWindowDecorViewModel(
                     context,
                     mainExecutor,
@@ -278,8 +278,8 @@
         ShellInit init = FreeformComponents.isFreeformEnabled(context)
                 ? shellInit
                 : null;
-        return new FreeformTaskListener(init, shellTaskOrganizer, desktopModeTaskRepository,
-                windowDecorViewModel);
+        return new FreeformTaskListener(context, init, shellTaskOrganizer,
+                desktopModeTaskRepository, windowDecorViewModel);
     }
 
     @WMSingleton
@@ -535,10 +535,12 @@
     @WMSingleton
     @Provides
     static Optional<DesktopTasksLimiter> provideDesktopTasksLimiter(
+            Context context,
             Transitions transitions,
             @DynamicOverride DesktopModeTaskRepository desktopModeTaskRepository,
             ShellTaskOrganizer shellTaskOrganizer) {
-        if (!DesktopModeStatus.isEnabled() || !Flags.enableDesktopWindowingTaskLimit()) {
+        if (!DesktopModeStatus.canEnterDesktopMode(context)
+                || !Flags.enableDesktopWindowingTaskLimit()) {
             return Optional.empty();
         }
         return Optional.of(
@@ -592,23 +594,26 @@
     @WMSingleton
     @Provides
     static Optional<DesktopTasksTransitionObserver> provideDesktopTasksTransitionObserver(
+            Context context,
             Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
             Transitions transitions,
             ShellInit shellInit
     ) {
         return desktopModeTaskRepository.flatMap(repository ->
-                Optional.of(new DesktopTasksTransitionObserver(repository, transitions, shellInit))
+                Optional.of(new DesktopTasksTransitionObserver(
+                        context, repository, transitions, shellInit))
         );
     }
 
     @WMSingleton
     @Provides
     static DesktopModeLoggerTransitionObserver provideDesktopModeLoggerTransitionObserver(
+            Context context,
             ShellInit shellInit,
             Transitions transitions,
             DesktopModeEventLogger desktopModeEventLogger) {
         return new DesktopModeLoggerTransitionObserver(
-                shellInit, transitions, desktopModeEventLogger);
+                context, shellInit, transitions, desktopModeEventLogger);
     }
 
     @WMSingleton
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
index a10c7c0..9038aaa 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeLoggerTransitionObserver.kt
@@ -20,6 +20,7 @@
 import android.app.ActivityTaskManager.INVALID_TASK_ID
 import android.app.TaskInfo
 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
+import android.content.Context
 import android.os.IBinder
 import android.util.SparseArray
 import android.view.SurfaceControl
@@ -49,6 +50,7 @@
  * and other transitions that originate both within and outside shell.
  */
 class DesktopModeLoggerTransitionObserver(
+    context: Context,
     shellInit: ShellInit,
     private val transitions: Transitions,
     private val desktopModeEventLogger: DesktopModeEventLogger
@@ -57,7 +59,8 @@
     private val idSequence: InstanceIdSequence by lazy { InstanceIdSequence(Int.MAX_VALUE) }
 
     init {
-        if (Transitions.ENABLE_SHELL_TRANSITIONS && DesktopModeStatus.isEnabled()) {
+        if (Transitions.ENABLE_SHELL_TRANSITIONS &&
+            DesktopModeStatus.canEnterDesktopMode(context)) {
             shellInit.addInitCallback(this::onInit, this)
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
index fcddcad..9bf9fa7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopModeStatus.java
@@ -93,8 +93,10 @@
             "persist.wm.debug.desktop_max_task_limit", DEFAULT_MAX_TASK_LIMIT);
 
     /**
-     * Return {@code true} if desktop windowing is enabled
+     * Return {@code true} if desktop windowing is enabled. Only to be used for testing. Callers
+     * should use {@link #canEnterDesktopMode(Context)} to query the state of desktop windowing.
      */
+    @VisibleForTesting
     public static boolean isEnabled() {
         return Flags.enableDesktopWindowingMode();
     }
@@ -155,9 +157,9 @@
     }
 
     /**
-     * Return {@code true} if desktop mode can be entered on the current device.
+     * Return {@code true} if desktop mode is enabled and can be entered on the current device.
      */
     public static boolean canEnterDesktopMode(@NonNull Context context) {
-        return !enforceDeviceRestrictions() || isDesktopModeSupported(context);
+        return (!enforceDeviceRestrictions() || isDesktopModeSupported(context)) && isEnabled();
     }
 }
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 ecfb134..f7bfb86 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
@@ -167,7 +167,7 @@
 
     init {
         desktopMode = DesktopModeImpl()
-        if (DesktopModeStatus.isEnabled()) {
+        if (DesktopModeStatus.canEnterDesktopMode(context)) {
             shellInit.addInitCallback({ onInit() }, this)
         }
     }
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 20df264..451e09c 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
@@ -16,6 +16,7 @@
 
 package com.android.wm.shell.desktopmode
 
+import android.content.Context
 import android.os.IBinder
 import android.view.SurfaceControl
 import android.view.WindowManager
@@ -33,13 +34,15 @@
  * and other transitions that originate both within and outside shell.
  */
 class DesktopTasksTransitionObserver(
+    context: Context,
     private val desktopModeTaskRepository: DesktopModeTaskRepository,
     private val transitions: Transitions,
     shellInit: ShellInit
 ) : Transitions.TransitionObserver {
 
     init {
-        if (Transitions.ENABLE_SHELL_TRANSITIONS && DesktopModeStatus.isEnabled()) {
+        if (Transitions.ENABLE_SHELL_TRANSITIONS &&
+            DesktopModeStatus.canEnterDesktopMode(context)) {
             shellInit.addInitCallback(::onInit, this)
         }
     }
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
index 6fea203..a414a55 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/freeform/FreeformTaskListener.java
@@ -21,6 +21,7 @@
 import static com.android.wm.shell.ShellTaskOrganizer.TASK_LISTENER_TYPE_FREEFORM;
 
 import android.app.ActivityManager.RunningTaskInfo;
+import android.content.Context;
 import android.util.SparseArray;
 import android.view.SurfaceControl;
 
@@ -44,6 +45,7 @@
         ShellTaskOrganizer.FocusListener {
     private static final String TAG = "FreeformTaskListener";
 
+    private final Context mContext;
     private final ShellTaskOrganizer mShellTaskOrganizer;
     private final Optional<DesktopModeTaskRepository> mDesktopModeTaskRepository;
     private final WindowDecorViewModel mWindowDecorationViewModel;
@@ -56,10 +58,12 @@
     }
 
     public FreeformTaskListener(
+            Context context,
             ShellInit shellInit,
             ShellTaskOrganizer shellTaskOrganizer,
             Optional<DesktopModeTaskRepository> desktopModeTaskRepository,
             WindowDecorViewModel windowDecorationViewModel) {
+        mContext = context;
         mShellTaskOrganizer = shellTaskOrganizer;
         mWindowDecorationViewModel = windowDecorationViewModel;
         mDesktopModeTaskRepository = desktopModeTaskRepository;
@@ -70,7 +74,7 @@
 
     private void onInit() {
         mShellTaskOrganizer.addListenerForType(this, TASK_LISTENER_TYPE_FREEFORM);
-        if (DesktopModeStatus.isEnabled()) {
+        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
             mShellTaskOrganizer.addFocusListener(this);
         }
     }
@@ -92,7 +96,7 @@
             t.apply();
         }
 
-        if (DesktopModeStatus.isEnabled()) {
+        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
             mDesktopModeTaskRepository.ifPresent(repository -> {
                 repository.addOrMoveFreeformTaskToTop(taskInfo.taskId);
                 repository.unminimizeTask(taskInfo.displayId, taskInfo.taskId);
@@ -114,7 +118,7 @@
                 taskInfo.taskId);
         mTasks.remove(taskInfo.taskId);
 
-        if (DesktopModeStatus.isEnabled()) {
+        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
             mDesktopModeTaskRepository.ifPresent(repository -> {
                 repository.removeFreeformTask(taskInfo.taskId);
                 repository.unminimizeTask(taskInfo.displayId, taskInfo.taskId);
@@ -125,7 +129,7 @@
                 repository.updateVisibleFreeformTasks(taskInfo.displayId, taskInfo.taskId, false);
             });
         }
-
+        mWindowDecorationViewModel.onTaskVanished(taskInfo);
         if (!Transitions.ENABLE_SHELL_TRANSITIONS) {
             mWindowDecorationViewModel.destroyWindowDecoration(taskInfo);
         }
@@ -139,7 +143,7 @@
                 taskInfo.taskId);
         mWindowDecorationViewModel.onTaskInfoChanged(taskInfo);
         state.mTaskInfo = taskInfo;
-        if (DesktopModeStatus.isEnabled()) {
+        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
             mDesktopModeTaskRepository.ifPresent(repository -> {
                 if (taskInfo.isVisible) {
                     if (repository.addActiveTask(taskInfo.displayId, taskInfo.taskId)) {
@@ -161,7 +165,7 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG,
                 "Freeform Task Focus Changed: #%d focused=%b",
                 taskInfo.taskId, taskInfo.isFocused);
-        if (DesktopModeStatus.isEnabled() && taskInfo.isFocused) {
+        if (DesktopModeStatus.canEnterDesktopMode(mContext) && taskInfo.isFocused) {
             mDesktopModeTaskRepository.ifPresent(repository -> {
                 repository.addOrMoveFreeformTaskToTop(taskInfo.taskId);
                 repository.unminimizeTask(taskInfo.displayId, taskInfo.taskId);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
index 998728d6..2626e73 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/fullscreen/FullscreenTaskListener.java
@@ -161,7 +161,7 @@
         ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TASK_ORG, "Fullscreen Task Vanished: #%d",
                 taskInfo.taskId);
         mTasks.remove(taskInfo.taskId);
-
+        mWindowDecorViewModelOptional.ifPresent(v -> v.onTaskVanished(taskInfo));
         if (Transitions.ENABLE_SHELL_TRANSITIONS) return;
         if (mWindowDecorViewModelOptional.isPresent()) {
             mWindowDecorViewModelOptional.get().destroyWindowDecoration(taskInfo);
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 c5f23a8..a8611d9 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
@@ -327,7 +327,8 @@
 
     private boolean shouldEnableRunningTasksForDesktopMode() {
         return mPcFeatureEnabled
-                || (DesktopModeStatus.isEnabled() && enableDesktopWindowingTaskbarRunningApps());
+                || (DesktopModeStatus.canEnterDesktopMode(mContext)
+                && enableDesktopWindowingTaskbarRunningApps());
     }
 
     @VisibleForTesting
@@ -371,7 +372,8 @@
                 continue;
             }
 
-            if (DesktopModeStatus.isEnabled() && mDesktopModeTaskRepository.isPresent()
+            if (DesktopModeStatus.canEnterDesktopMode(mContext)
+                    && mDesktopModeTaskRepository.isPresent()
                     && mDesktopModeTaskRepository.get().isActiveTask(taskInfo.taskId)) {
                 if (mDesktopModeTaskRepository.get().isMinimizedTask(taskInfo.taskId)) {
                     // Minimized freeform tasks should not be shown at all.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index f41bca3..1e305c5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -260,6 +260,7 @@
     public void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
         ProtoLog.d(WM_SHELL_SPLIT_SCREEN, "onTaskVanished: task=%d", taskInfo.taskId);
         final int taskId = taskInfo.taskId;
+        mWindowDecorViewModel.ifPresent(vm -> vm.onTaskVanished(taskInfo));
         if (mRootTaskInfo.taskId == taskId) {
             mCallbacks.onRootTaskVanished();
             mRootTaskInfo = null;
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 87dc391..e85cb64 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
@@ -119,6 +119,21 @@
     }
 
     @Override
+    public void onTaskVanished(RunningTaskInfo taskInfo) {
+        // A task vanishing doesn't necessarily mean the task was closed, it could also mean its
+        // windowing mode changed. We're only interested in closing tasks so checking whether
+        // its info still exists in the task organizer is one way to disambiguate.
+        final boolean closed = mTaskOrganizer.getRunningTaskInfo(taskInfo.taskId) == null;
+        if (closed) {
+            // Destroying the window decoration is usually handled when a TRANSIT_CLOSE transition
+            // changes happen, but there are certain cases in which closing tasks aren't included
+            // in transitions, such as when a non-visible task is closed. See b/296921167.
+            // Destroy the decoration here in case the lack of transition missed it.
+            destroyWindowDecoration(taskInfo);
+        }
+    }
+
+    @Override
     public void onTaskChanging(
             RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
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 01175f5..f3ef7c1 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
@@ -35,6 +35,7 @@
 import static com.android.wm.shell.common.split.SplitScreenConstants.SPLIT_POSITION_TOP_OR_LEFT;
 import static com.android.wm.shell.compatui.AppCompatUtils.isSingleTopActivityTranslucent;
 import static com.android.wm.shell.desktopmode.DesktopModeVisualIndicator.IndicatorType.TO_FULLSCREEN_INDICATOR;
+import static com.android.wm.shell.protolog.ShellProtoLogGroup.WM_SHELL_DESKTOP_MODE;
 import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
 
 import android.annotation.NonNull;
@@ -72,6 +73,7 @@
 import androidx.annotation.Nullable;
 
 import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.protolog.common.ProtoLog;
 import com.android.window.flags.Flags;
 import com.android.wm.shell.R;
 import com.android.wm.shell.RootTaskDisplayAreaOrganizer;
@@ -276,7 +278,7 @@
             public void onTaskStageChanged(int taskId, @StageType int stage, boolean visible) {
                 if (visible && stage != STAGE_TYPE_UNDEFINED) {
                     DesktopModeWindowDecoration decor = mWindowDecorByTaskId.get(taskId);
-                    if (decor != null && DesktopModeStatus.isEnabled()) {
+                    if (decor != null && DesktopModeStatus.canEnterDesktopMode(mContext)) {
                         mDesktopTasksController.moveToSplit(decor.mTaskInfo);
                     }
                 }
@@ -309,6 +311,22 @@
     }
 
     @Override
+    public void onTaskVanished(RunningTaskInfo taskInfo) {
+        // A task vanishing doesn't necessarily mean the task was closed, it could also mean its
+        // windowing mode changed. We're only interested in closing tasks so checking whether
+        // its info still exists in the task organizer is one way to disambiguate.
+        final boolean closed = mTaskOrganizer.getRunningTaskInfo(taskInfo.taskId) == null;
+        ProtoLog.v(WM_SHELL_DESKTOP_MODE, "Task Vanished: #%d closed=%b", taskInfo.taskId, closed);
+        if (closed) {
+            // Destroying the window decoration is usually handled when a TRANSIT_CLOSE transition
+            // changes happen, but there are certain cases in which closing tasks aren't included
+            // in transitions, such as when a non-visible task is closed. See b/296921167.
+            // Destroy the decoration here in case the lack of transition missed it.
+            destroyWindowDecoration(taskInfo);
+        }
+    }
+
+    @Override
     public void onTaskChanging(
             RunningTaskInfo taskInfo,
             SurfaceControl taskSurface,
@@ -594,7 +612,7 @@
         public boolean handleMotionEvent(@Nullable View v, MotionEvent e) {
             final DesktopModeWindowDecoration decoration = mWindowDecorByTaskId.get(mTaskId);
             final RunningTaskInfo taskInfo = decoration.mTaskInfo;
-            if (DesktopModeStatus.isEnabled()
+            if (DesktopModeStatus.canEnterDesktopMode(mContext)
                     && taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
                 return false;
             }
@@ -771,7 +789,7 @@
      */
     private void handleReceivedMotionEvent(MotionEvent ev, InputMonitor inputMonitor) {
         final DesktopModeWindowDecoration relevantDecor = getRelevantWindowDecor(ev);
-        if (DesktopModeStatus.isEnabled()) {
+        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
             if (!mInImmersiveMode && (relevantDecor == null
                     || relevantDecor.mTaskInfo.getWindowingMode() != WINDOWING_MODE_FREEFORM
                     || mTransitionDragActive)) {
@@ -780,7 +798,7 @@
         }
         handleEventOutsideCaption(ev, relevantDecor);
         // Prevent status bar from reacting to a caption drag.
-        if (DesktopModeStatus.isEnabled()) {
+        if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
             if (mTransitionDragActive) {
                 inputMonitor.pilferPointers();
             }
@@ -838,7 +856,7 @@
                 mDragToDesktopAnimationStartBounds.set(
                         relevantDecor.mTaskInfo.configuration.windowConfiguration.getBounds());
                 boolean dragFromStatusBarAllowed = false;
-                if (DesktopModeStatus.isEnabled()) {
+                if (DesktopModeStatus.canEnterDesktopMode(mContext)) {
                     // In proto2 any full screen or multi-window task can be dragged to
                     // freeform.
                     final int windowingMode = relevantDecor.mTaskInfo.getWindowingMode();
@@ -1013,12 +1031,11 @@
                 && isSingleTopActivityTranslucent(taskInfo)) {
             return false;
         }
-        return DesktopModeStatus.isEnabled()
+        return DesktopModeStatus.canEnterDesktopMode(mContext)
                 && !DesktopWallpaperActivity.isWallpaperTask(taskInfo)
                 && taskInfo.getWindowingMode() != WINDOWING_MODE_PINNED
                 && taskInfo.getActivityType() == ACTIVITY_TYPE_STANDARD
-                && !taskInfo.configuration.windowConfiguration.isAlwaysOnTop()
-                && DesktopModeStatus.canEnterDesktopMode(mContext);
+                && !taskInfo.configuration.windowConfiguration.isAlwaysOnTop();
     }
 
     private void createWindowDecoration(
@@ -1087,7 +1104,8 @@
     private void dump(PrintWriter pw, String prefix) {
         final String innerPrefix = prefix + "  ";
         pw.println(prefix + "DesktopModeWindowDecorViewModel");
-        pw.println(innerPrefix + "DesktopModeStatus=" + DesktopModeStatus.isEnabled());
+        pw.println(innerPrefix + "DesktopModeStatus="
+                + DesktopModeStatus.canEnterDesktopMode(mContext));
         pw.println(innerPrefix + "mTransitionDragActive=" + mTransitionDragActive);
         pw.println(innerPrefix + "mEventReceiversByDisplay=" + mEventReceiversByDisplay);
         pw.println(innerPrefix + "mWindowDecorByTaskId=" + mWindowDecorByTaskId);
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 8c6bc73..f7516da 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
@@ -638,7 +638,7 @@
                 .setOnClickListener(mOnCaptionButtonClickListener)
                 .setOnTouchListener(mOnCaptionTouchListener)
                 .setLayoutId(mRelayoutParams.mLayoutResId)
-                .setWindowingButtonsVisible(DesktopModeStatus.isEnabled())
+                .setWindowingButtonsVisible(DesktopModeStatus.canEnterDesktopMode(mContext))
                 .setCaptionHeight(mResult.mCaptionHeight)
                 .build();
         mWindowDecorViewHolder.onHandleMenuOpened();
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 01a6012..1563259 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
@@ -67,6 +67,14 @@
     void onTaskInfoChanged(ActivityManager.RunningTaskInfo taskInfo);
 
     /**
+     * Notifies a task has vanished, which can mean that the task changed windowing mode or was
+     * removed.
+     *
+     * @param taskInfo the task info of the task
+     */
+    void onTaskVanished(ActivityManager.RunningTaskInfo taskInfo);
+
+    /**
      * Notifies a transition is about to start about the given task to give the window decoration a
      * chance to prepare for this transition. Unlike {@link #onTaskInfoChanged}, this method creates
      * a window decoration if one does not exist but is required.
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 65117f7..60a7dcd 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
@@ -18,6 +18,7 @@
 import android.app.ActivityManager
 import android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM
 import android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN
+import android.content.Context
 import android.os.IBinder
 import android.testing.AndroidTestingRunner
 import android.view.SurfaceControl
@@ -35,6 +36,7 @@
 import android.window.TransitionInfo.Change
 import android.window.WindowContainerToken
 import androidx.test.filters.SmallTest
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
 import com.android.modules.utils.testing.ExtendedMockitoRule
 import com.android.wm.shell.common.ShellExecutor
 import com.android.wm.shell.desktopmode.DesktopModeEventLogger.Companion.EnterReason
@@ -58,6 +60,11 @@
 import org.mockito.kotlin.same
 import org.mockito.kotlin.times
 
+/**
+ * Test class for {@link DesktopModeLoggerTransitionObserver}
+ *
+ * Usage: atest WMShellUnitTests:DesktopModeLoggerTransitionObserverTest
+ */
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 class DesktopModeLoggerTransitionObserverTest {
@@ -74,6 +81,8 @@
     private lateinit var mockShellInit: ShellInit
     @Mock
     private lateinit var transitions: Transitions
+    @Mock
+    private lateinit var context: Context
 
     private lateinit var transitionObserver: DesktopModeLoggerTransitionObserver
     private lateinit var shellInit: ShellInit
@@ -81,12 +90,12 @@
 
     @Before
     fun setup() {
-        Mockito.`when`(DesktopModeStatus.isEnabled()).thenReturn(true)
+        doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(any()) }
         shellInit = Mockito.spy(ShellInit(testExecutor))
         desktopModeEventLogger = mock(DesktopModeEventLogger::class.java)
 
         transitionObserver = DesktopModeLoggerTransitionObserver(
-            mockShellInit, transitions, desktopModeEventLogger)
+            context, mockShellInit, transitions, desktopModeEventLogger)
         if (Transitions.ENABLE_SHELL_TRANSITIONS) {
             val initRunnableCaptor = ArgumentCaptor.forClass(
                 Runnable::class.java)
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 ad4b720..df8a222 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
@@ -159,6 +159,7 @@
         mockitoSession = mockitoSession().strictness(Strictness.LENIENT)
             .spyStatic(DesktopModeStatus::class.java).startMocking()
         whenever(DesktopModeStatus.isEnabled()).thenReturn(true)
+        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
 
         shellInit = Mockito.spy(ShellInit(testExecutor))
         desktopModeTaskRepository = DesktopModeTaskRepository()
@@ -1347,7 +1348,6 @@
 
     private fun setUpFullscreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
         val task = createFullscreenTask(displayId)
-        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
         whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
         whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
         runningTasks.add(task)
@@ -1356,7 +1356,6 @@
 
     private fun setUpSplitScreenTask(displayId: Int = DEFAULT_DISPLAY): RunningTaskInfo {
         val task = createSplitScreenTask(displayId)
-        doReturn(true).`when` { DesktopModeStatus.isDesktopModeSupported(any()) }
         whenever(DesktopModeStatus.enforceDeviceRestrictions()).thenReturn(true)
         whenever(splitScreenController.isTaskInSplitScreen(task.taskId)).thenReturn(true)
         whenever(shellTaskOrganizer.getRunningTaskInfo(task.taskId)).thenReturn(task)
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
index 38ea034..539d5b8 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopTasksLimiterTest.kt
@@ -27,6 +27,7 @@
 import android.window.WindowContainerTransaction.HierarchyOp.HIERARCHY_OP_TYPE_REORDER
 import androidx.test.filters.SmallTest
 import com.android.dx.mockito.inline.extended.ExtendedMockito
+import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn
 import com.android.dx.mockito.inline.extended.StaticMockitoSession
 import com.android.wm.shell.ShellTaskOrganizer
 import com.android.wm.shell.ShellTestCase
@@ -41,6 +42,7 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
+import org.mockito.Mockito.any
 import org.mockito.Mockito.`when`
 import org.mockito.quality.Strictness
 
@@ -69,7 +71,7 @@
     fun setUp() {
         mockitoSession = ExtendedMockito.mockitoSession().strictness(Strictness.LENIENT)
                 .spyStatic(DesktopModeStatus::class.java).startMocking()
-        `when`(DesktopModeStatus.isEnabled()).thenReturn(true)
+        doReturn(true).`when`{ DesktopModeStatus.canEnterDesktopMode(any()) }
 
         desktopTaskRepo = DesktopModeTaskRepository()
 
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
index 71eea4b..665077b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/freeform/FreeformTaskListenerTests.java
@@ -19,11 +19,12 @@
 import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
 import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
 
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
 
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import android.app.ActivityManager;
 
@@ -72,8 +73,10 @@
     public void setup() {
         mMockitoSession = mockitoSession().initMocks(this)
                 .strictness(Strictness.LENIENT).mockStatic(DesktopModeStatus.class).startMocking();
-        when(DesktopModeStatus.isEnabled()).thenReturn(true);
+        doReturn(true).when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+
         mFreeformTaskListener = new FreeformTaskListener(
+                mContext,
                 mShellInit,
                 mTaskOrganizer,
                 Optional.of(mDesktopModeTaskRepository),
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 5cf9be4..240324b 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -59,6 +59,7 @@
 import androidx.test.filters.SmallTest;
 import androidx.test.runner.AndroidJUnit4;
 
+import com.android.dx.mockito.inline.extended.ExtendedMockito;
 import com.android.dx.mockito.inline.extended.StaticMockitoSession;
 import com.android.window.flags.Flags;
 import com.android.wm.shell.ShellTaskOrganizer;
@@ -75,11 +76,13 @@
 import com.android.wm.shell.util.GroupedRecentTaskInfo;
 import com.android.wm.shell.util.SplitBounds;
 
+import org.junit.After;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
+import org.mockito.quality.Strictness;
 
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -88,7 +91,9 @@
 import java.util.function.Consumer;
 
 /**
- * Tests for {@link RecentTasksController}.
+ * Tests for {@link RecentTasksController}
+ *
+ * Usage: atest WMShellUnitTests:RecentTasksControllerTest
  */
 @RunWith(AndroidJUnit4.class)
 @SmallTest
@@ -118,9 +123,15 @@
     private ShellInit mShellInit;
     private ShellController mShellController;
     private TestShellExecutor mMainExecutor;
+    private static StaticMockitoSession sMockitoSession;
 
     @Before
     public void setUp() {
+        sMockitoSession = mockitoSession().initMocks(this).strictness(Strictness.LENIENT)
+                .mockStatic(DesktopModeStatus.class).startMocking();
+        ExtendedMockito.doReturn(true)
+                .when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
+
         mMainExecutor = new TestShellExecutor();
         when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
         mShellInit = spy(new ShellInit(mMainExecutor));
@@ -136,6 +147,11 @@
         mShellInit.init();
     }
 
+    @After
+    public void tearDown() {
+        sMockitoSession.finishMocking();
+    }
+
     @Test
     public void instantiateController_addInitCallback() {
         verify(mShellInit, times(1)).addInitCallback(any(), isA(RecentTasksController.class));
@@ -275,10 +291,6 @@
 
     @Test
     public void testGetRecentTasks_hasActiveDesktopTasks_proto2Enabled_groupFreeformTasks() {
-        StaticMockitoSession mockitoSession = mockitoSession().mockStatic(
-                DesktopModeStatus.class).startMocking();
-        when(DesktopModeStatus.isEnabled()).thenReturn(true);
-
         ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
         ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
@@ -309,16 +321,10 @@
         // Check single entries
         assertEquals(t2, singleGroup1.getTaskInfo1());
         assertEquals(t4, singleGroup2.getTaskInfo1());
-
-        mockitoSession.finishMocking();
     }
 
     @Test
     public void testGetRecentTasks_hasActiveDesktopTasks_proto2Enabled_freeformTaskOrder() {
-        StaticMockitoSession mockitoSession = mockitoSession().mockStatic(
-                DesktopModeStatus.class).startMocking();
-        when(DesktopModeStatus.isEnabled()).thenReturn(true);
-
         ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
         ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
@@ -357,15 +363,12 @@
 
         // Check single entry
         assertEquals(t4, singleGroup.getTaskInfo1());
-
-        mockitoSession.finishMocking();
     }
 
     @Test
     public void testGetRecentTasks_hasActiveDesktopTasks_proto2Disabled_doNotGroupFreeformTasks() {
-        StaticMockitoSession mockitoSession = mockitoSession().mockStatic(
-                DesktopModeStatus.class).startMocking();
-        when(DesktopModeStatus.isEnabled()).thenReturn(false);
+        ExtendedMockito.doReturn(false)
+                .when(() -> DesktopModeStatus.canEnterDesktopMode(any()));
 
         ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
@@ -390,16 +393,10 @@
         assertEquals(t2, recentTasks.get(1).getTaskInfo1());
         assertEquals(t3, recentTasks.get(2).getTaskInfo1());
         assertEquals(t4, recentTasks.get(3).getTaskInfo1());
-
-        mockitoSession.finishMocking();
     }
 
     @Test
     public void testGetRecentTasks_proto2Enabled_ignoresMinimizedFreeformTasks() {
-        StaticMockitoSession mockitoSession = mockitoSession().mockStatic(
-                DesktopModeStatus.class).startMocking();
-        when(DesktopModeStatus.isEnabled()).thenReturn(true);
-
         ActivityManager.RecentTaskInfo t1 = makeTaskInfo(1);
         ActivityManager.RecentTaskInfo t2 = makeTaskInfo(2);
         ActivityManager.RecentTaskInfo t3 = makeTaskInfo(3);
@@ -435,8 +432,6 @@
         // Check single entries
         assertEquals(t2, singleGroup1.getTaskInfo1());
         assertEquals(t4, singleGroup2.getTaskInfo1());
-
-        mockitoSession.finishMocking();
     }
 
     @Test
diff --git a/libs/input/SpriteController.h b/libs/input/SpriteController.h
index 4e4ba65..fdb15506 100644
--- a/libs/input/SpriteController.h
+++ b/libs/input/SpriteController.h
@@ -165,29 +165,23 @@
      * on the sprites for a long time.
      * Note that the SpriteIcon holds a reference to a shared (and immutable) bitmap. */
     struct SpriteState {
-        inline SpriteState() :
-                dirty(0), visible(false),
-                positionX(0), positionY(0), layer(0), alpha(1.0f), displayId(ADISPLAY_ID_DEFAULT),
-                surfaceWidth(0), surfaceHeight(0), surfaceDrawn(false), surfaceVisible(false) {
-        }
-
-        uint32_t dirty;
+        uint32_t dirty{0};
 
         SpriteIcon icon;
-        bool visible;
-        float positionX;
-        float positionY;
-        int32_t layer;
-        float alpha;
+        bool visible{false};
+        float positionX{0};
+        float positionY{0};
+        int32_t layer{0};
+        float alpha{1.0f};
         SpriteTransformationMatrix transformationMatrix;
-        int32_t displayId;
+        int32_t displayId{ADISPLAY_ID_DEFAULT};
 
         sp<SurfaceControl> surfaceControl;
-        int32_t surfaceWidth;
-        int32_t surfaceHeight;
-        bool surfaceDrawn;
-        bool surfaceVisible;
-        bool skipScreenshot;
+        int32_t surfaceWidth{0};
+        int32_t surfaceHeight{0};
+        bool surfaceDrawn{false};
+        bool surfaceVisible{false};
+        bool skipScreenshot{false};
 
         inline bool wantSurfaceVisible() const {
             return visible && alpha > 0.0f && icon.isValid();
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 65c5708..fce7a00f 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -382,6 +382,7 @@
         "androidx.compose.material_material-icons-extended",
         "androidx.activity_activity-compose",
         "androidx.compose.animation_animation-graphics",
+        "device_policy_aconfig_flags_lib",
     ],
     libs: [
         "keepanno-annotations",
@@ -622,6 +623,7 @@
         "//frameworks/libs/systemui:compilelib",
         "SystemUI-tests-base",
         "androidx.compose.runtime_runtime",
+        "SystemUI-core",
     ],
     libs: [
         "keepanno-annotations",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 59e2b91..b9e70ef 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -1110,7 +1110,7 @@
                 android:resource="@xml/home_controls_dream_metadata" />
         </service>
 
-        <activity android:name="com.android.systemui.keyboard.shortcut.ShortcutHelperActivity"
+        <activity android:name="com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity"
             android:exported="false"
             android:theme="@style/ShortcutHelperTheme"
             android:excludeFromRecents="true"
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncButtonComponent.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncButtonComponent.kt
index 0f6d51d..79d17ef 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncButtonComponent.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/component/anc/ui/composable/AncButtonComponent.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.volume.panel.component.anc.ui.composable
 
+import androidx.compose.foundation.basicMarquee
 import androidx.compose.foundation.layout.Arrangement
 import androidx.compose.foundation.layout.Column
 import androidx.compose.foundation.layout.fillMaxWidth
@@ -35,7 +36,6 @@
 import androidx.compose.ui.semantics.contentDescription
 import androidx.compose.ui.semantics.role
 import androidx.compose.ui.semantics.semantics
-import androidx.compose.ui.text.style.TextOverflow
 import androidx.compose.ui.unit.dp
 import com.android.systemui.res.R
 import com.android.systemui.volume.panel.component.anc.ui.viewmodel.AncViewModel
@@ -81,11 +81,10 @@
                 onClick = onClick,
             )
             Text(
-                modifier = Modifier.clearAndSetSemantics {},
+                modifier = Modifier.clearAndSetSemantics {}.basicMarquee(),
                 text = label,
                 style = MaterialTheme.typography.labelMedium,
-                maxLines = 1,
-                overflow = TextOverflow.Ellipsis,
+                maxLines = 2,
             )
         }
     }
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
index c51e8b0..a602e25 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/volume/panel/ui/composable/VolumePanelRoot.kt
@@ -28,7 +28,11 @@
 import androidx.compose.runtime.getValue
 import androidx.compose.ui.Alignment
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.paneTitle
+import androidx.compose.ui.semantics.semantics
 import androidx.compose.ui.unit.dp
+import com.android.systemui.res.R
 import com.android.systemui.volume.panel.ui.layout.ComponentsLayout
 import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelState
 import com.android.systemui.volume.panel.ui.viewmodel.VolumePanelViewModel
@@ -49,6 +53,7 @@
         }
     }
 
+    val accessibilityTitle = stringResource(R.string.accessibility_volume_settings)
     val state: VolumePanelState by viewModel.volumePanelState.collectAsState()
     val components by viewModel.componentsLayout.collectAsState(null)
 
@@ -56,12 +61,14 @@
         components?.let { componentsState ->
             Components(
                 componentsState,
-                modifier.padding(
-                    start = padding,
-                    top = padding,
-                    end = padding,
-                    bottom = 20.dp,
-                )
+                modifier
+                    .semantics { paneTitle = accessibilityTitle }
+                    .padding(
+                        start = padding,
+                        top = padding,
+                        end = padding,
+                        bottom = 20.dp,
+                    )
             )
         }
     }
diff --git a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
index 624f18d..47a00f4 100644
--- a/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
+++ b/packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
@@ -133,7 +133,7 @@
         @ColorInt seed: Int,
         darkTheme: Boolean,
         style: Style
-    ) : this(seed, darkTheme, style, 0.0)
+    ) : this(seed, darkTheme, style, 0.5)
 
     @JvmOverloads
     constructor(
diff --git a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
index 447c280..6c3f3c1 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.kt
@@ -17,8 +17,11 @@
 
 package com.android.keyguard
 
+import android.app.admin.DevicePolicyManager
+import android.app.admin.flags.Flags as DevicePolicyFlags
 import android.content.res.Configuration
 import android.media.AudioManager
+import android.platform.test.annotations.EnableFlags
 import android.telephony.TelephonyManager
 import android.testing.TestableLooper.RunWithLooper
 import android.testing.TestableResources
@@ -148,6 +151,7 @@
     @Mock private lateinit var faceAuthAccessibilityDelegate: FaceAuthAccessibilityDelegate
     @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController
     @Mock private lateinit var postureController: DevicePostureController
+    @Mock private lateinit var devicePolicyManager: DevicePolicyManager
 
     @Captor
     private lateinit var swipeListenerArgumentCaptor:
@@ -273,6 +277,7 @@
                 mSelectedUserInteractor,
                 deviceProvisionedController,
                 faceAuthAccessibilityDelegate,
+                devicePolicyManager,
                 keyguardTransitionInteractor,
                 { primaryBouncerInteractor },
             ) {
@@ -934,6 +939,45 @@
         verify(viewFlipperController).asynchronouslyInflateView(any(), any(), any())
     }
 
+    @Test
+    @EnableFlags(DevicePolicyFlags.FLAG_HEADLESS_SINGLE_USER_FIXES)
+    fun showAlmostAtWipeDialog_calledOnMainUser_setsCorrectUserType() {
+        val mainUserId = 10
+
+        underTest.showMessageForFailedUnlockAttempt(
+            /* userId = */ mainUserId,
+            /* expiringUserId = */ mainUserId,
+            /* mainUserId = */ mainUserId,
+            /* remainingBeforeWipe = */ 1,
+            /* failedAttempts = */ 1
+        )
+
+        verify(view)
+            .showAlmostAtWipeDialog(any(), any(), eq(KeyguardSecurityContainer.USER_TYPE_PRIMARY))
+    }
+
+    @Test
+    @EnableFlags(DevicePolicyFlags.FLAG_HEADLESS_SINGLE_USER_FIXES)
+    fun showAlmostAtWipeDialog_calledOnNonMainUser_setsCorrectUserType() {
+        val secondaryUserId = 10
+        val mainUserId = 0
+
+        underTest.showMessageForFailedUnlockAttempt(
+            /* userId = */ secondaryUserId,
+            /* expiringUserId = */ secondaryUserId,
+            /* mainUserId = */ mainUserId,
+            /* remainingBeforeWipe = */ 1,
+            /* failedAttempts = */ 1
+        )
+
+        verify(view)
+            .showAlmostAtWipeDialog(
+                any(),
+                any(),
+                eq(KeyguardSecurityContainer.USER_TYPE_SECONDARY_USER)
+            )
+    }
+
     private val registeredSwipeListener: KeyguardSecurityContainer.SwipeListener
         get() {
             underTest.onViewAttached()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
index 81878aa..0c5e726 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractorTest.kt
@@ -17,6 +17,8 @@
 package com.android.systemui.authentication.domain.interactor
 
 import android.app.admin.DevicePolicyManager
+import android.app.admin.flags.Flags as DevicePolicyFlags
+import android.platform.test.annotations.EnableFlags
 import androidx.test.ext.junit.runners.AndroidJUnit4
 import androidx.test.filters.SmallTest
 import com.android.internal.widget.LockPatternUtils
@@ -32,6 +34,8 @@
 import com.android.systemui.coroutines.collectLastValue
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
+import com.android.systemui.user.data.repository.FakeUserRepository
+import com.android.systemui.user.data.repository.fakeUserRepository
 import com.google.common.truth.Truth.assertThat
 import kotlin.time.Duration.Companion.seconds
 import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -410,12 +414,16 @@
         }
 
     @Test
+    @EnableFlags(DevicePolicyFlags.FLAG_HEADLESS_SINGLE_USER_FIXES)
     fun upcomingWipe() =
         testScope.runTest {
             val upcomingWipe by collectLastValue(underTest.upcomingWipe)
             kosmos.fakeAuthenticationRepository.setAuthenticationMethod(Pin)
             val correctPin = FakeAuthenticationRepository.DEFAULT_PIN
             val wrongPin = FakeAuthenticationRepository.DEFAULT_PIN.map { it + 1 }
+            kosmos.fakeUserRepository.asMainUser()
+            kosmos.fakeAuthenticationRepository.profileWithMinFailedUnlockAttemptsForWipe =
+                FakeUserRepository.MAIN_USER_ID
 
             underTest.authenticate(correctPin)
             assertThat(upcomingWipe).isNull()
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/BooleanFlowOperatorsTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/BooleanFlowOperatorsTest.kt
index 03a39f8..2d8cd93 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/BooleanFlowOperatorsTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/util/kotlin/BooleanFlowOperatorsTest.kt
@@ -23,9 +23,9 @@
 import com.android.systemui.coroutines.collectValues
 import com.android.systemui.kosmos.testScope
 import com.android.systemui.testKosmos
-import com.android.systemui.util.kotlin.BooleanFlowOperators.and
+import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
+import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import com.android.systemui.util.kotlin.BooleanFlowOperators.not
-import com.android.systemui.util.kotlin.BooleanFlowOperators.or
 import com.google.common.truth.Truth.assertThat
 import kotlinx.coroutines.flow.Flow
 import kotlinx.coroutines.flow.MutableStateFlow
@@ -45,21 +45,21 @@
     @Test
     fun and_allTrue_returnsTrue() =
         testScope.runTest {
-            val result by collectLastValue(and(TRUE, TRUE))
+            val result by collectLastValue(allOf(TRUE, TRUE))
             assertThat(result).isTrue()
         }
 
     @Test
     fun and_anyFalse_returnsFalse() =
         testScope.runTest {
-            val result by collectLastValue(and(TRUE, FALSE, TRUE))
+            val result by collectLastValue(allOf(TRUE, FALSE, TRUE))
             assertThat(result).isFalse()
         }
 
     @Test
     fun and_allFalse_returnsFalse() =
         testScope.runTest {
-            val result by collectLastValue(and(FALSE, FALSE, FALSE))
+            val result by collectLastValue(allOf(FALSE, FALSE, FALSE))
             assertThat(result).isFalse()
         }
 
@@ -68,7 +68,7 @@
         testScope.runTest {
             val flow1 = MutableStateFlow(false)
             val flow2 = MutableStateFlow(false)
-            val values by collectValues(and(flow1, flow2))
+            val values by collectValues(allOf(flow1, flow2))
 
             assertThat(values).containsExactly(false)
             flow1.value = true
@@ -81,21 +81,21 @@
     @Test
     fun or_allTrue_returnsTrue() =
         testScope.runTest {
-            val result by collectLastValue(or(TRUE, TRUE))
+            val result by collectLastValue(anyOf(TRUE, TRUE))
             assertThat(result).isTrue()
         }
 
     @Test
     fun or_anyTrue_returnsTrue() =
         testScope.runTest {
-            val result by collectLastValue(or(FALSE, TRUE, FALSE))
+            val result by collectLastValue(anyOf(FALSE, TRUE, FALSE))
             assertThat(result).isTrue()
         }
 
     @Test
     fun or_allFalse_returnsFalse() =
         testScope.runTest {
-            val result by collectLastValue(or(FALSE, FALSE, FALSE))
+            val result by collectLastValue(anyOf(FALSE, FALSE, FALSE))
             assertThat(result).isFalse()
         }
 
@@ -104,7 +104,7 @@
         testScope.runTest {
             val flow1 = MutableStateFlow(false)
             val flow2 = MutableStateFlow(false)
-            val values by collectValues(or(flow1, flow2))
+            val values by collectValues(anyOf(flow1, flow2))
 
             assertThat(values).containsExactly(false)
             flow1.value = true
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index c43e394..da12dd7 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -36,7 +36,6 @@
     </style>
     <style name="Keyguard.Bouncer.SecondaryMessage" parent="Theme.SystemUI">
         <item name="android:textSize">14sp</item>
-        <item name="android:lineHeight">20dp</item>
         <item name="android:maxLines">@integer/bouncer_secondary_message_lines</item>
         <item name="android:lines">@integer/bouncer_secondary_message_lines</item>
         <item name="android:textAlignment">center</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 91fb688..905a98c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -35,6 +35,7 @@
 
 import android.app.ActivityManager;
 import android.app.admin.DevicePolicyManager;
+import android.app.admin.flags.Flags;
 import android.content.Intent;
 import android.content.res.ColorStateList;
 import android.content.res.Configuration;
@@ -134,6 +135,7 @@
     private final BouncerMessageInteractor mBouncerMessageInteractor;
     private int mTranslationY;
     private final KeyguardTransitionInteractor mKeyguardTransitionInteractor;
+    private final DevicePolicyManager mDevicePolicyManager;
     // Whether the volume keys should be handled by keyguard. If true, then
     // they will be handled here for specific media types such as music, otherwise
     // the audio service will bring up the volume dialog.
@@ -460,6 +462,7 @@
             SelectedUserInteractor selectedUserInteractor,
             DeviceProvisionedController deviceProvisionedController,
             FaceAuthAccessibilityDelegate faceAuthAccessibilityDelegate,
+            DevicePolicyManager devicePolicyManager,
             KeyguardTransitionInteractor keyguardTransitionInteractor,
             Lazy<PrimaryBouncerInteractor> primaryBouncerInteractor,
             Provider<DeviceEntryInteractor> deviceEntryInteractor
@@ -495,6 +498,7 @@
         mKeyguardTransitionInteractor = keyguardTransitionInteractor;
         mDeviceProvisionedController = deviceProvisionedController;
         mPrimaryBouncerInteractor = primaryBouncerInteractor;
+        mDevicePolicyManager = devicePolicyManager;
     }
 
     @Override
@@ -1105,35 +1109,23 @@
 
         if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts);
 
-        final DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager();
         final int failedAttemptsBeforeWipe =
-                dpm.getMaximumFailedPasswordsForWipe(null, userId);
+                mDevicePolicyManager.getMaximumFailedPasswordsForWipe(null, userId);
 
         final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0
                 ? (failedAttemptsBeforeWipe - failedAttempts)
                 : Integer.MAX_VALUE; // because DPM returns 0 if no restriction
         if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) {
-            // The user has installed a DevicePolicyManager that requests a user/profile to be wiped
-            // N attempts. Once we get below the grace period, we post this dialog every time as a
-            // clear warning until the deletion fires.
-            // Check which profile has the strictest policy for failed password attempts
-            final int expiringUser = dpm.getProfileWithMinimumFailedPasswordsForWipe(userId);
-            int userType = USER_TYPE_PRIMARY;
-            if (expiringUser == userId) {
-                // TODO: http://b/23522538
-                if (expiringUser != UserHandle.USER_SYSTEM) {
-                    userType = USER_TYPE_SECONDARY_USER;
-                }
-            } else if (expiringUser != UserHandle.USER_NULL) {
-                userType = USER_TYPE_WORK_PROFILE;
-            } // If USER_NULL, which shouldn't happen, leave it as USER_TYPE_PRIMARY
-            if (remainingBeforeWipe > 0) {
-                mView.showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe, userType);
-            } else {
-                // Too many attempts. The device will be wiped shortly.
-                Slog.i(TAG, "Too many unlock attempts; user " + expiringUser + " will be wiped!");
-                mView.showWipeDialog(failedAttempts, userType);
-            }
+            // The user has installed a DevicePolicyManager that requests a
+            // user/profile to be wiped N attempts. Once we get below the grace period,
+            // we post this dialog every time as a clear warning until the deletion
+            // fires. Check which profile has the strictest policy for failed password
+            // attempts.
+            final int expiringUser =
+                    mDevicePolicyManager.getProfileWithMinimumFailedPasswordsForWipe(userId);
+            Integer mainUser = mSelectedUserInteractor.getMainUserId();
+            showMessageForFailedUnlockAttempt(
+                    userId, expiringUser, mainUser, remainingBeforeWipe, failedAttempts);
         }
         mLockPatternUtils.reportFailedPasswordAttempt(userId);
         if (timeoutMs > 0) {
@@ -1145,6 +1137,35 @@
         }
     }
 
+    @VisibleForTesting
+    void showMessageForFailedUnlockAttempt(int userId, int expiringUserId, Integer mainUserId,
+            int remainingBeforeWipe, int failedAttempts) {
+        int userType = USER_TYPE_PRIMARY;
+        if (expiringUserId == userId) {
+            int primaryUser = UserHandle.USER_SYSTEM;
+            if (Flags.headlessSingleUserFixes()) {
+                if (mainUserId != null) {
+                    primaryUser = mainUserId;
+                }
+            }
+            // TODO: http://b/23522538
+            if (expiringUserId != primaryUser) {
+                userType = USER_TYPE_SECONDARY_USER;
+            }
+        } else if (expiringUserId != UserHandle.USER_NULL) {
+            userType = USER_TYPE_WORK_PROFILE;
+        } // If USER_NULL, which shouldn't happen, leave it as USER_TYPE_PRIMARY
+        if (remainingBeforeWipe > 0) {
+            mView.showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe,
+                    userType);
+        } else {
+            // Too many attempts. The device will be wiped shortly.
+            Slog.i(TAG, "Too many unlock attempts; user " + expiringUserId
+                    + " will be wiped!");
+            mView.showWipeDialog(failedAttempts, userType);
+        }
+    }
+
     private void getCurrentSecurityController(
             KeyguardSecurityViewFlipperController.OnViewInflatedCallback onViewInflatedCallback) {
         mSecurityViewFlipperController
diff --git a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
index 5df7fc9..fcba425 100644
--- a/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/authentication/domain/interactor/AuthenticationInteractor.kt
@@ -16,6 +16,7 @@
 
 package com.android.systemui.authentication.domain.interactor
 
+import android.app.admin.flags.Flags
 import android.os.UserHandle
 import com.android.internal.widget.LockPatternUtils
 import com.android.internal.widget.LockPatternView
@@ -288,9 +289,15 @@
     private suspend fun getWipeTarget(): WipeTarget {
         // Check which profile has the strictest policy for failed authentication attempts.
         val userToBeWiped = repository.getProfileWithMinFailedUnlockAttemptsForWipe()
+        val primaryUser =
+            if (Flags.headlessSingleUserFixes()) {
+                selectedUserInteractor.getMainUserId() ?: UserHandle.USER_SYSTEM
+            } else {
+                UserHandle.USER_SYSTEM
+            }
         return when (userToBeWiped) {
             selectedUserInteractor.getSelectedUserId() ->
-                if (userToBeWiped == UserHandle.USER_SYSTEM) {
+                if (userToBeWiped == primaryUser) {
                     WipeTarget.WholeDevice
                 } else {
                     WipeTarget.User
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogModule.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogModule.kt
new file mode 100644
index 0000000..2e9169e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogModule.kt
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.bluetooth.qsdialog
+
+import com.android.systemui.dagger.SysUISingleton
+import dagger.Binds
+import dagger.Module
+
+@Module
+interface BluetoothTileDialogModule {
+    @Binds
+    @SysUISingleton
+    fun bindDeviceItemActionInteractor(
+        impl: DeviceItemActionInteractorImpl
+    ): DeviceItemActionInteractor
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
index 4369f3f..94f465d 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModel.kt
@@ -62,6 +62,7 @@
 @Inject
 constructor(
     private val deviceItemInteractor: DeviceItemInteractor,
+    private val deviceItemActionInteractor: DeviceItemActionInteractor,
     private val bluetoothStateInteractor: BluetoothStateInteractor,
     private val bluetoothAutoOnInteractor: BluetoothAutoOnInteractor,
     private val audioSharingInteractor: AudioSharingInteractor,
@@ -192,7 +193,7 @@
 
                 // deviceItemClick is emitted when user clicked on a device item.
                 dialogDelegate.deviceItemClick
-                    .onEach { deviceItemInteractor.updateDeviceItemOnClick(it) }
+                    .onEach { deviceItemActionInteractor.onClick(it, dialog) }
                     .launchIn(this)
 
                 // contentHeight is emitted when the dialog is dismissed.
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractor.kt
new file mode 100644
index 0000000..9311760
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractor.kt
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth.qsdialog
+
+import com.android.internal.logging.UiEventLogger
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.withContext
+
+/** Defines interface for click handling of a DeviceItem. */
+interface DeviceItemActionInteractor {
+    suspend fun onClick(deviceItem: DeviceItem, dialog: SystemUIDialog)
+}
+
+@SysUISingleton
+open class DeviceItemActionInteractorImpl
+@Inject
+constructor(
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val logger: BluetoothTileDialogLogger,
+    private val uiEventLogger: UiEventLogger,
+) : DeviceItemActionInteractor {
+
+    override suspend fun onClick(deviceItem: DeviceItem, dialog: SystemUIDialog) {
+        withContext(backgroundDispatcher) {
+            logger.logDeviceClick(deviceItem.cachedBluetoothDevice.address, deviceItem.type)
+
+            deviceItem.cachedBluetoothDevice.apply {
+                when (deviceItem.type) {
+                    DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE -> {
+                        disconnect()
+                        uiEventLogger.log(BluetoothTileDialogUiEvent.ACTIVE_DEVICE_DISCONNECT)
+                    }
+                    DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> {
+                        uiEventLogger.log(BluetoothTileDialogUiEvent.AUDIO_SHARING_DEVICE_CLICKED)
+                    }
+                    DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> {
+                        setActive()
+                        uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_DEVICE_SET_ACTIVE)
+                    }
+                    DeviceItemType.CONNECTED_BLUETOOTH_DEVICE -> {
+                        disconnect()
+                        uiEventLogger.log(
+                            BluetoothTileDialogUiEvent.CONNECTED_OTHER_DEVICE_DISCONNECT
+                        )
+                    }
+                    DeviceItemType.SAVED_BLUETOOTH_DEVICE -> {
+                        connect()
+                        uiEventLogger.log(BluetoothTileDialogUiEvent.SAVED_DEVICE_CONNECT)
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
index 66e593b..1526cd9 100644
--- a/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractor.kt
@@ -20,7 +20,6 @@
 import android.bluetooth.BluetoothDevice
 import android.content.Context
 import android.media.AudioManager
-import com.android.internal.logging.UiEventLogger
 import com.android.settingslib.bluetooth.BluetoothCallback
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
 import com.android.settingslib.bluetooth.LocalBluetoothManager
@@ -52,7 +51,6 @@
     private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter(),
     private val localBluetoothManager: LocalBluetoothManager?,
     private val systemClock: SystemClock,
-    private val uiEventLogger: UiEventLogger,
     private val logger: BluetoothTileDialogLogger,
     @Application private val coroutineScope: CoroutineScope,
     @Background private val backgroundDispatcher: CoroutineDispatcher,
@@ -169,38 +167,6 @@
         )
     }
 
-    internal suspend fun updateDeviceItemOnClick(deviceItem: DeviceItem) {
-        withContext(backgroundDispatcher) {
-            logger.logDeviceClick(deviceItem.cachedBluetoothDevice.address, deviceItem.type)
-
-            deviceItem.cachedBluetoothDevice.apply {
-                when (deviceItem.type) {
-                    DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE -> {
-                        disconnect()
-                        uiEventLogger.log(BluetoothTileDialogUiEvent.ACTIVE_DEVICE_DISCONNECT)
-                    }
-                    DeviceItemType.AUDIO_SHARING_MEDIA_BLUETOOTH_DEVICE -> {
-                        uiEventLogger.log(BluetoothTileDialogUiEvent.AUDIO_SHARING_DEVICE_CLICKED)
-                    }
-                    DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE -> {
-                        setActive()
-                        uiEventLogger.log(BluetoothTileDialogUiEvent.CONNECTED_DEVICE_SET_ACTIVE)
-                    }
-                    DeviceItemType.CONNECTED_BLUETOOTH_DEVICE -> {
-                        disconnect()
-                        uiEventLogger.log(
-                            BluetoothTileDialogUiEvent.CONNECTED_OTHER_DEVICE_DISCONNECT
-                        )
-                    }
-                    DeviceItemType.SAVED_BLUETOOTH_DEVICE -> {
-                        connect()
-                        uiEventLogger.log(BluetoothTileDialogUiEvent.SAVED_DEVICE_CONNECT)
-                    }
-                }
-            }
-        }
-    }
-
     internal fun setDeviceItemFactoryListForTesting(list: List<DeviceItemFactory>) {
         deviceItemFactoryList = list
     }
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
index fa19bf4..e0334a0 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/domain/interactor/AlternateBouncerInteractor.kt
@@ -29,7 +29,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.plugins.statusbar.StatusBarStateController
 import com.android.systemui.statusbar.policy.KeyguardStateController
-import com.android.systemui.util.kotlin.BooleanFlowOperators.or
+import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import com.android.systemui.util.time.SystemClock
 import dagger.Lazy
 import javax.inject.Inject
@@ -78,7 +78,7 @@
             bouncerRepository.alternateBouncerUIAvailable
         }
     private val isDozingOrAod: Flow<Boolean> =
-        or(
+        anyOf(
                 keyguardTransitionInteractor.get().transitionValue(KeyguardState.DOZING).map {
                     it > 0f
                 },
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index fc7f513..b42a903 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -206,7 +206,7 @@
         );
         final CommunalInteractor communalInteractor = mCommunalInteractorLazy.get();
         mJavaAdapter.alwaysCollectFlow(
-                BooleanFlowOperators.INSTANCE.and(
+                BooleanFlowOperators.INSTANCE.allOf(
                         communalInteractor.isCommunalEnabled(),
                         communalInteractor.isCommunalShowing()),
                 this::onShowingCommunalHubChanged
diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
index 0042915..5091a99 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/domain/interactor/CommunalInteractor.kt
@@ -60,9 +60,9 @@
 import com.android.systemui.scene.shared.model.Scenes
 import com.android.systemui.settings.UserTracker
 import com.android.systemui.smartspace.data.repository.SmartspaceRepository
-import com.android.systemui.util.kotlin.BooleanFlowOperators.and
+import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
+import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import com.android.systemui.util.kotlin.BooleanFlowOperators.not
-import com.android.systemui.util.kotlin.BooleanFlowOperators.or
 import com.android.systemui.util.kotlin.emitOnStart
 import javax.inject.Inject
 import kotlinx.coroutines.CoroutineDispatcher
@@ -127,10 +127,10 @@
 
     /** Whether communal features are enabled and available. */
     val isCommunalAvailable: Flow<Boolean> =
-        and(
+        allOf(
                 communalSettingsInteractor.isCommunalEnabled,
                 not(keyguardInteractor.isEncryptedOrLockdown),
-                or(keyguardInteractor.isKeyguardShowing, keyguardInteractor.isDreaming)
+                anyOf(keyguardInteractor.isKeyguardShowing, keyguardInteractor.isDreaming)
             )
             .distinctUntilChanged()
             .onEach { available ->
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 8390d62..2ccab07 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/widgets/CommunalAppWidgetHostStartable.kt
@@ -23,7 +23,7 @@
 import com.android.systemui.dagger.qualifiers.Background
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.settings.UserTracker
-import com.android.systemui.util.kotlin.BooleanFlowOperators.or
+import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import com.android.systemui.util.kotlin.pairwise
 import com.android.systemui.util.kotlin.sample
 import javax.inject.Inject
@@ -46,7 +46,7 @@
 ) : CoreStartable {
 
     override fun start() {
-        or(communalInteractor.isCommunalAvailable, communalInteractor.editModeOpen)
+        anyOf(communalInteractor.isCommunalAvailable, communalInteractor.editModeOpen)
             // Only trigger updates on state changes, ignoring the initial false value.
             .pairwise(false)
             .filter { (previous, new) -> previous != new }
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
index c6fb4f9..fc9406b 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardModule.kt
@@ -19,12 +19,13 @@
 
 import com.android.systemui.keyboard.data.repository.KeyboardRepository
 import com.android.systemui.keyboard.data.repository.KeyboardRepositoryImpl
+import com.android.systemui.keyboard.shortcut.ShortcutHelperModule
 import com.android.systemui.keyboard.stickykeys.data.repository.StickyKeysRepository
 import com.android.systemui.keyboard.stickykeys.data.repository.StickyKeysRepositoryImpl
 import dagger.Binds
 import dagger.Module
 
-@Module
+@Module(includes = [ShortcutHelperModule::class])
 abstract class KeyboardModule {
 
     @Binds
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
new file mode 100644
index 0000000..5635f80
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperModule.kt
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut
+
+import android.app.Activity
+import com.android.systemui.CoreStartable
+import com.android.systemui.Flags.keyboardShortcutHelperRewrite
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperRepository
+import com.android.systemui.keyboard.shortcut.ui.ShortcutHelperActivityStarter
+import com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity
+import dagger.Binds
+import dagger.Lazy
+import dagger.Module
+import dagger.Provides
+import dagger.multibindings.ClassKey
+import dagger.multibindings.IntoMap
+
+@Module
+interface ShortcutHelperModule {
+
+    @Binds
+    @IntoMap
+    @ClassKey(ShortcutHelperActivity::class)
+    fun activity(impl: ShortcutHelperActivity): Activity
+
+    companion object {
+        @Provides
+        @IntoMap
+        @ClassKey(ShortcutHelperActivityStarter::class)
+        fun starter(implLazy: Lazy<ShortcutHelperActivityStarter>): CoreStartable {
+            return if (keyboardShortcutHelperRewrite()) {
+                implLazy.get()
+            } else {
+                // No-op implementation when the flag is disabled.
+                NoOpStartable
+            }
+        }
+
+        @Provides
+        @IntoMap
+        @ClassKey(ShortcutHelperRepository::class)
+        fun repo(implLazy: Lazy<ShortcutHelperRepository>): CoreStartable {
+            return if (keyboardShortcutHelperRewrite()) {
+                implLazy.get()
+            } else {
+                // No-op implementation when the flag is disabled.
+                NoOpStartable
+            }
+        }
+    }
+}
+
+private object NoOpStartable : CoreStartable {
+    override fun start() {}
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperRepository.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperRepository.kt
new file mode 100644
index 0000000..9450af4
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperRepository.kt
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.keyboard.shortcut.data.repository
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import com.android.systemui.CoreStartable
+import com.android.systemui.broadcast.BroadcastDispatcher
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Active
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState.Inactive
+import com.android.systemui.statusbar.CommandQueue
+import javax.inject.Inject
+import kotlinx.coroutines.flow.MutableStateFlow
+
+@SysUISingleton
+class ShortcutHelperRepository
+@Inject
+constructor(
+    private val commandQueue: CommandQueue,
+    private val broadcastDispatcher: BroadcastDispatcher,
+) : CoreStartable {
+
+    val state = MutableStateFlow<ShortcutHelperState>(Inactive)
+
+    override fun start() {
+        registerBroadcastReceiver(
+            action = Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS,
+            onReceive = { state.value = Active() }
+        )
+        registerBroadcastReceiver(
+            action = Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS,
+            onReceive = { state.value = Inactive }
+        )
+        commandQueue.addCallback(
+            object : CommandQueue.Callbacks {
+                override fun dismissKeyboardShortcutsMenu() {
+                    state.value = Inactive
+                }
+
+                override fun toggleKeyboardShortcutsMenu(deviceId: Int) {
+                    state.value =
+                        if (state.value is Inactive) {
+                            Active(deviceId)
+                        } else {
+                            Inactive
+                        }
+                }
+            }
+        )
+    }
+
+    fun hide() {
+        state.value = Inactive
+    }
+
+    private fun registerBroadcastReceiver(action: String, onReceive: () -> Unit) {
+        broadcastDispatcher.registerReceiver(
+            receiver =
+                object : BroadcastReceiver() {
+                    override fun onReceive(context: Context, intent: Intent) {
+                        onReceive()
+                    }
+                },
+            filter = IntentFilter(action),
+            flags = Context.RECEIVER_EXPORTED or Context.RECEIVER_VISIBLE_TO_INSTANT_APPS
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperInteractor.kt
new file mode 100644
index 0000000..d3f7e24
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/domain/interactor/ShortcutHelperInteractor.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperRepository
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
+import javax.inject.Inject
+import kotlinx.coroutines.flow.Flow
+
+@SysUISingleton
+class ShortcutHelperInteractor
+@Inject
+constructor(private val repository: ShortcutHelperRepository) {
+
+    val state: Flow<ShortcutHelperState> = repository.state
+
+    fun onUserLeave() {
+        repository.hide()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutHelperState.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutHelperState.kt
new file mode 100644
index 0000000..d22d6c8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/shared/model/ShortcutHelperState.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.shared.model
+
+sealed interface ShortcutHelperState {
+    data object Inactive : ShortcutHelperState
+
+    data class Active(val deviceId: Int? = null) : ShortcutHelperState
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarter.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarter.kt
new file mode 100644
index 0000000..fbf52e7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarter.kt
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.ui
+
+import android.content.Context
+import android.content.Intent
+import com.android.systemui.CoreStartable
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity
+import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutHelperViewModel
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.launch
+
+@SysUISingleton
+class ShortcutHelperActivityStarter(
+    private val context: Context,
+    @Application private val applicationScope: CoroutineScope,
+    private val viewModel: ShortcutHelperViewModel,
+    private val startActivity: (Intent) -> Unit,
+) : CoreStartable {
+
+    @Inject
+    constructor(
+        context: Context,
+        @Application applicationScope: CoroutineScope,
+        viewModel: ShortcutHelperViewModel,
+    ) : this(
+        context,
+        applicationScope,
+        viewModel,
+        startActivity = { intent -> context.startActivity(intent) }
+    )
+
+    override fun start() {
+        applicationScope.launch {
+            viewModel.shouldShow.collect { shouldShow ->
+                if (shouldShow) {
+                    startShortcutHelperActivity()
+                }
+            }
+        }
+    }
+
+    private fun startShortcutHelperActivity() {
+        startActivity(
+            Intent(context, ShortcutHelperActivity::class.java)
+                .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+        )
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperActivity.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
similarity index 86%
rename from packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperActivity.kt
rename to packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
index 692fbb0..934f9ee 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ShortcutHelperActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/view/ShortcutHelperActivity.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package com.android.systemui.keyboard.shortcut
+package com.android.systemui.keyboard.shortcut.ui.view
 
 import android.graphics.Insets
 import android.os.Bundle
@@ -24,16 +24,25 @@
 import androidx.activity.ComponentActivity
 import androidx.activity.OnBackPressedCallback
 import androidx.core.view.updatePadding
+import androidx.lifecycle.flowWithLifecycle
+import androidx.lifecycle.lifecycleScope
+import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutHelperViewModel
 import com.android.systemui.res.R
 import com.google.android.material.bottomsheet.BottomSheetBehavior
 import com.google.android.material.bottomsheet.BottomSheetBehavior.BottomSheetCallback
 import com.google.android.material.bottomsheet.BottomSheetBehavior.STATE_HIDDEN
+import javax.inject.Inject
+import kotlinx.coroutines.launch
 
 /**
  * Activity that hosts the new version of the keyboard shortcut helper. It will be used both for
  * small and large screen devices.
  */
-class ShortcutHelperActivity : ComponentActivity() {
+class ShortcutHelperActivity
+@Inject
+constructor(
+    private val viewModel: ShortcutHelperViewModel,
+) : ComponentActivity() {
 
     private val bottomSheetContainer
         get() = requireViewById<View>(R.id.shortcut_helper_sheet_container)
@@ -53,6 +62,24 @@
         setUpPredictiveBack()
         setUpSheetDismissListener()
         setUpDismissOnTouchOutside()
+        observeFinishRequired()
+    }
+
+    override fun onDestroy() {
+        super.onDestroy()
+        if (isFinishing) {
+            viewModel.onUserLeave()
+        }
+    }
+
+    private fun observeFinishRequired() {
+        lifecycleScope.launch {
+            viewModel.shouldShow.flowWithLifecycle(lifecycle).collect { shouldShow ->
+                if (!shouldShow) {
+                    finish()
+                }
+            }
+        }
     }
 
     private fun setupEdgeToEdge() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
new file mode 100644
index 0000000..7e48c65
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModel.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.ui.viewmodel
+
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperInteractor
+import com.android.systemui.keyboard.shortcut.shared.model.ShortcutHelperState
+import javax.inject.Inject
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flowOn
+import kotlinx.coroutines.flow.map
+
+class ShortcutHelperViewModel
+@Inject
+constructor(
+    @Background private val backgroundDispatcher: CoroutineDispatcher,
+    private val interactor: ShortcutHelperInteractor
+) {
+
+    val shouldShow =
+        interactor.state
+            .map { it is ShortcutHelperState.Active }
+            .distinctUntilChanged()
+            .flowOn(backgroundDispatcher)
+
+    fun onUserLeave() {
+        interactor.onUserLeave()
+    }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
index 54d9a78..faab033 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGlanceableHubTransitionInteractor.kt
@@ -28,7 +28,7 @@
 import com.android.systemui.keyguard.shared.model.KeyguardState
 import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
 import com.android.systemui.power.domain.interactor.PowerInteractor
-import com.android.systemui.util.kotlin.BooleanFlowOperators.and
+import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
 import com.android.systemui.util.kotlin.BooleanFlowOperators.not
 import javax.inject.Inject
 import kotlin.time.Duration.Companion.seconds
@@ -148,7 +148,7 @@
             }
         } else {
             scope.launch {
-                and(keyguardInteractor.isKeyguardOccluded, not(keyguardInteractor.isDreaming))
+                allOf(keyguardInteractor.isKeyguardOccluded, not(keyguardInteractor.isDreaming))
                     .filterRelevantKeyguardStateAnd { isOccludedAndNotDreaming ->
                         isOccludedAndNotDreaming
                     }
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
index 24a7c51..bbcea56 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt
@@ -42,7 +42,7 @@
 import com.android.systemui.statusbar.notification.domain.interactor.NotificationsKeyguardInteractor
 import com.android.systemui.statusbar.phone.DozeParameters
 import com.android.systemui.statusbar.phone.ScreenOffAnimationController
-import com.android.systemui.util.kotlin.BooleanFlowOperators.or
+import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import com.android.systemui.util.kotlin.pairwise
 import com.android.systemui.util.kotlin.sample
 import com.android.systemui.util.ui.AnimatableEvent
@@ -64,7 +64,6 @@
 import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.merge
 import kotlinx.coroutines.flow.onStart
-import kotlinx.coroutines.launch
 
 @OptIn(ExperimentalCoroutinesApi::class)
 @SysUISingleton
@@ -134,7 +133,7 @@
     private val isOnLockscreen: Flow<Boolean> =
         combine(
                 keyguardTransitionInteractor.isFinishedInState(LOCKSCREEN).onStart { emit(false) },
-                or(
+                anyOf(
                     keyguardTransitionInteractor.isInTransitionToState(LOCKSCREEN),
                     keyguardTransitionInteractor.isInTransitionFromState(LOCKSCREEN),
                 ),
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index b705a03..ea89be6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -21,6 +21,7 @@
 import android.content.Context;
 import android.os.Handler;
 
+import com.android.systemui.bluetooth.qsdialog.BluetoothTileDialogModule;
 import com.android.systemui.dagger.NightDisplayListenerModule;
 import com.android.systemui.dagger.SysUISingleton;
 import com.android.systemui.dagger.qualifiers.Background;
@@ -60,6 +61,7 @@
  */
 @Module(subcomponents = {QSFragmentComponent.class, QSSceneComponent.class},
         includes = {
+                BluetoothTileDialogModule.class,
                 MediaModule.class,
                 PanelsModule.class,
                 QSExternalModule.class,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 76bd80f..faf2bbc 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -707,7 +707,8 @@
             public void moveFocusedTaskToStageSplit(int displayId, boolean leftOrTop) {
                 if (mOverviewProxy != null) {
                     try {
-                        if (DesktopModeStatus.isEnabled() && (sysUiState.getFlags()
+                        if (DesktopModeStatus.canEnterDesktopMode(mContext)
+                                && (sysUiState.getFlags()
                                 & SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE) != 0) {
                             return;
                         }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 494fc9b..bd90de2 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -47,7 +47,6 @@
 import android.graphics.Bitmap;
 import android.graphics.Insets;
 import android.graphics.Rect;
-import android.hardware.display.DisplayManager;
 import android.net.Uri;
 import android.os.Process;
 import android.os.UserHandle;
@@ -208,8 +207,7 @@
     @Nullable
     private final ScreenshotSoundController mScreenshotSoundController;
     private final PhoneWindow mWindow;
-    private final DisplayManager mDisplayManager;
-    private final int mDisplayId;
+    private final Display mDisplay;
     private final ScrollCaptureExecutor mScrollCaptureExecutor;
     private final ScreenshotNotificationSmartActionsProvider
             mScreenshotNotificationSmartActionsProvider;
@@ -249,7 +247,6 @@
     @AssistedInject
     ScreenshotController(
             Context context,
-            DisplayManager displayManager,
             WindowManager windowManager,
             FeatureFlags flags,
             ScreenshotViewProxy.Factory viewProxyFactory,
@@ -271,12 +268,13 @@
             AssistContentRequester assistContentRequester,
             MessageContainerController messageContainerController,
             Provider<ScreenshotSoundController> screenshotSoundController,
-            @Assisted int displayId,
+            @Assisted Display display,
             @Assisted boolean showUIOnExternalDisplay
     ) {
         mScreenshotSmartActions = screenshotSmartActions;
         mActionsProviderFactory = actionsProviderFactory;
-        mNotificationsController = screenshotNotificationsControllerFactory.create(displayId);
+        mNotificationsController = screenshotNotificationsControllerFactory.create(
+                display.getDisplayId());
         mUiEventLogger = uiEventLogger;
         mImageExporter = imageExporter;
         mImageCapture = imageCapture;
@@ -290,11 +288,9 @@
         mScreenshotHandler = timeoutHandler;
         mScreenshotHandler.setDefaultTimeoutMillis(SCREENSHOT_CORNER_DEFAULT_TIMEOUT_MILLIS);
 
-
-        mDisplayId = displayId;
-        mDisplayManager = displayManager;
+        mDisplay = display;
         mWindowManager = windowManager;
-        final Context displayContext = context.createDisplayContext(getDisplay());
+        final Context displayContext = context.createDisplayContext(display);
         mContext = (WindowContext) displayContext.createWindowContext(TYPE_SCREENSHOT, null);
         mFlags = flags;
         mActionIntentExecutor = actionIntentExecutor;
@@ -302,7 +298,7 @@
         mMessageContainerController = messageContainerController;
         mAssistContentRequester = assistContentRequester;
 
-        mViewProxy = viewProxyFactory.getProxy(mContext, mDisplayId);
+        mViewProxy = viewProxyFactory.getProxy(mContext, mDisplay.getDisplayId());
 
         mScreenshotHandler.setOnTimeoutRunnable(() -> {
             if (DEBUG_UI) {
@@ -328,7 +324,7 @@
                 });
 
         // Sound is only reproduced from the controller of the default display.
-        if (displayId == Display.DEFAULT_DISPLAY) {
+        if (mDisplay.getDisplayId() == Display.DEFAULT_DISPLAY) {
             mScreenshotSoundController = screenshotSoundController.get();
         } else {
             mScreenshotSoundController = null;
@@ -356,7 +352,7 @@
         if (screenshot.getType() == WindowManager.TAKE_SCREENSHOT_FULLSCREEN
                 && screenshot.getBitmap() == null) {
             Rect bounds = getFullScreenRect();
-            screenshot.setBitmap(mImageCapture.captureDisplay(mDisplayId, bounds));
+            screenshot.setBitmap(mImageCapture.captureDisplay(mDisplay.getDisplayId(), bounds));
             screenshot.setScreenBounds(bounds);
         }
 
@@ -459,7 +455,7 @@
     }
 
     private boolean shouldShowUi() {
-        return mDisplayId == Display.DEFAULT_DISPLAY || mShowUIOnExternalDisplay;
+        return mDisplay.getDisplayId() == Display.DEFAULT_DISPLAY || mShowUIOnExternalDisplay;
     }
 
     void prepareViewForNewScreenshot(@NonNull ScreenshotData screenshot, String oldPackageName) {
@@ -618,7 +614,7 @@
 
     private void requestScrollCapture(UserHandle owner) {
         mScrollCaptureExecutor.requestScrollCapture(
-                mDisplayId,
+                mDisplay.getDisplayId(),
                 mWindow.getDecorView().getWindowToken(),
                 (response) -> {
                     mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_IMPRESSION,
@@ -641,7 +637,8 @@
         }
         mUiEventLogger.log(ScreenshotEvent.SCREENSHOT_LONG_SCREENSHOT_REQUESTED, 0,
                 response.getPackageName());
-        Bitmap newScreenshot = mImageCapture.captureDisplay(mDisplayId, getFullScreenRect());
+        Bitmap newScreenshot = mImageCapture.captureDisplay(mDisplay.getDisplayId(),
+                getFullScreenRect());
         if (newScreenshot == null) {
             Log.e(TAG, "Failed to capture current screenshot for scroll transition!");
             return;
@@ -819,7 +816,8 @@
     private void saveScreenshotInBackground(
             ScreenshotData screenshot, UUID requestId, Consumer<Uri> finisher) {
         ListenableFuture<ImageExporter.Result> future = mImageExporter.export(mBgExecutor,
-                requestId, screenshot.getBitmap(), screenshot.getUserOrDefault(), mDisplayId);
+                requestId, screenshot.getBitmap(), screenshot.getUserOrDefault(),
+                mDisplay.getDisplayId());
         future.addListener(() -> {
             try {
                 ImageExporter.Result result = future.get();
@@ -861,7 +859,7 @@
         data.mActionsReadyListener = actionsReadyListener;
         data.mQuickShareActionsReadyListener = quickShareActionsReadyListener;
         data.owner = owner;
-        data.displayId = mDisplayId;
+        data.displayId = mDisplay.getDisplayId();
 
         if (mSaveInBgTask != null) {
             // just log success/failure for the pre-existing screenshot
@@ -986,13 +984,9 @@
         }
     }
 
-    private Display getDisplay() {
-        return mDisplayManager.getDisplay(mDisplayId);
-    }
-
     private Rect getFullScreenRect() {
         DisplayMetrics displayMetrics = new DisplayMetrics();
-        getDisplay().getRealMetrics(displayMetrics);
+        mDisplay.getRealMetrics(displayMetrics);
         return new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
     }
 
@@ -1026,12 +1020,12 @@
     @AssistedFactory
     public interface Factory {
         /**
-         * Creates an instance of the controller for that specific displayId.
+         * Creates an instance of the controller for that specific display.
          *
-         * @param displayId:               display to capture
-         * @param showUIOnExternalDisplay: Whether the UI should be shown if this is an external
-         *                                 display.
+         * @param display                 display to capture
+         * @param showUIOnExternalDisplay Whether the UI should be shown if this is an external
+         *                                display.
          */
-        ScreenshotController create(int displayId, boolean showUIOnExternalDisplay);
+        ScreenshotController create(Display display, boolean showUIOnExternalDisplay);
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
index e56a4f4..40d709d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/TakeScreenshotExecutor.kt
@@ -68,11 +68,13 @@
         onSaved: (Uri?) -> Unit,
         requestCallback: RequestCallback
     ) {
-        val displayIds = getDisplaysToScreenshot(screenshotRequest.type)
+        val displays = getDisplaysToScreenshot(screenshotRequest.type)
         val resultCallbackWrapper = MultiResultCallbackWrapper(requestCallback)
-        displayIds.forEach { displayId: Int ->
+        displays.forEach { display ->
+            val displayId = display.displayId
             Log.d(TAG, "Executing screenshot for display $displayId")
             dispatchToController(
+                display = display,
                 rawScreenshotData = ScreenshotData.fromRequest(screenshotRequest, displayId),
                 onSaved =
                     if (displayId == Display.DEFAULT_DISPLAY) {
@@ -85,6 +87,7 @@
 
     /** All logging should be triggered only by this method. */
     private suspend fun dispatchToController(
+        display: Display,
         rawScreenshotData: ScreenshotData,
         onSaved: (Uri?) -> Unit,
         callback: RequestCallback
@@ -104,8 +107,7 @@
         logScreenshotRequested(screenshotData)
         Log.d(TAG, "Screenshot request: $screenshotData")
         try {
-            getScreenshotController(screenshotData.displayId)
-                .handleScreenshot(screenshotData, onSaved, callback)
+            getScreenshotController(display).handleScreenshot(screenshotData, onSaved, callback)
         } catch (e: IllegalStateException) {
             Log.e(TAG, "Error while ScreenshotController was handling ScreenshotData!", e)
             onFailedScreenshotRequest(screenshotData, callback)
@@ -135,12 +137,13 @@
         callback.reportError()
     }
 
-    private suspend fun getDisplaysToScreenshot(requestType: Int): List<Int> {
+    private suspend fun getDisplaysToScreenshot(requestType: Int): List<Display> {
+        val allDisplays = displays.first()
         return if (requestType == TAKE_SCREENSHOT_PROVIDED_IMAGE) {
             // If this is a provided image, let's show the UI on the default display only.
-            listOf(Display.DEFAULT_DISPLAY)
+            allDisplays.filter { it.displayId == Display.DEFAULT_DISPLAY }
         } else {
-            displays.first().filter { it.type in ALLOWED_DISPLAY_TYPES }.map { it.displayId }
+            allDisplays.filter { it.type in ALLOWED_DISPLAY_TYPES }
         }
     }
 
@@ -170,9 +173,9 @@
         screenshotControllers.clear()
     }
 
-    private fun getScreenshotController(id: Int): ScreenshotController {
-        return screenshotControllers.computeIfAbsent(id) {
-            screenshotControllerFactory.create(id, /* showUIOnExternalDisplay= */ false)
+    private fun getScreenshotController(display: Display): ScreenshotController {
+        return screenshotControllers.computeIfAbsent(display.displayId) {
+            screenshotControllerFactory.create(display, /* showUIOnExternalDisplay= */ false)
         }
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
index 281857f..6367d44b 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/GlanceableHubContainerController.kt
@@ -51,9 +51,9 @@
 import com.android.systemui.scene.shared.model.SceneDataSourceDelegator
 import com.android.systemui.shade.domain.interactor.ShadeInteractor
 import com.android.systemui.statusbar.phone.SystemUIDialogFactory
-import com.android.systemui.util.kotlin.BooleanFlowOperators.and
+import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
+import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import com.android.systemui.util.kotlin.BooleanFlowOperators.not
-import com.android.systemui.util.kotlin.BooleanFlowOperators.or
 import com.android.systemui.util.kotlin.collectFlow
 import javax.inject.Inject
 import kotlinx.coroutines.flow.Flow
@@ -145,7 +145,7 @@
 
     /** Returns a flow that tracks whether communal hub is available. */
     fun communalAvailable(): Flow<Boolean> =
-        or(communalInteractor.isCommunalAvailable, communalInteractor.editModeOpen)
+        anyOf(communalInteractor.isCommunalAvailable, communalInteractor.editModeOpen)
 
     /**
      * Creates the container view containing the glanceable hub UI.
@@ -248,7 +248,7 @@
         // transition to the bouncer would be incorrectly intercepted by the hub.
         collectFlow(
             containerView,
-            or(
+            anyOf(
                 keyguardInteractor.primaryBouncerShowing,
                 keyguardInteractor.alternateBouncerShowing
             ),
@@ -267,7 +267,7 @@
         )
         collectFlow(
             containerView,
-            and(shadeInteractor.isAnyFullyExpanded, not(shadeInteractor.isUserInteracting)),
+            allOf(shadeInteractor.isAnyFullyExpanded, not(shadeInteractor.isUserInteracting)),
             {
                 shadeShowing = it
                 updateTouchHandlingState()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index 1f1251a..0ba7b3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -68,8 +68,8 @@
 import com.android.systemui.statusbar.notification.stack.domain.interactor.NotificationStackAppearanceInteractor
 import com.android.systemui.statusbar.notification.stack.domain.interactor.SharedNotificationContainerInteractor
 import com.android.systemui.unfold.domain.interactor.UnfoldTransitionInteractor
-import com.android.systemui.util.kotlin.BooleanFlowOperators.and
-import com.android.systemui.util.kotlin.BooleanFlowOperators.or
+import com.android.systemui.util.kotlin.BooleanFlowOperators.allOf
+import com.android.systemui.util.kotlin.BooleanFlowOperators.anyOf
 import com.android.systemui.util.kotlin.FlowDumperImpl
 import com.android.systemui.util.kotlin.Utils.Companion.sample as sampleCombine
 import javax.inject.Inject
@@ -246,7 +246,7 @@
                 keyguardTransitionInteractor.finishedKeyguardState.map { state ->
                     state == GLANCEABLE_HUB
                 },
-                or(
+                anyOf(
                     keyguardTransitionInteractor.isInTransitionToState(GLANCEABLE_HUB),
                     keyguardTransitionInteractor.isInTransitionFromState(GLANCEABLE_HUB),
                 ),
@@ -424,14 +424,14 @@
                 while (currentCoroutineContext().isActive) {
                     emit(false)
                     // Ensure states are inactive to start
-                    and(
+                    allOf(
                             *toFlowArray(statesForHiddenKeyguard) { state ->
                                 keyguardTransitionInteractor.transitionValue(state).map { it == 0f }
                             }
                         )
                         .first { it }
                     // Wait for a qualifying transition to begin
-                    or(
+                    anyOf(
                             *toFlowArray(statesForHiddenKeyguard) { state ->
                                 keyguardTransitionInteractor
                                     .transitionStepsToState(state)
@@ -446,7 +446,7 @@
                     // it is considered safe to reset alpha to 1f for HUNs.
                     combine(
                             keyguardInteractor.statusBarState,
-                            and(
+                            allOf(
                                 *toFlowArray(statesForHiddenKeyguard) { state ->
                                     keyguardTransitionInteractor.transitionValue(state).map {
                                         it == 0f
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 226a84a..88ca9e5 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
@@ -229,7 +229,7 @@
         @SysUISingleton
         @OemSatelliteInputLog
         fun provideOemSatelliteInputLog(factory: LogBufferFactory): LogBuffer {
-            return factory.create("DeviceBasedSatelliteInputLog", 32)
+            return factory.create("DeviceBasedSatelliteInputLog", 150)
         }
 
         const val FIRST_MOBILE_SUB_SHOWING_NETWORK_TYPE_ICON =
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
index a7c4187..12f252d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/satellite/data/prod/DeviceBasedSatelliteRepositoryImpl.kt
@@ -249,11 +249,17 @@
                 try {
                     sm.registerForNtnSignalStrengthChanged(bgDispatcher.asExecutor(), cb)
                     registered = true
+                    logBuffer.i { "Registered for signal strength successfully" }
                 } catch (e: Exception) {
                     logBuffer.e("error registering for signal strength", e)
                 }
 
-                awaitClose { if (registered) sm.unregisterForNtnSignalStrengthChanged(cb) }
+                awaitClose {
+                    if (registered) {
+                        sm.unregisterForNtnSignalStrengthChanged(cb)
+                        logBuffer.i { "Unregistered for signal strength successfully" }
+                    }
+                }
             }
             .flowOn(bgDispatcher)
 
diff --git a/packages/SystemUI/src/com/android/systemui/theme/CustomDynamicColors.java b/packages/SystemUI/src/com/android/systemui/theme/CustomDynamicColors.java
deleted file mode 100644
index efeb2f9..0000000
--- a/packages/SystemUI/src/com/android/systemui/theme/CustomDynamicColors.java
+++ /dev/null
@@ -1,322 +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.theme;
-
-import com.google.ux.material.libmonet.dynamiccolor.ContrastCurve;
-import com.google.ux.material.libmonet.dynamiccolor.DynamicColor;
-import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors;
-import com.google.ux.material.libmonet.dynamiccolor.ToneDeltaPair;
-import com.google.ux.material.libmonet.dynamiccolor.TonePolarity;
-
-class CustomDynamicColors {
-    private final MaterialDynamicColors mMdc;
-
-    CustomDynamicColors(boolean isExtendedFidelity) {
-        this.mMdc = new MaterialDynamicColors(isExtendedFidelity);
-    }
-
-    // CLOCK COLORS
-
-    public DynamicColor widgetBackground() {
-        return new DynamicColor(
-                /* name= */ "widget_background",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> s.isDark ? 20.0 : 95.0,
-                /* isBackground= */ true,
-                /* background= */ null,
-                /* secondBackground= */ null,
-                /* contrastCurve= */ null,
-                /* toneDeltaPair= */ null);
-    }
-
-    public DynamicColor clockHour() {
-        return new DynamicColor(
-                /* name= */ "clock_hour",
-                /* palette= */ (s) -> s.secondaryPalette,
-                /* tone= */ (s) -> s.isDark ? 30.0 : 60.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> widgetBackground(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 4.0, 5.0, 15.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(clockHour(), clockMinute(), 10.0, TonePolarity.DARKER,
-                        false));
-    }
-
-    public DynamicColor clockMinute() {
-        return new DynamicColor(
-                /* name= */ "clock_minute",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> s.isDark ? 40.0 : 90.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> widgetBackground(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 6.5, 10.0, 15.0),
-                /* toneDeltaPair= */ null);
-    }
-
-    public DynamicColor clockSecond() {
-        return new DynamicColor(
-                /* name= */ "clock_second",
-                /* palette= */ (s) -> s.tertiaryPalette,
-                /* tone= */ (s) -> s.isDark ? 40.0 : 90.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> widgetBackground(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 5.0, 70.0, 11.0),
-                /* toneDeltaPair= */ null);
-    }
-
-    public DynamicColor weatherTemp() {
-        return new DynamicColor(
-                /* name= */ "clock_second",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> s.isDark ? 55.0 : 80.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> widgetBackground(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 5.0, 70.0, 11.0),
-                /* toneDeltaPair= */ null);
-    }
-
-    // THEME APP ICONS
-
-    public DynamicColor themeApp() {
-        return new DynamicColor(
-                /* name= */ "theme_app",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> s.isDark ? 90.0 : 30.0, // Adjusted values
-                /* isBackground= */ true,
-                /* background= */ null,
-                /* secondBackground= */ null,
-                /* contrastCurve= */ null,
-                /* toneDeltaPair= */ null);
-    }
-
-    public DynamicColor onThemeApp() {
-        return new DynamicColor(
-                /* name= */ "on_theme_app",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> s.isDark ? 40.0 : 80.0, // Adjusted values
-                /* isBackground= */ false,
-                /* background= */ (s) -> themeApp(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 7.0, 10.0),
-                /* toneDeltaPair= */ null);
-    }
-
-    public DynamicColor themeAppRing() {
-        return new DynamicColor(
-                /* name= */ "theme_app_ring",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> 70.0,
-                /* isBackground= */ true,
-                /* background= */ null,
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 1.0, 1.0, 1.0),
-                /* toneDeltaPair= */ null);
-    }
-
-    public DynamicColor themeNotif() {
-        return new DynamicColor(
-                /* name= */ "theme_notif",
-                /* palette= */ (s) -> s.tertiaryPalette,
-                /* tone= */ (s) -> s.isDark ? 80.0 : 90.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> themeAppRing(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 1.0, 1.0, 1.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(themeNotif(), themeAppRing(), 10.0, TonePolarity.NEARER,
-                        false));
-    }
-
-    // SUPER G COLORS
-
-    public DynamicColor brandA() {
-        return new DynamicColor(
-                /* name= */ "brand_a",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> s.isDark ? 40.0 : 80.0,
-                /* isBackground= */ true,
-                /* background= */ (s) -> mMdc.surfaceContainerLow(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 7.0, 17.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(brandA(), brandB(), 10.0, TonePolarity.NEARER, false));
-    }
-
-    public DynamicColor brandB() {
-        return new DynamicColor(
-                /* name= */ "brand_b",
-                /* palette= */ (s) -> s.secondaryPalette,
-                /* tone= */ (s) -> s.isDark ? 70.0 : 98.0,
-                /* isBackground= */ true,
-                /* background= */ (s) -> mMdc.surfaceContainerLow(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 3.0, 6.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(brandB(), brandC(), 10.0, TonePolarity.NEARER, false));
-    }
-
-    public DynamicColor brandC() {
-        return new DynamicColor(
-                /* name= */ "brand_c",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> s.isDark ? 50.0 : 60.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> mMdc.surfaceContainerLow(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 4.0, 9.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(brandC(), brandD(), 10.0, TonePolarity.NEARER, false));
-    }
-
-    public DynamicColor brandD() {
-        return new DynamicColor(
-                /* name= */ "brand_d",
-                /* palette= */ (s) -> s.tertiaryPalette,
-                /* tone= */ (s) -> s.isDark ? 59.0 : 90.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> mMdc.surfaceContainerLow(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 4.0, 13.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(brandD(), brandA(), 10.0, TonePolarity.NEARER, false));
-    }
-
-    // QUICK SETTING TIILES
-
-    public DynamicColor underSurface() {
-        return new DynamicColor(
-                /* name= */ "under_surface",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> 0.0,
-                /* isBackground= */ true,
-                /* background= */ null,
-                /* secondBackground= */ null,
-                /* contrastCurve= */ null,
-                /* toneDeltaPair= */ null);
-    }
-
-    public DynamicColor shadeActive() {
-        return new DynamicColor(
-                /* name= */ "shade_active",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> 90.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> underSurface(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 3.0, 4.5, 7.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(shadeActive(), shadeInactive(), 30.0, TonePolarity.LIGHTER,
-                        false));
-    }
-
-    public DynamicColor onShadeActive() {
-        return new DynamicColor(
-                /* name= */ "on_shade_active",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> 10.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> shadeActive(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 4.5, 7.0, 11.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(onShadeActive(), onShadeActiveVariant(), 20.0,
-                        TonePolarity.NEARER, false));
-    }
-
-    public DynamicColor onShadeActiveVariant() {
-        return new DynamicColor(
-                /* name= */ "on_shade_active_variant",
-                /* palette= */ (s) -> s.primaryPalette,
-                /* tone= */ (s) -> 30.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> shadeActive(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 4.5, 7.0, 11.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(onShadeActiveVariant(), onShadeActive(), 20.0,
-                        TonePolarity.NEARER, false));
-    }
-
-    public DynamicColor shadeInactive() {
-        return new DynamicColor(
-                /* name= */ "shade_inactive",
-                /* palette= */ (s) -> s.neutralPalette,
-                /* tone= */ (s) -> 20.0,
-                /* isBackground= */ true,
-                /* background= */ (s) -> underSurface(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 1.0, 1.0, 1.0),
-                /* toneDeltaPair= */(s) -> new ToneDeltaPair(shadeInactive(), shadeDisabled(), 15.0,
-                TonePolarity.LIGHTER, false));
-    }
-
-    public DynamicColor onShadeInactive() {
-        return new DynamicColor(
-                /* name= */ "on_shade_inactive",
-                /* palette= */ (s) -> s.neutralVariantPalette,
-                /* tone= */ (s) -> 90.0,
-                /* isBackground= */ true,
-                /* background= */ (s) -> shadeInactive(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 4.5, 7.0, 11.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(onShadeInactive(), onShadeInactiveVariant(), 10.0,
-                        TonePolarity.NEARER, false));
-    }
-
-    public DynamicColor onShadeInactiveVariant() {
-        return new DynamicColor(
-                /* name= */ "on_shade_inactive_variant",
-                /* palette= */ (s) -> s.neutralVariantPalette,
-                /* tone= */ (s) -> 80.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> shadeInactive(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 4.5, 7.0, 11.0),
-                /* toneDeltaPair= */
-                (s) -> new ToneDeltaPair(onShadeInactiveVariant(), onShadeInactive(), 10.0,
-                        TonePolarity.NEARER, false));
-    }
-
-    public DynamicColor shadeDisabled() {
-        return new DynamicColor(
-                /* name= */ "shade_disabled",
-                /* palette= */ (s) -> s.neutralPalette,
-                /* tone= */ (s) -> 4.0,
-                /* isBackground= */ false,
-                /* background= */ (s) -> underSurface(),
-                /* secondBackground= */ null,
-                /* contrastCurve= */ new ContrastCurve(1.0, 1.0, 1.0, 1.0),
-                /* toneDeltaPair= */ null);
-    }
-
-    public DynamicColor overviewBackground() {
-        return new DynamicColor(
-                /* name= */ "overview_background",
-                /* palette= */ (s) -> s.neutralVariantPalette,
-                /* tone= */ (s) -> s.isDark ? 80.0 : 35.0,
-                /* isBackground= */ true,
-                /* background= */ null,
-                /* secondBackground= */ null,
-                /* contrastCurve= */null,
-                /* toneDeltaPair= */ null);
-    }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
index 3518759..a983d2f 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
+++ b/packages/SystemUI/src/com/android/systemui/theme/DynamicColors.kt
@@ -103,33 +103,5 @@
                 Pair.create("on_tertiary_fixed_variant", mdc.onTertiaryFixedVariant()),
             )
         }
-
-        @JvmStatic
-        fun getCustomColorsMapped(isExtendedFidelity: Boolean): List<Pair<String, DynamicColor>> {
-            val customMdc = CustomDynamicColors(isExtendedFidelity)
-            return arrayListOf(
-                Pair.create("widget_background", customMdc.widgetBackground()),
-                Pair.create("clock_hour", customMdc.clockHour()),
-                Pair.create("clock_minute", customMdc.clockMinute()),
-                Pair.create("clock_second", customMdc.weatherTemp()),
-                Pair.create("theme_app", customMdc.themeApp()),
-                Pair.create("on_theme_app", customMdc.onThemeApp()),
-                Pair.create("theme_app_ring", customMdc.themeAppRing()),
-                Pair.create("on_theme_app_ring", customMdc.themeNotif()),
-                Pair.create("brand_a", customMdc.brandA()),
-                Pair.create("brand_b", customMdc.brandB()),
-                Pair.create("brand_c", customMdc.brandC()),
-                Pair.create("brand_d", customMdc.brandD()),
-                Pair.create("under_surface", customMdc.underSurface()),
-                Pair.create("shade_active", customMdc.shadeActive()),
-                Pair.create("on_shade_active", customMdc.onShadeActive()),
-                Pair.create("on_shade_active_variant", customMdc.onShadeActiveVariant()),
-                Pair.create("shade_inactive", customMdc.shadeInactive()),
-                Pair.create("on_shade_inactive", customMdc.onShadeInactive()),
-                Pair.create("on_shade_inactive_variant", customMdc.onShadeInactiveVariant()),
-                Pair.create("shade_disabled", customMdc.shadeDisabled()),
-                Pair.create("overview_background", customMdc.overviewBackground())
-            )
-        }
     }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index d256c4a..5c3bbb7 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -56,7 +56,6 @@
 import android.util.ArrayMap;
 import android.util.ArraySet;
 import android.util.Log;
-import android.util.Pair;
 import android.util.SparseArray;
 import android.util.SparseIntArray;
 
@@ -85,7 +84,6 @@
 import com.android.systemui.util.kotlin.JavaAdapter;
 import com.android.systemui.util.settings.SecureSettings;
 
-import com.google.ux.material.libmonet.dynamiccolor.DynamicColor;
 import com.google.ux.material.libmonet.dynamiccolor.MaterialDynamicColors;
 
 import org.json.JSONException;
@@ -633,33 +631,29 @@
 
     protected FabricatedOverlay createDynamicOverlay() {
         FabricatedOverlay overlay = newFabricatedOverlay("dynamic");
-        //Themed Colors
-        assignColorsToOverlay(overlay, DynamicColors.allDynamicColorsMapped(mIsFidelityEnabled),
-                false);
-        // Fixed Colors
-        assignColorsToOverlay(overlay, DynamicColors.getFixedColorsMapped(mIsFidelityEnabled),
-                true);
-        //Custom Colors
-        assignColorsToOverlay(overlay, DynamicColors.getCustomColorsMapped(mIsFidelityEnabled),
-                false);
+        assignDynamicPaletteToOverlay(overlay, true /* isDark */);
+        assignDynamicPaletteToOverlay(overlay, false /* isDark */);
+        assignFixedColorsToOverlay(overlay);
         return overlay;
     }
 
-    private void assignColorsToOverlay(FabricatedOverlay overlay,
-            List<Pair<String, DynamicColor>> colors, Boolean isFixed) {
-        colors.forEach(p -> {
-            String prefix = "android:color/system_" + p.first;
+    private void assignDynamicPaletteToOverlay(FabricatedOverlay overlay, boolean isDark) {
+        String suffix = isDark ? "dark" : "light";
+        ColorScheme scheme = isDark ? mDarkColorScheme : mLightColorScheme;
+        DynamicColors.allDynamicColorsMapped(mIsFidelityEnabled).forEach(p -> {
+            String resourceName = "android:color/system_" + p.first + "_" + suffix;
+            int colorValue = p.second.getArgb(scheme.getMaterialScheme());
+            overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue,
+                    null /* configuration */);
+        });
+    }
 
-            if (isFixed) {
-                overlay.setResourceValue(prefix, TYPE_INT_COLOR_ARGB8,
-                        p.second.getArgb(mLightColorScheme.getMaterialScheme()), null);
-                return;
-            }
-
-            overlay.setResourceValue(prefix + "_light", TYPE_INT_COLOR_ARGB8,
-                    p.second.getArgb(mLightColorScheme.getMaterialScheme()), null);
-            overlay.setResourceValue(prefix + "_dark", TYPE_INT_COLOR_ARGB8,
-                    p.second.getArgb(mDarkColorScheme.getMaterialScheme()), null);
+    private void assignFixedColorsToOverlay(FabricatedOverlay overlay) {
+        DynamicColors.getFixedColorsMapped(mIsFidelityEnabled).forEach(p -> {
+            String resourceName = "android:color/system_" + p.first;
+            int colorValue = p.second.getArgb(mLightColorScheme.getMaterialScheme());
+            overlay.setResourceValue(resourceName, TYPE_INT_COLOR_ARGB8, colorValue,
+                    null /* configuration */);
         });
     }
 
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 37be1c6..a817b31 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
@@ -18,6 +18,7 @@
 package com.android.systemui.user.data.repository
 
 import android.annotation.SuppressLint
+import android.annotation.UserIdInt
 import android.content.Context
 import android.content.pm.UserInfo
 import android.os.UserHandle
@@ -107,6 +108,22 @@
     fun isSimpleUserSwitcher(): Boolean
 
     fun isUserSwitcherEnabled(): Boolean
+
+    /**
+     * Returns the user ID of the "main user" of the device. This user may have access to certain
+     * features which are limited to at most one user. There will never be more than one main user
+     * on a device.
+     *
+     * <p>Currently, on most form factors the first human user on the device will be the main user;
+     * in the future, the concept may be transferable, so a different user (or even no user at all)
+     * may be designated the main user instead. On other form factors there might not be a main
+     * user.
+     *
+     * <p> When the device doesn't have a main user, this will return {@code null}.
+     *
+     * @see [UserManager.getMainUser]
+     */
+    @UserIdInt suspend fun getMainUserId(): Int?
 }
 
 @SysUISingleton
@@ -239,6 +256,10 @@
         return _userSwitcherSettings.value.isUserSwitcherEnabled
     }
 
+    override suspend fun getMainUserId(): Int? {
+        return withContext(backgroundDispatcher) { manager.mainUser?.identifier }
+    }
+
     private suspend fun getSettings(): UserSwitcherSettingsModel {
         return withContext(backgroundDispatcher) {
             val isSimpleUserSwitcher =
diff --git a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/SelectedUserInteractor.kt b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/SelectedUserInteractor.kt
index 38b381a..59c819d 100644
--- a/packages/SystemUI/src/com/android/systemui/user/domain/interactor/SelectedUserInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/user/domain/interactor/SelectedUserInteractor.kt
@@ -2,6 +2,7 @@
 
 import android.annotation.UserIdInt
 import android.content.pm.UserInfo
+import android.os.UserManager
 import com.android.keyguard.KeyguardUpdateMonitor
 import com.android.systemui.Flags.refactorGetCurrentUser
 import com.android.systemui.dagger.SysUISingleton
@@ -38,4 +39,23 @@
             KeyguardUpdateMonitor.getCurrentUser()
         }
     }
+
+    /**
+     * Returns the user ID of the "main user" of the device. This user may have access to certain
+     * features which are limited to at most one user. There will never be more than one main user
+     * on a device.
+     *
+     * <p>Currently, on most form factors the first human user on the device will be the main user;
+     * in the future, the concept may be transferable, so a different user (or even no user at all)
+     * may be designated the main user instead. On other form factors there might not be a main
+     * user.
+     *
+     * <p> When the device doesn't have a main user, this will return {@code null}.
+     *
+     * @see [UserManager.getMainUser]
+     */
+    @UserIdInt
+    fun getMainUserId(): Int? {
+        return repository.mainUserId
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/util/kotlin/BooleanFlowOperators.kt b/packages/SystemUI/src/com/android/systemui/util/kotlin/BooleanFlowOperators.kt
index b300885..a2759c6 100644
--- a/packages/SystemUI/src/com/android/systemui/util/kotlin/BooleanFlowOperators.kt
+++ b/packages/SystemUI/src/com/android/systemui/util/kotlin/BooleanFlowOperators.kt
@@ -28,11 +28,23 @@
      *
      * Usage:
      * ```
-     * val result = and(flow1, flow2)
+     * val result = allOf(flow1, flow2)
      * ```
      */
-    fun and(vararg flows: Flow<Boolean>): Flow<Boolean> =
-        combine(flows.asIterable()) { values -> values.all { it } }.distinctUntilChanged()
+    fun allOf(vararg flows: Flow<Boolean>): Flow<Boolean> = flows.asIterable().all()
+
+    /**
+     * Logical AND operator for boolean flows. Will collect all flows and [combine] them to
+     * determine the result.
+     */
+    fun Array<Flow<Boolean>>.all(): Flow<Boolean> = allOf(*this)
+
+    /**
+     * Logical AND operator for boolean flows. Will collect all flows and [combine] them to
+     * determine the result.
+     */
+    fun Iterable<Flow<Boolean>>.all(): Flow<Boolean> =
+        combine(this) { values -> values.all { it } }.distinctUntilChanged()
 
     /**
      * Logical NOT operator for a boolean flow.
@@ -48,6 +60,36 @@
      * Logical OR operator for a boolean flow. Will collect all flows and [combine] them to
      * determine the result.
      */
-    fun or(vararg flows: Flow<Boolean>): Flow<Boolean> =
-        combine(flows.asIterable()) { values -> values.any { it } }.distinctUntilChanged()
+    fun anyOf(vararg flows: Flow<Boolean>): Flow<Boolean> = flows.asIterable().any()
+
+    /**
+     * Logical OR operator for a boolean flow. Will collect all flows and [combine] them to
+     * determine the result.
+     */
+    fun Array<Flow<Boolean>>.any(): Flow<Boolean> = anyOf(*this)
+
+    /**
+     * Logical OR operator for a boolean flow. Will collect all flows and [combine] them to
+     * determine the result.
+     */
+    fun Iterable<Flow<Boolean>>.any(): Flow<Boolean> =
+        combine(this) { values -> values.any { it } }.distinctUntilChanged()
+
+    /**
+     * Returns a Flow that produces `true` when all input flows are producing `false`, otherwise
+     * produces `false`.
+     */
+    fun noneOf(vararg flows: Flow<Boolean>): Flow<Boolean> = not(anyOf(*flows))
+
+    /**
+     * Returns a Flow that produces `true` when all input flows are producing `false`, otherwise
+     * produces `false`.
+     */
+    fun Array<Flow<Boolean>>.none(): Flow<Boolean> = noneOf(*this)
+
+    /**
+     * Returns a Flow that produces `true` when all input flows are producing `false`, otherwise
+     * produces `false`.
+     */
+    fun Iterable<Flow<Boolean>>.none(): Flow<Boolean> = not(any())
 }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
index af1d315..f62a55d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/BluetoothTileDialogViewModelTest.kt
@@ -77,6 +77,8 @@
 
     @Mock private lateinit var deviceItemInteractor: DeviceItemInteractor
 
+    @Mock private lateinit var deviceItemActionInteractor: DeviceItemActionInteractor
+
     @Mock private lateinit var activityStarter: ActivityStarter
 
     @Mock private lateinit var mDialogTransitionAnimator: DialogTransitionAnimator
@@ -118,6 +120,7 @@
         bluetoothTileDialogViewModel =
             BluetoothTileDialogViewModel(
                 deviceItemInteractor,
+                deviceItemActionInteractor,
                 BluetoothStateInteractor(
                     localBluetoothManager,
                     bluetoothTileDialogLogger,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorImplTest.kt
new file mode 100644
index 0000000..762137b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorImplTest.kt
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.bluetooth.qsdialog
+
+import android.bluetooth.BluetoothDevice
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import androidx.test.filters.SmallTest
+import com.android.settingslib.bluetooth.CachedBluetoothDevice
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.kosmos.testScope
+import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.testKosmos
+import com.android.systemui.util.mockito.whenever
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Rule
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.junit.MockitoJUnit
+import org.mockito.junit.MockitoRule
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper(setAsMainLooper = true)
+@OptIn(ExperimentalCoroutinesApi::class)
+class DeviceItemActionInteractorImplTest : SysuiTestCase() {
+    @get:Rule val mockitoRule: MockitoRule = MockitoJUnit.rule()
+    private val kosmos = testKosmos().apply { testDispatcher = UnconfinedTestDispatcher() }
+    private lateinit var actionInteractorImpl: DeviceItemActionInteractor
+
+    @Mock private lateinit var dialog: SystemUIDialog
+    @Mock private lateinit var cachedDevice: CachedBluetoothDevice
+    @Mock private lateinit var device: BluetoothDevice
+    @Mock private lateinit var deviceItem: DeviceItem
+
+    @Before
+    fun setUp() {
+        actionInteractorImpl = kosmos.deviceItemActionInteractor
+        whenever(deviceItem.cachedBluetoothDevice).thenReturn(cachedDevice)
+        whenever(cachedDevice.address).thenReturn("ADDRESS")
+        whenever(cachedDevice.device).thenReturn(device)
+    }
+
+    @Test
+    fun testOnClick_connectedMedia_setActive() {
+        with(kosmos) {
+            testScope.runTest {
+                whenever(deviceItem.type)
+                    .thenReturn(DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE)
+                actionInteractorImpl.onClick(deviceItem, dialog)
+                verify(cachedDevice).setActive()
+                verify(bluetoothTileDialogLogger)
+                    .logDeviceClick(
+                        cachedDevice.address,
+                        DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE
+                    )
+            }
+        }
+    }
+
+    @Test
+    fun testOnClick_activeMedia_disconnect() {
+        with(kosmos) {
+            testScope.runTest {
+                whenever(deviceItem.type).thenReturn(DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
+                actionInteractorImpl.onClick(deviceItem, dialog)
+                verify(cachedDevice).disconnect()
+                verify(bluetoothTileDialogLogger)
+                    .logDeviceClick(
+                        cachedDevice.address,
+                        DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE
+                    )
+            }
+        }
+    }
+
+    @Test
+    fun testOnClick_connectedOtherDevice_disconnect() {
+        with(kosmos) {
+            testScope.runTest {
+                whenever(deviceItem.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+                actionInteractorImpl.onClick(deviceItem, dialog)
+                verify(cachedDevice).disconnect()
+                verify(bluetoothTileDialogLogger)
+                    .logDeviceClick(cachedDevice.address, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
+            }
+        }
+    }
+
+    @Test
+    fun testOnClick_saved_connect() {
+        with(kosmos) {
+            testScope.runTest {
+                whenever(deviceItem.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)
+                actionInteractorImpl.onClick(deviceItem, dialog)
+                verify(cachedDevice).connect()
+                verify(bluetoothTileDialogLogger)
+                    .logDeviceClick(cachedDevice.address, DeviceItemType.SAVED_BLUETOOTH_DEVICE)
+            }
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt
new file mode 100644
index 0000000..e8e37bc
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemActionInteractorKosmos.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.bluetooth.qsdialog
+
+import com.android.internal.logging.uiEventLogger
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.testDispatcher
+import com.android.systemui.util.mockito.mock
+
+val Kosmos.bluetoothTileDialogLogger: BluetoothTileDialogLogger by Kosmos.Fixture { mock {} }
+
+val Kosmos.deviceItemActionInteractor: DeviceItemActionInteractor by
+    Kosmos.Fixture {
+        DeviceItemActionInteractorImpl(
+            testDispatcher,
+            bluetoothTileDialogLogger,
+            uiEventLogger,
+        )
+    }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
index daf4a3c..2b4f950 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/bluetooth/qsdialog/DeviceItemInteractorTest.kt
@@ -23,7 +23,6 @@
 import android.testing.AndroidTestingRunner
 import android.testing.TestableLooper
 import androidx.test.filters.SmallTest
-import com.android.internal.logging.UiEventLogger
 import com.android.settingslib.bluetooth.CachedBluetoothDevice
 import com.android.settingslib.bluetooth.LocalBluetoothManager
 import com.android.systemui.SysuiTestCase
@@ -39,7 +38,6 @@
 import org.junit.Test
 import org.junit.runner.RunWith
 import org.mockito.Mock
-import org.mockito.Mockito.verify
 import org.mockito.Mockito.`when`
 import org.mockito.junit.MockitoJUnit
 import org.mockito.junit.MockitoRule
@@ -71,8 +69,6 @@
 
     @Mock private lateinit var localBluetoothManager: LocalBluetoothManager
 
-    @Mock private lateinit var uiEventLogger: UiEventLogger
-
     @Mock private lateinit var logger: BluetoothTileDialogLogger
 
     private val fakeSystemClock = FakeSystemClock()
@@ -94,7 +90,6 @@
                 adapter,
                 localBluetoothManager,
                 fakeSystemClock,
-                uiEventLogger,
                 logger,
                 testScope.backgroundScope,
                 dispatcher
@@ -218,61 +213,6 @@
         }
     }
 
-    @Test
-    fun testUpdateDeviceItemOnClick_connectedMedia_setActive() {
-        testScope.runTest {
-            `when`(deviceItem1.type).thenReturn(DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE)
-
-            interactor.updateDeviceItemOnClick(deviceItem1)
-
-            verify(cachedDevice1).setActive()
-            verify(logger)
-                .logDeviceClick(
-                    cachedDevice1.address,
-                    DeviceItemType.AVAILABLE_MEDIA_BLUETOOTH_DEVICE
-                )
-        }
-    }
-
-    @Test
-    fun testUpdateDeviceItemOnClick_activeMedia_disconnect() {
-        testScope.runTest {
-            `when`(deviceItem1.type).thenReturn(DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
-
-            interactor.updateDeviceItemOnClick(deviceItem1)
-
-            verify(cachedDevice1).disconnect()
-            verify(logger)
-                .logDeviceClick(cachedDevice1.address, DeviceItemType.ACTIVE_MEDIA_BLUETOOTH_DEVICE)
-        }
-    }
-
-    @Test
-    fun testUpdateDeviceItemOnClick_connectedOtherDevice_disconnect() {
-        testScope.runTest {
-            `when`(deviceItem1.type).thenReturn(DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
-
-            interactor.updateDeviceItemOnClick(deviceItem1)
-
-            verify(cachedDevice1).disconnect()
-            verify(logger)
-                .logDeviceClick(cachedDevice1.address, DeviceItemType.CONNECTED_BLUETOOTH_DEVICE)
-        }
-    }
-
-    @Test
-    fun testUpdateDeviceItemOnClick_saved_connect() {
-        testScope.runTest {
-            `when`(deviceItem1.type).thenReturn(DeviceItemType.SAVED_BLUETOOTH_DEVICE)
-
-            interactor.updateDeviceItemOnClick(deviceItem1)
-
-            verify(cachedDevice1).connect()
-            verify(logger)
-                .logDeviceClick(cachedDevice1.address, DeviceItemType.SAVED_BLUETOOTH_DEVICE)
-        }
-    }
-
     private fun createFactory(
         isFilterMatchFunc: (CachedBluetoothDevice) -> Boolean,
         deviceItem: DeviceItem
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarterTest.kt
new file mode 100644
index 0000000..05a2ca2
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/ShortcutHelperActivityStarterTest.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.ui
+
+import android.content.Intent
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.keyboard.shortcut.fakeShortcutHelperStartActivity
+import com.android.systemui.keyboard.shortcut.shortcutHelperActivityStarter
+import com.android.systemui.keyboard.shortcut.shortcutHelperTestHelper
+import com.android.systemui.keyboard.shortcut.ui.view.ShortcutHelperActivity
+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.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ShortcutHelperActivityStarterTest : SysuiTestCase() {
+
+    private val kosmos =
+        Kosmos().also {
+            it.testCase = this
+            it.testDispatcher = UnconfinedTestDispatcher()
+        }
+
+    private val testScope = kosmos.testScope
+    private val testHelper = kosmos.shortcutHelperTestHelper
+    private val fakeStartActivity = kosmos.fakeShortcutHelperStartActivity
+    private val starter = kosmos.shortcutHelperActivityStarter
+
+    @Test
+    fun start_doesNotStartByDefault() =
+        testScope.runTest {
+            starter.start()
+
+            assertThat(fakeStartActivity.startIntents).isEmpty()
+        }
+
+    @Test
+    fun start_onToggle_startsActivity() =
+        testScope.runTest {
+            starter.start()
+
+            testHelper.toggle(deviceId = 456)
+
+            verifyShortcutHelperActivityStarted()
+        }
+
+    @Test
+    fun start_onToggle_multipleTimesStartsActivityOnlyWhenNotStarted() =
+        testScope.runTest {
+            starter.start()
+
+            testHelper.toggle(deviceId = 456)
+            testHelper.toggle(deviceId = 456)
+            testHelper.toggle(deviceId = 456)
+            testHelper.toggle(deviceId = 456)
+
+            verifyShortcutHelperActivityStarted(numTimes = 2)
+        }
+
+    @Test
+    fun start_onRequestShowShortcuts_startsActivity() =
+        testScope.runTest {
+            starter.start()
+
+            testHelper.showFromActivity()
+
+            verifyShortcutHelperActivityStarted()
+        }
+
+    @Test
+    fun start_onRequestShowShortcuts_multipleTimes_startsActivityOnlyOnce() =
+        testScope.runTest {
+            starter.start()
+
+            testHelper.showFromActivity()
+            testHelper.showFromActivity()
+            testHelper.showFromActivity()
+
+            verifyShortcutHelperActivityStarted(numTimes = 1)
+        }
+
+    @Test
+    fun start_onRequestShowShortcuts_multipleTimes_startsActivityOnlyWhenNotStarted() =
+        testScope.runTest {
+            starter.start()
+
+            testHelper.hideFromActivity()
+            testHelper.hideForSystem()
+            testHelper.toggle(deviceId = 987)
+            testHelper.showFromActivity()
+            testHelper.hideFromActivity()
+            testHelper.hideForSystem()
+            testHelper.toggle(deviceId = 456)
+            testHelper.showFromActivity()
+
+            verifyShortcutHelperActivityStarted(numTimes = 2)
+        }
+
+    private fun verifyShortcutHelperActivityStarted(numTimes: Int = 1) {
+        assertThat(fakeStartActivity.startIntents).hasSize(numTimes)
+        fakeStartActivity.startIntents.forEach { intent ->
+            assertThat(intent.flags).isEqualTo(Intent.FLAG_ACTIVITY_NEW_TASK)
+            assertThat(intent.filterEquals(Intent(context, ShortcutHelperActivity::class.java)))
+                .isTrue()
+        }
+    }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
new file mode 100644
index 0000000..8653308
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyboard/shortcut/ui/viewmodel/ShortcutHelperViewModelTest.kt
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.keyboard.shortcut.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.coroutines.collectValues
+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.testCase
+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.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ShortcutHelperViewModelTest : SysuiTestCase() {
+
+    private val kosmos =
+        Kosmos().also {
+            it.testCase = this
+            it.testDispatcher = UnconfinedTestDispatcher()
+        }
+
+    private val testScope = kosmos.testScope
+    private val testHelper = kosmos.shortcutHelperTestHelper
+
+    private val viewModel = kosmos.shortcutHelperViewModel
+
+    @Test
+    fun shouldShow_falseByDefault() =
+        testScope.runTest {
+            val shouldShow by collectLastValue(viewModel.shouldShow)
+
+            assertThat(shouldShow).isFalse()
+        }
+
+    @Test
+    fun shouldShow_trueAfterShowRequested() =
+        testScope.runTest {
+            val shouldShow by collectLastValue(viewModel.shouldShow)
+
+            testHelper.showFromActivity()
+
+            assertThat(shouldShow).isTrue()
+        }
+
+    @Test
+    fun shouldShow_trueAfterToggleRequested() =
+        testScope.runTest {
+            val shouldShow by collectLastValue(viewModel.shouldShow)
+
+            testHelper.toggle(deviceId = 123)
+
+            assertThat(shouldShow).isTrue()
+        }
+
+    @Test
+    fun shouldShow_falseAfterToggleTwice() =
+        testScope.runTest {
+            val shouldShow by collectLastValue(viewModel.shouldShow)
+
+            testHelper.toggle(deviceId = 123)
+            testHelper.toggle(deviceId = 123)
+
+            assertThat(shouldShow).isFalse()
+        }
+
+    @Test
+    fun shouldShow_falseAfterViewDestroyed() =
+        testScope.runTest {
+            val shouldShow by collectLastValue(viewModel.shouldShow)
+
+            testHelper.toggle(deviceId = 567)
+            viewModel.onUserLeave()
+
+            assertThat(shouldShow).isFalse()
+        }
+
+    @Test
+    fun shouldShow_doesNotEmitDuplicateValues() =
+        testScope.runTest {
+            val shouldShowValues by collectValues(viewModel.shouldShow)
+
+            testHelper.hideForSystem()
+            testHelper.toggle(deviceId = 987)
+            testHelper.showFromActivity()
+            viewModel.onUserLeave()
+            testHelper.hideFromActivity()
+            testHelper.hideForSystem()
+            testHelper.toggle(deviceId = 456)
+            testHelper.showFromActivity()
+
+            assertThat(shouldShowValues).containsExactly(false, true, false, true).inOrder()
+        }
+
+    @Test
+    fun shouldShow_emitsLatestValueToNewSubscribers() =
+        testScope.runTest {
+            val shouldShow by collectLastValue(viewModel.shouldShow)
+
+            testHelper.showFromActivity()
+
+            val shouldShowNew by collectLastValue(viewModel.shouldShow)
+            assertThat(shouldShowNew).isEqualTo(shouldShow)
+        }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt
index 85cc88d..9f0e67b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/monet/ColorSchemeTest.kt
@@ -15,13 +15,11 @@
  */
 package com.android.systemui.monet
 
+import androidx.test.filters.SmallTest
 import android.testing.AndroidTestingRunner
 import android.util.Log
-import android.util.Pair
-import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
 import com.android.systemui.theme.DynamicColors
-import com.google.ux.material.libmonet.dynamiccolor.DynamicColor
 import com.google.ux.material.libmonet.hct.Hct
 import com.google.ux.material.libmonet.scheme.SchemeTonalSpot
 import java.io.File
@@ -83,10 +81,6 @@
 @SmallTest
 @RunWith(AndroidTestingRunner::class)
 class ColorSchemeTest : SysuiTestCase() {
-    private val defaultContrast = 0.0
-    private val defaultIsDark = false
-    private val defaultIsFidelity = false
-
     @Test
     fun generateThemeStyles() {
         val document = buildDoc<Any>()
@@ -113,7 +107,7 @@
                 }
 
                 val style = document.createElement(styleValue.name.lowercase())
-                val colorScheme = ColorScheme(sourceColor.toInt(), defaultIsDark, styleValue)
+                val colorScheme = ColorScheme(sourceColor.toInt(), false, styleValue)
 
                 style.appendChild(
                     document.createTextNode(
@@ -145,7 +139,7 @@
         document.appendWithBreak(resources)
 
         // shade colors
-        val colorScheme = ColorScheme(GOOGLE_BLUE, defaultIsDark)
+        val colorScheme = ColorScheme(GOOGLE_BLUE, false)
         arrayOf(
                 Triple("accent1", "Primary", colorScheme.accent1),
                 Triple("accent2", "Secondary", colorScheme.accent2),
@@ -168,35 +162,24 @@
 
         resources.appendWithBreak(document.createComment(commentRoles), 2)
 
-        fun generateDynamic(pairs: List<Pair<String, DynamicColor>>) {
-            arrayOf(false, true).forEach { isDark ->
-                val suffix = if (isDark) "_dark" else "_light"
-                val dynamicScheme =
-                    SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, defaultContrast)
-                pairs.forEach {
-                    resources.createColorEntry(
-                        "system_${it.first}$suffix",
-                        it.second.getArgb(dynamicScheme)
-                    )
-                }
+        // dynamic colors
+        arrayOf(false, true).forEach { isDark ->
+            val suffix = if (isDark) "_dark" else "_light"
+            val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), isDark, 0.5)
+            DynamicColors.allDynamicColorsMapped(false).forEach {
+                resources.createColorEntry(
+                    "system_${it.first}$suffix",
+                    it.second.getArgb(dynamicScheme)
+                )
             }
         }
 
-        // dynamic colors
-        generateDynamic(DynamicColors.allDynamicColorsMapped(defaultIsFidelity))
-
         // fixed colors
-        val dynamicScheme =
-            SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), defaultIsDark, defaultContrast)
-        DynamicColors.getFixedColorsMapped(defaultIsFidelity).forEach {
+        val dynamicScheme = SchemeTonalSpot(Hct.fromInt(GOOGLE_BLUE), false, 0.5)
+        DynamicColors.getFixedColorsMapped(false).forEach {
             resources.createColorEntry("system_${it.first}", it.second.getArgb(dynamicScheme))
         }
 
-        resources.appendWithBreak(document.createComment(commentRoles), 2)
-
-        // custom colors
-        generateDynamic(DynamicColors.getCustomColorsMapped(defaultIsFidelity))
-
         saveFile(document, "role_values.xml")
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
index 0f37143..bf7d909 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotExecutorTest.kt
@@ -69,8 +69,9 @@
 
     @Before
     fun setUp() {
-        whenever(controllerFactory.create(eq(0), any())).thenReturn(controller0)
-        whenever(controllerFactory.create(eq(1), any())).thenReturn(controller1)
+        whenever(controllerFactory.create(any(), any())).thenAnswer {
+            if (it.getArgument<Display>(0).displayId == 0) controller0 else controller1
+        }
         whenever(notificationControllerFactory.create(eq(0))).thenReturn(notificationsController0)
         whenever(notificationControllerFactory.create(eq(1))).thenReturn(notificationsController1)
     }
@@ -78,12 +79,14 @@
     @Test
     fun executeScreenshots_severalDisplays_callsControllerForEachOne() =
         testScope.runTest {
-            setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
+            val internalDisplay = display(TYPE_INTERNAL, id = 0)
+            val externalDisplay = display(TYPE_EXTERNAL, id = 1)
+            setDisplays(internalDisplay, externalDisplay)
             val onSaved = { _: Uri? -> }
             screenshotExecutor.executeScreenshots(createScreenshotRequest(), onSaved, callback)
 
-            verify(controllerFactory).create(eq(0), any())
-            verify(controllerFactory).create(eq(1), any())
+            verify(controllerFactory).create(eq(internalDisplay), any())
+            verify(controllerFactory).create(eq(externalDisplay), any())
 
             val capturer = ArgumentCaptor<ScreenshotData>()
 
@@ -107,7 +110,9 @@
     @Test
     fun executeScreenshots_providedImageType_callsOnlyDefaultDisplayController() =
         testScope.runTest {
-            setDisplays(display(TYPE_INTERNAL, id = 0), display(TYPE_EXTERNAL, id = 1))
+            val internalDisplay = display(TYPE_INTERNAL, id = 0)
+            val externalDisplay = display(TYPE_EXTERNAL, id = 1)
+            setDisplays(internalDisplay, externalDisplay)
             val onSaved = { _: Uri? -> }
             screenshotExecutor.executeScreenshots(
                 createScreenshotRequest(TAKE_SCREENSHOT_PROVIDED_IMAGE),
@@ -115,8 +120,8 @@
                 callback
             )
 
-            verify(controllerFactory).create(eq(0), any())
-            verify(controllerFactory, never()).create(eq(1), any())
+            verify(controllerFactory).create(eq(internalDisplay), any())
+            verify(controllerFactory, never()).create(eq(externalDisplay), any())
 
             val capturer = ArgumentCaptor<ScreenshotData>()
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
index a5e7a67..ed7c956 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/theme/ThemeOverlayControllerTest.java
@@ -995,11 +995,9 @@
                 .setResourceValue(any(String.class), eq(TYPE_INT_COLOR_ARGB8), anyInt(), eq(null));
         // All dynamic colors were added twice: light and dark them
         // All fixed colors were added once
-        // All custom dynamic tokens added twice
         verify(dynamic, times(
                 DynamicColors.allDynamicColorsMapped(false).size() * 2
-                        + DynamicColors.getFixedColorsMapped(false).size()
-                        + DynamicColors.getCustomColorsMapped(false).size() * 2)
+                        + DynamicColors.getFixedColorsMapped(false).size())
         ).setResourceValue(any(String.class), eq(TYPE_INT_COLOR_ARGB8), anyInt(), eq(null));
     }
 }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/FakeShortcutHelperStartActivity.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/FakeShortcutHelperStartActivity.kt
new file mode 100644
index 0000000..3190171
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/FakeShortcutHelperStartActivity.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.keyboard.shortcut
+
+import android.content.Intent
+
+class FakeShortcutHelperStartActivity : (Intent) -> Unit {
+
+    val startIntents = mutableListOf<Intent>()
+
+    override fun invoke(intent: Intent) {
+        startIntents += intent
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
new file mode 100644
index 0000000..38f2a56
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/KeyboardShortcutHelperKosmos.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut
+
+import android.content.applicationContext
+import com.android.systemui.broadcast.broadcastDispatcher
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperRepository
+import com.android.systemui.keyboard.shortcut.data.repository.ShortcutHelperTestHelper
+import com.android.systemui.keyboard.shortcut.domain.interactor.ShortcutHelperInteractor
+import com.android.systemui.keyboard.shortcut.ui.ShortcutHelperActivityStarter
+import com.android.systemui.keyboard.shortcut.ui.viewmodel.ShortcutHelperViewModel
+import com.android.systemui.keyguard.data.repository.fakeCommandQueue
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.kosmos.applicationCoroutineScope
+import com.android.systemui.kosmos.testDispatcher
+
+val Kosmos.shortcutHelperRepository by
+    Kosmos.Fixture { ShortcutHelperRepository(fakeCommandQueue, broadcastDispatcher) }
+
+val Kosmos.shortcutHelperTestHelper by
+    Kosmos.Fixture {
+        ShortcutHelperTestHelper(
+            shortcutHelperRepository,
+            applicationContext,
+            broadcastDispatcher,
+            fakeCommandQueue
+        )
+    }
+
+val Kosmos.shortcutHelperInteractor by
+    Kosmos.Fixture { ShortcutHelperInteractor(shortcutHelperRepository) }
+
+val Kosmos.shortcutHelperViewModel by
+    Kosmos.Fixture { ShortcutHelperViewModel(testDispatcher, shortcutHelperInteractor) }
+
+val Kosmos.fakeShortcutHelperStartActivity by Kosmos.Fixture { FakeShortcutHelperStartActivity() }
+
+val Kosmos.shortcutHelperActivityStarter by
+    Kosmos.Fixture {
+        ShortcutHelperActivityStarter(
+            applicationContext,
+            applicationCoroutineScope,
+            shortcutHelperViewModel,
+            fakeShortcutHelperStartActivity,
+        )
+    }
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
new file mode 100644
index 0000000..772ce41
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/keyboard/shortcut/data/repository/ShortcutHelperTestHelper.kt
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.keyboard.shortcut.data.repository
+
+import android.content.Context
+import android.content.Intent
+import com.android.systemui.broadcast.FakeBroadcastDispatcher
+import com.android.systemui.keyguard.data.repository.FakeCommandQueue
+
+class ShortcutHelperTestHelper(
+    repo: ShortcutHelperRepository,
+    private val context: Context,
+    private val fakeBroadcastDispatcher: FakeBroadcastDispatcher,
+    private val fakeCommandQueue: FakeCommandQueue,
+) {
+
+    init {
+        repo.start()
+    }
+
+    fun hideFromActivity() {
+        fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+            context,
+            Intent(Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS)
+        )
+    }
+
+    fun showFromActivity() {
+        fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
+            context,
+            Intent(Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS)
+        )
+    }
+
+    fun toggle(deviceId: Int) {
+        fakeCommandQueue.doForEachCallback { it.toggleKeyboardShortcutsMenu(deviceId) }
+    }
+
+    fun hideForSystem() {
+        fakeCommandQueue.doForEachCallback { it.dismissKeyboardShortcutsMenu() }
+    }
+}
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
index 3e9ae4d..1f2ecb7 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/user/data/repository/FakeUserRepository.kt
@@ -37,7 +37,7 @@
 class FakeUserRepository @Inject constructor() : UserRepository {
     companion object {
         // User id to represent a non system (human) user id. We presume this is the main user.
-        private const val MAIN_USER_ID = 10
+        const val MAIN_USER_ID = 10
 
         private const val DEFAULT_SELECTED_USER = 0
         private val DEFAULT_SELECTED_USER_INFO =
@@ -84,6 +84,10 @@
 
     override var isRefreshUsersPaused: Boolean = false
 
+    override suspend fun getMainUserId(): Int? {
+        return MAIN_USER_ID
+    }
+
     var refreshUsersCallCount: Int = 0
         private set
 
diff --git a/services/core/java/com/android/server/location/contexthub/ContextHubService.java b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
index 5731161..d6d134d 100644
--- a/services/core/java/com/android/server/location/contexthub/ContextHubService.java
+++ b/services/core/java/com/android/server/location/contexthub/ContextHubService.java
@@ -78,10 +78,14 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
+import java.util.PriorityQueue;
+import java.util.Random;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
 /**
@@ -152,6 +156,16 @@
     private final ScheduledThreadPoolExecutor mDailyMetricTimer =
             new ScheduledThreadPoolExecutor(1);
 
+    // A queue of reliable message records for duplicate detection
+    private final PriorityQueue<ReliableMessageRecord> mReliableMessageRecordQueue =
+            new PriorityQueue<ReliableMessageRecord>(
+                    (ReliableMessageRecord left, ReliableMessageRecord right) -> {
+                        return Long.compare(left.getTimestamp(), right.getTimestamp());
+                    });
+
+    // The test mode manager that manages behaviors during test mode.
+    private final TestModeManager mTestModeManager = new TestModeManager();
+
     // The period of the recurring time
     private static final int PERIOD_METRIC_QUERY_DAYS = 1;
 
@@ -164,6 +178,9 @@
     private boolean mIsBtScanningEnabled = false;
     private boolean mIsBtMainEnabled = false;
 
+    // True if test mode is enabled for the Context Hub
+    private AtomicBoolean mIsTestModeEnabled = new AtomicBoolean(false);
+
     // A hashmap used to record if a contexthub is waiting for daily query
     private Set<Integer> mMetricQueryPendingContextHubIds =
             Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());
@@ -210,8 +227,17 @@
         @Override
         public void handleNanoappMessage(short hostEndpointId, NanoAppMessage message,
                 List<String> nanoappPermissions, List<String> messagePermissions) {
-            handleClientMessageCallback(mContextHubId, hostEndpointId, message, nanoappPermissions,
-                    messagePermissions);
+            if (Flags.reliableMessageImplementation()
+                    && Flags.reliableMessageTestModeBehavior()
+                    && mIsTestModeEnabled.get()
+                    && mTestModeManager.handleNanoappMessage(mContextHubId, hostEndpointId,
+                            message, nanoappPermissions, messagePermissions)) {
+                // The TestModeManager handled the nanoapp message, so return here.
+                return;
+            }
+
+            handleClientMessageCallback(mContextHubId, hostEndpointId, message,
+                    nanoappPermissions, messagePermissions);
         }
 
         @Override
@@ -228,6 +254,106 @@
         }
     }
 
+    /**
+     * Records a reliable message from a nanoapp for duplicate detection.
+     */
+    private static class ReliableMessageRecord {
+        public static final int TIMEOUT_NS = 1000000000;
+
+        public int mContextHubId;
+        public long mTimestamp;
+        public int mMessageSequenceNumber;
+        byte mErrorCode;
+
+        ReliableMessageRecord(int contextHubId, long timestamp,
+                int messageSequenceNumber, byte errorCode) {
+            mContextHubId = contextHubId;
+            mTimestamp = timestamp;
+            mMessageSequenceNumber = messageSequenceNumber;
+            mErrorCode = errorCode;
+        }
+
+        public int getContextHubId() {
+            return mContextHubId;
+        }
+
+        public long getTimestamp() {
+            return mTimestamp;
+        }
+
+        public int getMessageSequenceNumber() {
+            return mMessageSequenceNumber;
+        }
+
+        public byte getErrorCode() {
+            return mErrorCode;
+        }
+
+        public void setErrorCode(byte errorCode) {
+            mErrorCode = errorCode;
+        }
+
+        public boolean isExpired() {
+            return mTimestamp + TIMEOUT_NS < SystemClock.elapsedRealtimeNanos();
+        }
+    }
+
+    /**
+     * A class to manage behaviors during test mode. This is used for testing.
+     */
+    private class TestModeManager {
+        /**
+         * Probability (in percent) of duplicating a message.
+         */
+        private static final int MESSAGE_DUPLICATION_PROBABILITY_PERCENT = 50;
+
+        /**
+         * The number of total messages to send when the duplicate event happens.
+         */
+        private static final int NUM_MESSAGES_TO_DUPLICATE = 3;
+
+        /**
+         * A probability percent for a certain event.
+         */
+        private static final int MAX_PROBABILITY_PERCENT = 100;
+
+        /**
+         * Random number generator.
+         */
+        private Random mRandom = new Random();
+
+        /**
+         * @see ContextHubServiceCallback.handleNanoappMessage
+         * @return whether the message was handled
+         */
+        public boolean handleNanoappMessage(int contextHubId,
+                short hostEndpointId, NanoAppMessage message,
+                List<String> nanoappPermissions, List<String> messagePermissions) {
+            if (!message.isReliable()) {
+                return false;
+            }
+
+            if (didEventHappen(MESSAGE_DUPLICATION_PROBABILITY_PERCENT)) {
+                for (int i = 0; i < NUM_MESSAGES_TO_DUPLICATE; ++i) {
+                    handleClientMessageCallback(contextHubId, hostEndpointId,
+                            message, nanoappPermissions, messagePermissions);
+                }
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Returns true if the event with percentPercent did happen.
+         *
+         * @param probabilityPercent the percent probability of the event.
+         * @return true if the event happened, false otherwise.
+         */
+        private boolean didEventHappen(int probabilityPercent) {
+            return mRandom.nextInt(MAX_PROBABILITY_PERCENT) < probabilityPercent;
+        }
+    }
+
     public ContextHubService(Context context, IContextHubWrapper contextHubWrapper) {
         Log.i(TAG, "Starting Context Hub Service init");
         mContext = context;
@@ -563,6 +689,8 @@
      * Resets the settings. Called when a context hub restarts or the AIDL HAL dies
      */
     private void resetSettings() {
+        mIsTestModeEnabled.set(false);
+
         sendLocationSettingUpdate();
         sendWifiSettingUpdate(/* forceUpdate= */ true);
         sendAirplaneModeSettingUpdate();
@@ -854,14 +982,76 @@
     private void handleClientMessageCallback(int contextHubId, short hostEndpointId,
             NanoAppMessage message, List<String> nanoappPermissions,
             List<String> messagePermissions) {
-        byte errorCode = mClientManager.onMessageFromNanoApp(contextHubId, hostEndpointId, message,
-                nanoappPermissions, messagePermissions);
-        if (message.isReliable() && errorCode != ErrorCode.OK) {
-            sendMessageDeliveryStatusToContextHub(contextHubId, message.getMessageSequenceNumber(),
-                    errorCode);
+        if (!Flags.reliableMessageImplementation()
+                || !Flags.reliableMessageDuplicateDetectionService()) {
+            byte errorCode = mClientManager.onMessageFromNanoApp(contextHubId, hostEndpointId,
+                    message, nanoappPermissions, messagePermissions);
+            if (message.isReliable() && errorCode != ErrorCode.OK) {
+                sendMessageDeliveryStatusToContextHub(contextHubId,
+                        message.getMessageSequenceNumber(), errorCode);
+            }
+            return;
+        }
+
+        if (message.isReliable()) {
+            byte errorCode = ErrorCode.OK;
+            synchronized (mReliableMessageRecordQueue) {
+                Optional<ReliableMessageRecord> record = Optional.empty();
+                for (ReliableMessageRecord r: mReliableMessageRecordQueue) {
+                    if (r.getContextHubId() == contextHubId
+                            && r.getMessageSequenceNumber() == message.getMessageSequenceNumber()) {
+                        record = Optional.of(r);
+                        break;
+                    }
+                }
+
+                if (record.isPresent()) {
+                    errorCode = record.get().getErrorCode();
+                    if (errorCode == ErrorCode.TRANSIENT_ERROR) {
+                        Log.w(TAG, "Found duplicate reliable message with message sequence number: "
+                                + record.get().getMessageSequenceNumber() + ": retrying");
+                        errorCode = mClientManager.onMessageFromNanoApp(
+                                contextHubId, hostEndpointId, message,
+                                nanoappPermissions, messagePermissions);
+                        record.get().setErrorCode(errorCode);
+                    } else {
+                        Log.w(TAG, "Found duplicate reliable message with message sequence number: "
+                                + record.get().getMessageSequenceNumber());
+                    }
+                } else {
+                    errorCode = mClientManager.onMessageFromNanoApp(
+                            contextHubId, hostEndpointId, message,
+                            nanoappPermissions, messagePermissions);
+                    mReliableMessageRecordQueue.add(
+                            new ReliableMessageRecord(contextHubId,
+                                    SystemClock.elapsedRealtimeNanos(),
+                                    message.getMessageSequenceNumber(),
+                                    errorCode));
+                }
+            }
+            sendMessageDeliveryStatusToContextHub(contextHubId,
+                    message.getMessageSequenceNumber(), errorCode);
+        } else {
+            mClientManager.onMessageFromNanoApp(
+                    contextHubId, hostEndpointId, message,
+                    nanoappPermissions, messagePermissions);
+        }
+
+        synchronized (mReliableMessageRecordQueue) {
+            while (mReliableMessageRecordQueue.peek() != null
+                   && mReliableMessageRecordQueue.peek().isExpired()) {
+                mReliableMessageRecordQueue.poll();
+            }
         }
     }
 
+    /**
+     * Sends the message delivery status to the Context Hub.
+     *
+     * @param contextHubId the ID of the hub
+     * @param messageSequenceNumber the message sequence number
+     * @param errorCode the error code, one of the enum ErrorCode
+     */
     private void sendMessageDeliveryStatusToContextHub(int contextHubId,
             int messageSequenceNumber, byte errorCode) {
         if (!Flags.reliableMessageImplementation()) {
@@ -1229,6 +1419,9 @@
     public boolean setTestMode(boolean enable) {
         super.setTestMode_enforcePermission();
         boolean status = mContextHubWrapper.setTestMode(enable);
+        if (status) {
+            mIsTestModeEnabled.set(enable);
+        }
 
         // Query nanoapps to update service state after test mode state change.
         for (int contextHubId: mDefaultClientMap.keySet()) {
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 143bc5c..b589f49 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -486,6 +486,7 @@
         }
     }
 
+    @GuardedBy("mConfigLock")
     private ZenRule maybeRestoreRemovedRule(ZenModeConfig config, ZenRule ruleToAdd,
             AutomaticZenRule azrToAdd, @ConfigChangeOrigin int origin) {
         if (!Flags.modesApi()) {
@@ -1112,6 +1113,7 @@
      * <p>The rule's {@link ZenRule#condition} is cleared (meaning that an active rule will be
      * deactivated) unless the update has origin == {@link ZenModeConfig#UPDATE_ORIGIN_USER}.
      */
+    @GuardedBy("mConfigLock")
     private boolean populateZenRule(String pkg, AutomaticZenRule azr, ZenRule rule,
                          @ConfigChangeOrigin int origin, boolean isNew) {
         if (Flags.modesApi()) {
@@ -1261,12 +1263,14 @@
      *
      * <p>Returns {@code true} if the policy of the rule was modified.
      */
+    @GuardedBy("mConfigLock")
     private boolean updatePolicy(ZenRule zenRule, @Nullable ZenPolicy newPolicy,
             boolean updateBitmask, boolean isNew) {
         if (newPolicy == null) {
             if (isNew) {
                 // Newly created rule with no provided policy; fill in with the default.
-                zenRule.zenPolicy = mDefaultConfig.toZenPolicy();
+                zenRule.zenPolicy =
+                        Flags.modesUi() ? mDefaultConfig.toZenPolicy() : mConfig.toZenPolicy();
                 return true;
             }
             // Otherwise, a null policy means no policy changes, so we can stop here.
@@ -1275,8 +1279,9 @@
 
         // If oldPolicy is null, we compare against the default policy when determining which
         // fields in the bitmask should be marked as updated.
-        ZenPolicy oldPolicy =
-                zenRule.zenPolicy != null ? zenRule.zenPolicy : mDefaultConfig.toZenPolicy();
+        ZenPolicy oldPolicy = zenRule.zenPolicy != null
+                ? zenRule.zenPolicy
+                : (Flags.modesUi() ? mDefaultConfig.toZenPolicy() : mConfig.toZenPolicy());
 
         // If this is updating a rule rather than creating a new one, keep any fields from the
         // old policy if they are unspecified in the new policy. For newly created rules, oldPolicy
@@ -2033,7 +2038,8 @@
                     // rule's policy fields should be set upon creation, this is a fallback to
                     // catch any that may have fallen through the cracks.
                     Log.wtf(TAG, "active automatic rule found with no specified policy: " + rule);
-                    policy.apply(mDefaultConfig.toZenPolicy());
+                    policy.apply(
+                            Flags.modesUi() ? mDefaultConfig.toZenPolicy() : mConfig.toZenPolicy());
                 }
             } else {
                 // active rule with no specified policy inherits the global config settings
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index c60f0af..209cbb7 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -46,6 +46,7 @@
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.pm.ApexStagedEvent;
+import android.content.pm.Flags;
 import android.content.pm.IPackageManagerNative;
 import android.content.pm.IStagedApexObserver;
 import android.content.pm.PackageManager;
@@ -766,6 +767,10 @@
         final PackageSetting ps = installRequest.getScannedPackageSetting();
         final AndroidPackage pkg = ps.getPkg();
         final boolean onIncremental = isIncrementalPath(ps.getPathString());
+        final boolean performDexOptForRollback = Flags.recoverabilityDetection()
+                ? !(installRequest.isRollback()
+                && installRequest.getInstallSource().mInitiatingPackageName.equals("android"))
+                : true;
 
         return (!instantApp || Global.getInt(context.getContentResolver(),
                 Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
@@ -773,7 +778,8 @@
                 && !pkg.isDebuggable()
                 && (!onIncremental)
                 && dexoptOptions.isCompilationEnabled()
-                && !isApex;
+                && !isApex
+                && performDexOptForRollback;
     }
 
     private static class StagedApexObserver extends IStagedApexObserver.Stub {
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index b1976cd..f6487ce 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1371,7 +1371,7 @@
             for (int i = 0; i < userSize; i++) {
                 UserInfo ui = mUsers.valueAt(i).info;
                 if ((excludePartial && ui.partial)
-                        || (excludeDying && mRemovingUserIds.get(ui.id))
+                        || (excludeDying && isDyingLU(ui))
                         || (excludePreCreated && ui.preCreated)) {
                     continue;
                 }
@@ -1381,6 +1381,17 @@
         }
     }
 
+    @GuardedBy("mUsersLock")
+    private boolean isDyingLU(UserInfo ui) {
+        if (mRemovingUserIds.get(ui.id)) {
+            return true;
+        }
+        if (ui.isEphemeral() && ui.isInitialized() && ui.id != getCurrentUserId()) {
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public List<UserInfo> getProfiles(@UserIdInt int userId, boolean enabledOnly) {
         boolean returnFullInfo;
diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java
index 1a9e012..f7eb29f 100644
--- a/services/core/java/com/android/server/pm/VerifyingSession.java
+++ b/services/core/java/com/android/server/pm/VerifyingSession.java
@@ -141,6 +141,8 @@
     @NonNull
     private final PackageManagerService mPm;
 
+    private final int mInstallReason;
+
     VerifyingSession(UserHandle user, File stagedDir, IPackageInstallObserver2 observer,
             PackageInstaller.SessionParams sessionParams, InstallSource installSource,
             int installerUid, SigningDetails signingDetails, int sessionId, PackageLite lite,
@@ -168,6 +170,7 @@
         mUserActionRequiredType = sessionParams.requireUserAction;
         mIsInherit = sessionParams.mode == MODE_INHERIT_EXISTING;
         mIsStaged = sessionParams.isStaged;
+        mInstallReason = sessionParams.installReason;
     }
 
     @Override
@@ -190,7 +193,9 @@
         // Perform package verification and enable rollback (unless we are simply moving the
         // package).
         if (!mOriginInfo.mExisting) {
-            if (!isApex() && !isArchivedInstallation()) {
+            final boolean verifyForRollback = Flags.recoverabilityDetection()
+                    ? !isARollback() : true;
+            if (!isApex() && !isArchivedInstallation() && verifyForRollback) {
                 // TODO(b/182426975): treat APEX as APK when APK verification is concerned
                 sendApkVerificationRequest(pkgLite);
             }
@@ -200,6 +205,11 @@
         }
     }
 
+    private boolean isARollback() {
+        return mInstallReason == PackageManager.INSTALL_REASON_ROLLBACK
+                && mInstallSource.mInitiatingPackageName.equals("android");
+    }
+
     private void sendApkVerificationRequest(PackageInfoLite pkgLite) {
         final int verificationId = mPm.mPendingVerificationToken++;
 
diff --git a/services/core/java/com/android/server/wm/LetterboxConfiguration.java b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
index 5aa0ed7..ce1a72d 100644
--- a/services/core/java/com/android/server/wm/LetterboxConfiguration.java
+++ b/services/core/java/com/android/server/wm/LetterboxConfiguration.java
@@ -25,7 +25,6 @@
 import android.content.Context;
 import android.graphics.Color;
 import android.provider.DeviceConfig;
-import android.util.Slog;
 
 import com.android.internal.R;
 import com.android.internal.annotations.VisibleForTesting;
@@ -33,6 +32,7 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.util.function.Function;
+import java.util.function.IntSupplier;
 
 /** Reads letterbox configs from resources and controls their overrides at runtime. */
 final class LetterboxConfiguration {
@@ -265,6 +265,12 @@
     // unresizable apps
     private boolean mIsDisplayAspectRatioEnabledForFixedOrientationLetterbox;
 
+    // Supplier for the value in pixel to consider when detecting vertical thin letterboxing
+    private final IntSupplier mThinLetterboxWidthFn;
+
+    // Supplier for the value in pixel to consider when detecting horizontal thin letterboxing
+    private final IntSupplier mThinLetterboxHeightFn;
+
     // Allows to enable letterboxing strategy for translucent activities ignoring flags.
     private boolean mTranslucentLetterboxingOverrideEnabled;
 
@@ -358,6 +364,10 @@
                 R.bool.config_isWindowManagerCameraCompatSplitScreenAspectRatioEnabled);
         mIsPolicyForIgnoringRequestedOrientationEnabled = mContext.getResources().getBoolean(
                 R.bool.config_letterboxIsPolicyForIgnoringRequestedOrientationEnabled);
+        mThinLetterboxWidthFn = () ->  mContext.getResources().getDimensionPixelSize(
+                R.dimen.config_letterboxThinLetterboxWidthDp);
+        mThinLetterboxHeightFn = () -> mContext.getResources().getDimensionPixelSize(
+                R.dimen.config_letterboxThinLetterboxHeightDp);
 
         mLetterboxConfigurationPersister = letterboxConfigurationPersister;
         mLetterboxConfigurationPersister.start();
@@ -1129,6 +1139,24 @@
     }
 
     /**
+     * @return Width in pixel about the padding to use to understand if the letterbox for an
+     *         activity is thin. If the available space has width W and the app has width w, this
+     *         is the maximum value for (W - w) / 2 to be considered for a thin letterboxed app.
+     */
+    int getThinLetterboxWidthPx() {
+        return mThinLetterboxWidthFn.getAsInt();
+    }
+
+    /**
+     * @return Height in pixel about the padding to use to understand if a letterbox is thin.
+     *         If the available space has height H and the app has height h, this is the maximum
+     *         value for (H - h) / 2 to be considered for a thin letterboxed app.
+     */
+    int getThinLetterboxHeightPx() {
+        return mThinLetterboxHeightFn.getAsInt();
+    }
+
+    /**
      * Overrides whether using split screen aspect ratio as a default aspect ratio for unresizable
      * apps.
      */
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index b38e666..9e16b8a 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -1024,6 +1024,67 @@
         return getSplitScreenAspectRatio();
     }
 
+    /**
+     * @return {@value true} if the resulting app is letterboxed in a way defined as thin.
+     */
+    boolean isVerticalThinLetterboxed() {
+        final int thinHeight = mLetterboxConfiguration.getThinLetterboxHeightPx();
+        if (thinHeight < 0) {
+            return false;
+        }
+        final Task task = mActivityRecord.getTask();
+        if (task == null) {
+            return false;
+        }
+        final int padding = Math.abs(
+                task.getBounds().height() - mActivityRecord.getBounds().height()) / 2;
+        return padding <= thinHeight;
+    }
+
+    /**
+     * @return {@value true} if the resulting app is pillarboxed in a way defined as thin.
+     */
+    boolean isHorizontalThinLetterboxed() {
+        final int thinWidth = mLetterboxConfiguration.getThinLetterboxWidthPx();
+        if (thinWidth < 0) {
+            return false;
+        }
+        final Task task = mActivityRecord.getTask();
+        if (task == null) {
+            return false;
+        }
+        final int padding = Math.abs(
+                task.getBounds().width() - mActivityRecord.getBounds().width()) / 2;
+        return padding <= thinWidth;
+    }
+
+
+    /**
+     * @return {@value true} if the vertical reachability should be allowed in case of
+     * thin letteboxing
+     */
+    boolean allowVerticalReachabilityForThinLetterbox() {
+        if (!Flags.disableThinLetterboxingReachability()) {
+            return true;
+        }
+        // When the flag is enabled we allow vertical reachability only if the
+        // app is not thin letterboxed vertically.
+        return !isVerticalThinLetterboxed();
+    }
+
+    /**
+     * @return {@value true} if the vertical reachability should be enabled in case of
+     * thin letteboxing
+     */
+    boolean allowHorizontalReachabilityForThinLetterbox() {
+        if (!Flags.disableThinLetterboxingReachability()) {
+            return true;
+        }
+        // When the flag is enabled we allow horizontal reachability only if the
+        // app is not thin pillarboxed.
+        return !isHorizontalThinLetterboxed();
+    }
+
     float getSplitScreenAspectRatio() {
         // Getting the same aspect ratio that apps get in split screen.
         final DisplayArea displayArea = mActivityRecord.getDisplayArea();
@@ -1263,6 +1324,9 @@
      * </ul>
      */
     private boolean isHorizontalReachabilityEnabled(Configuration parentConfiguration) {
+        if (!allowHorizontalReachabilityForThinLetterbox()) {
+            return false;
+        }
         // Use screen resolved bounds which uses resolved bounds or size compat bounds
         // as activity bounds can sometimes be empty
         final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior()
@@ -1298,6 +1362,9 @@
      * </ul>
      */
     private boolean isVerticalReachabilityEnabled(Configuration parentConfiguration) {
+        if (!allowVerticalReachabilityForThinLetterbox()) {
+            return false;
+        }
         // Use screen resolved bounds which uses resolved bounds or size compat bounds
         // as activity bounds can sometimes be empty
         final Rect opaqueActivityBounds = hasInheritedLetterboxBehavior()
@@ -1566,6 +1633,8 @@
         if (!shouldShowLetterboxUi) {
             return;
         }
+        pw.println(prefix + "  isVerticalThinLetterboxed=" + isVerticalThinLetterboxed());
+        pw.println(prefix + "  isHorizontalThinLetterboxed=" + isHorizontalThinLetterboxed());
         pw.println(prefix + "  letterboxBackgroundColor=" + Integer.toHexString(
                 getLetterboxBackgroundColor().toArgb()));
         pw.println(prefix + "  letterboxBackgroundType="
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index a9c47b8..8bd7b5f 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -20,7 +20,6 @@
 import static android.app.ActivityTaskManager.INVALID_TASK_ID;
 import static android.app.ActivityTaskManager.INVALID_WINDOWING_MODE;
 import static android.app.ActivityTaskManager.RESIZE_MODE_FORCED;
-import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
 import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
 import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
@@ -171,7 +170,6 @@
 import android.view.DisplayInfo;
 import android.view.InsetsState;
 import android.view.RemoteAnimationAdapter;
-import android.view.Surface;
 import android.view.SurfaceControl;
 import android.view.WindowManager;
 import android.view.WindowManager.TransitionOldType;
@@ -362,6 +360,10 @@
      * user wants to return to it. */
     private WindowProcessController mRootProcess;
 
+    /** The TF host info are set once the task has ever added an organized task fragment. */
+    int mTaskFragmentHostUid;
+    String mTaskFragmentHostProcessName;
+
     /** Takes on same value as first root activity */
     boolean isPersistable = false;
     int maxRecents;
@@ -438,16 +440,6 @@
     // Id of the previous display the root task was on.
     int mPrevDisplayId = INVALID_DISPLAY;
 
-    /** ID of the display which rotation {@link #mRotation} has. */
-    private int mLastRotationDisplayId = INVALID_DISPLAY;
-
-    /**
-     * Display rotation as of the last time {@link #setBounds(Rect)} was called or this task was
-     * moved to a new display.
-     */
-    @Surface.Rotation
-    private int mRotation;
-
     int mMultiWindowRestoreWindowingMode = INVALID_WINDOWING_MODE;
 
     /**
@@ -458,10 +450,7 @@
      */
     int mLastReportedRequestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
 
-    // For comparison with DisplayContent bounds.
-    private Rect mTmpRect = new Rect();
-    // For handling display rotations.
-    private Rect mTmpRect2 = new Rect();
+    private final Rect mTmpRect = new Rect();
 
     // Resize mode of the task. See {@link ActivityInfo#resizeMode}
     // Based on the {@link ActivityInfo#resizeMode} of the root activity.
@@ -1194,9 +1183,6 @@
             updateOverrideConfigurationFromLaunchBounds();
         }
 
-        // Update task bounds if needed.
-        adjustBoundsForDisplayChangeIfNeeded(getDisplayContent());
-
         mRootWindowContainer.updateUIDsPresentOnDisplay();
 
         // Ensure all animations are finished at same time in split-screen mode.
@@ -1468,6 +1454,11 @@
         // passed from Task constructor.
         final TaskFragment childTaskFrag = child.asTaskFragment();
         if (childTaskFrag != null && childTaskFrag.asTask() == null) {
+            if (childTaskFrag.mTaskFragmentOrganizerProcessName != null
+                    && mTaskFragmentHostProcessName == null) {
+                mTaskFragmentHostUid = childTaskFrag.mTaskFragmentOrganizerUid;
+                mTaskFragmentHostProcessName = childTaskFrag.mTaskFragmentOrganizerProcessName;
+            }
             childTaskFrag.setMinDimensions(mMinWidth, mMinHeight);
 
             // The starting window should keep covering its task when a pure TaskFragment is added
@@ -2731,15 +2722,7 @@
             return setBounds(getRequestedOverrideBounds(), bounds);
         }
 
-        int rotation = Surface.ROTATION_0;
-        final DisplayContent displayContent = getRootTask() != null
-                ? getRootTask().getDisplayContent() : null;
-        if (displayContent != null) {
-            rotation = displayContent.getDisplayInfo().rotation;
-        }
-
         final int boundsChange = super.setBounds(bounds);
-        mRotation = rotation;
         updateSurfacePositionNonOrganized();
         return boundsChange;
     }
@@ -2799,10 +2782,6 @@
 
     @Override
     void onDisplayChanged(DisplayContent dc) {
-        final boolean isRootTask = isRootTask();
-        if (!isRootTask && !mCreatedByOrganizer) {
-            adjustBoundsForDisplayChangeIfNeeded(dc);
-        }
         super.onDisplayChanged(dc);
         if (isLeafTask()) {
             final int displayId = (dc != null) ? dc.getDisplayId() : INVALID_DISPLAY;
@@ -2953,48 +2932,6 @@
         return mDragResizing;
     }
 
-    void adjustBoundsForDisplayChangeIfNeeded(final DisplayContent displayContent) {
-        if (displayContent == null) {
-            return;
-        }
-        if (getRequestedOverrideBounds().isEmpty()) {
-            return;
-        }
-        final int displayId = displayContent.getDisplayId();
-        final int newRotation = displayContent.getDisplayInfo().rotation;
-        if (displayId != mLastRotationDisplayId) {
-            // This task is on a display that it wasn't on. There is no point to keep the relative
-            // position if display rotations for old and new displays are different. Just keep these
-            // values.
-            mLastRotationDisplayId = displayId;
-            mRotation = newRotation;
-            return;
-        }
-
-        if (mRotation == newRotation) {
-            // Rotation didn't change. We don't need to adjust the bounds to keep the relative
-            // position.
-            return;
-        }
-
-        // Device rotation changed.
-        // - We don't want the task to move around on the screen when this happens, so update the
-        //   task bounds so it stays in the same place.
-        // - Rotate the bounds and notify activity manager if the task can be resized independently
-        //   from its root task. The root task will take care of task rotation for the other case.
-        mTmpRect2.set(getBounds());
-
-        if (!getWindowConfiguration().canResizeTask()) {
-            setBounds(mTmpRect2);
-            return;
-        }
-
-        displayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
-        if (setBounds(mTmpRect2) != BOUNDS_CHANGE_NONE) {
-            mAtmService.resizeTask(mTaskId, getBounds(), RESIZE_MODE_SYSTEM_SCREEN_ROTATION);
-        }
-    }
-
     /** Cancels any running app transitions associated with the task. */
     void cancelTaskWindowTransition() {
         for (int i = mChildren.size() - 1; i >= 0; --i) {
@@ -3525,8 +3462,6 @@
         info.isVisibleRequested = isVisibleRequested();
         info.isSleeping = shouldSleepActivities();
         info.isTopActivityTransparent = top != null && !top.fillsParent();
-        appCompatTaskInfo.isLetterboxDoubleTapEnabled = top != null
-                && top.mLetterboxUiController.isLetterboxDoubleTapEducationEnabled();
         appCompatTaskInfo.topActivityLetterboxVerticalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
         appCompatTaskInfo.topActivityLetterboxHorizontalPosition = TaskInfo.PROPERTY_VALUE_UNSET;
         appCompatTaskInfo.topActivityLetterboxWidth = TaskInfo.PROPERTY_VALUE_UNSET;
@@ -3541,15 +3476,29 @@
             appCompatTaskInfo.topActivityLetterboxWidth = top.getBounds().width();
             appCompatTaskInfo.topActivityLetterboxHeight = top.getBounds().height();
         }
+        // We need to consider if letterboxed or pillarboxed
+        // TODO(b/336807329) Encapsulate reachability logic
+        appCompatTaskInfo.isLetterboxDoubleTapEnabled = top != null
+                && top.mLetterboxUiController.isLetterboxDoubleTapEducationEnabled();
         if (appCompatTaskInfo.isLetterboxDoubleTapEnabled) {
             if (appCompatTaskInfo.isTopActivityPillarboxed()) {
-                // Pillarboxed
-                appCompatTaskInfo.topActivityLetterboxHorizontalPosition =
-                        top.mLetterboxUiController.getLetterboxPositionForHorizontalReachability();
+                if (top.mLetterboxUiController.allowHorizontalReachabilityForThinLetterbox()) {
+                    // Pillarboxed
+                    appCompatTaskInfo.topActivityLetterboxHorizontalPosition =
+                            top.mLetterboxUiController
+                                    .getLetterboxPositionForHorizontalReachability();
+                } else {
+                    appCompatTaskInfo.isLetterboxDoubleTapEnabled = false;
+                }
             } else {
-                // Letterboxed
-                appCompatTaskInfo.topActivityLetterboxVerticalPosition =
-                        top.mLetterboxUiController.getLetterboxPositionForVerticalReachability();
+                if (top.mLetterboxUiController.allowVerticalReachabilityForThinLetterbox()) {
+                    // Letterboxed
+                    appCompatTaskInfo.topActivityLetterboxVerticalPosition =
+                            top.mLetterboxUiController
+                                    .getLetterboxPositionForVerticalReachability();
+                } else {
+                    appCompatTaskInfo.isLetterboxDoubleTapEnabled = false;
+                }
             }
         }
         appCompatTaskInfo.topActivityEligibleForUserAspectRatioButton = top != null
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 2b631f7..6a7f60b 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -320,9 +320,9 @@
     /** Organizer that organizing this TaskFragment. */
     @Nullable
     private ITaskFragmentOrganizer mTaskFragmentOrganizer;
-    @VisibleForTesting
+
     int mTaskFragmentOrganizerUid = INVALID_UID;
-    private @Nullable String mTaskFragmentOrganizerProcessName;
+    @Nullable String mTaskFragmentOrganizerProcessName;
 
     /** Client assigned unique token for this TaskFragment if this is created by an organizer. */
     @Nullable
@@ -485,14 +485,16 @@
      */
     @Nullable
     private WindowProcessController getOrganizerProcessIfDifferent(@Nullable ActivityRecord r) {
-        if ((r == null || mTaskFragmentOrganizerProcessName == null)
-                || (mTaskFragmentOrganizerProcessName.equals(r.processName)
-                && mTaskFragmentOrganizerUid == r.getUid())) {
-            // No organizer or the process is the same.
+        final Task task = getTask();
+        if (r == null || task == null || task.mTaskFragmentHostProcessName == null) {
             return null;
         }
-        return mAtmService.getProcessController(mTaskFragmentOrganizerProcessName,
-                mTaskFragmentOrganizerUid);
+        if (task.mTaskFragmentHostProcessName.equals(r.processName)
+                && task.mTaskFragmentHostUid == r.getUid()) {
+            return null;
+        }
+        return mAtmService.getProcessController(task.mTaskFragmentHostProcessName,
+                task.mTaskFragmentHostUid);
     }
 
     void setAnimationParams(@NonNull TaskFragmentAnimationParams animationParams) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index c25080f..e90c845 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -858,6 +858,10 @@
      * {@link InsetsStateController#notifyInsetsChanged}.
      */
     boolean isReadyToDispatchInsetsState() {
+        if (mStartingData != null) {
+            // Starting window doesn't consider insets.
+            return false;
+        }
         final boolean visible = shouldCheckTokenVisibleRequested()
                 ? isVisibleRequested() : isVisible();
         return visible && mFrozenInsetsState == null;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 8755a80..cfe4e17 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -47,6 +47,7 @@
 import android.content.pm.PackageManagerInternal;
 import android.content.res.Configuration;
 import android.content.res.Resources.Theme;
+import android.crashrecovery.flags.Flags;
 import android.credentials.CredentialManager;
 import android.database.sqlite.SQLiteCompatibilityWalFlags;
 import android.database.sqlite.SQLiteGlobal;
@@ -1195,11 +1196,13 @@
         mSystemServiceManager.startService(RecoverySystemService.Lifecycle.class);
         t.traceEnd();
 
-        // Now that we have the bare essentials of the OS up and running, take
-        // note that we just booted, which might send out a rescue party if
-        // we're stuck in a runtime restart loop.
-        RescueParty.registerHealthObserver(mSystemContext);
-        PackageWatchdog.getInstance(mSystemContext).noteBoot();
+        if (!Flags.recoverabilityDetection()) {
+            // Now that we have the bare essentials of the OS up and running, take
+            // note that we just booted, which might send out a rescue party if
+            // we're stuck in a runtime restart loop.
+            RescueParty.registerHealthObserver(mSystemContext);
+            PackageWatchdog.getInstance(mSystemContext).noteBoot();
+        }
 
         // Manages LEDs and display backlight so we need it to bring up the display.
         t.traceBegin("StartLightsService");
@@ -1469,9 +1472,12 @@
         boolean enableVrService = context.getPackageManager().hasSystemFeature(
                 PackageManager.FEATURE_VR_MODE_HIGH_PERFORMANCE);
 
-        // For debugging RescueParty
-        if (Build.IS_DEBUGGABLE && SystemProperties.getBoolean("debug.crash_system", false)) {
-            throw new RuntimeException();
+        if (!Flags.recoverabilityDetection()) {
+            // For debugging RescueParty
+            if (Build.IS_DEBUGGABLE
+                    && SystemProperties.getBoolean("debug.crash_system", false)) {
+                throw new RuntimeException();
+            }
         }
 
         try {
@@ -2910,6 +2916,14 @@
         mPackageManagerService.systemReady();
         t.traceEnd();
 
+        if (Flags.recoverabilityDetection()) {
+            // Now that we have the essential services needed for rescue party, initialize
+            // RescuParty. note that we just booted, which might send out a rescue party if
+            // we're stuck in a runtime restart loop.
+            RescueParty.registerHealthObserver(mSystemContext);
+            PackageWatchdog.getInstance(mSystemContext).noteBoot();
+        }
+
         t.traceBegin("MakeDisplayManagerServiceReady");
         try {
             // TODO: use boot phase and communicate this flag some other way
@@ -3313,6 +3327,14 @@
      * are updated outside of OTA; and to avoid breaking dependencies from system into apexes.
      */
     private void startApexServices(@NonNull TimingsTraceAndSlog t) {
+        if (Flags.recoverabilityDetection()) {
+            // For debugging RescueParty
+            if (Build.IS_DEBUGGABLE
+                    && SystemProperties.getBoolean("debug.crash_system", false)) {
+                throw new RuntimeException();
+            }
+        }
+
         t.traceBegin("startApexServices");
         // TODO(b/192880996): get the list from "android" package, once the manifest entries
         // are migrated to system manifest.
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
index 79f1574..7d58a2e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserManagerServiceTest.java
@@ -778,6 +778,49 @@
     }
 
     @Test
+    public void testGetAliveUsers_shouldExcludeInitialisedEphemeralNonCurrentUsers() {
+        assertWithMessage("Ephemeral user should not exist at all initially")
+                .that(mUmi.getUsers(false).stream().anyMatch(u -> u.id == USER_ID))
+                .isFalse();
+
+        // add an ephemeral full user
+        TestUserData userData = new TestUserData(USER_ID);
+        userData.info.flags = UserInfo.FLAG_FULL | UserInfo.FLAG_EPHEMERAL;
+        addUserData(userData);
+
+        assertWithMessage("Ephemeral user should exist as alive after being created")
+                .that(mUmi.getUsers(true).stream().anyMatch(u -> u.id == USER_ID))
+                .isTrue();
+
+        // mock switch to the user (mark it as initialized & make it the current user)
+        userData.info.flags |= UserInfo.FLAG_INITIALIZED;
+        mockCurrentUser(USER_ID);
+
+        assertWithMessage("Ephemeral user should still exist as alive after being switched to")
+                .that(mUmi.getUsers(true).stream().anyMatch(u -> u.id == USER_ID))
+                .isTrue();
+
+        // switch away from the user
+        mockCurrentUser(OTHER_USER_ID);
+
+        assertWithMessage("Ephemeral user should not exist as alive after getting switched away")
+                .that(mUmi.getUsers(true).stream().anyMatch(u -> u.id == USER_ID))
+                .isFalse();
+
+        assertWithMessage("Ephemeral user should still exist as dying after getting switched away")
+                .that(mUmi.getUsers(false).stream().anyMatch(u -> u.id == USER_ID))
+                .isTrue();
+
+        // finally remove the user
+        mUms.removeUserInfo(USER_ID);
+
+        assertWithMessage("Ephemeral user should not exist at all after cleanup")
+                .that(mUmi.getUsers(false).stream().anyMatch(u -> u.id == USER_ID))
+                .isFalse();
+    }
+
+
+    @Test
     @RequiresFlagsEnabled({android.os.Flags.FLAG_ALLOW_PRIVATE_PROFILE,
             Flags.FLAG_BLOCK_PRIVATE_SPACE_CREATION, Flags.FLAG_ENABLE_PRIVATE_SPACE_FEATURES})
     public void testCreatePrivateProfileOnHeadlessSystemUser_shouldAllowCreation() {
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 5fdb396..d1423fe 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -3002,39 +3002,45 @@
         assertEquals(ZEN_MODE_OFF, mZenModeHelper.mZenMode);
     }
 
-    private enum ModesApiFlag {
-        ENABLED(true, /* originForUserActionInSystemUi= */ UPDATE_ORIGIN_USER),
-        DISABLED(false, /* originForUserActionInSystemUi= */ UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI);
+    private enum ModesFlag {
+        MODES_UI(2, /* originForUserActionInSystemUi= */ UPDATE_ORIGIN_USER),
+        MODES_API(1, /* originForUserActionInSystemUi= */ UPDATE_ORIGIN_USER),
+        DISABLED(0, /* originForUserActionInSystemUi= */ UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI);
 
-        private final boolean mEnabled;
+        private final int mFlagsEnabled;
         @ConfigChangeOrigin
         private final int mOriginForUserActionInSystemUi;
 
-        ModesApiFlag(boolean enabled, @ConfigChangeOrigin int originForUserActionInSystemUi) {
-            this.mEnabled = enabled;
+        ModesFlag(int flagsEnabled, @ConfigChangeOrigin int originForUserActionInSystemUi) {
+            this.mFlagsEnabled = flagsEnabled;
             this.mOriginForUserActionInSystemUi = originForUserActionInSystemUi;
         }
 
-        void applyFlag(SetFlagsRule setFlagsRule) {
-            if (mEnabled) {
+        void applyFlags(SetFlagsRule setFlagsRule) {
+            if (mFlagsEnabled >= 1) {
                 setFlagsRule.enableFlags(Flags.FLAG_MODES_API);
             } else {
                 setFlagsRule.disableFlags(Flags.FLAG_MODES_API);
             }
+            if (mFlagsEnabled >= 2) {
+                setFlagsRule.enableFlags(Flags.FLAG_MODES_UI);
+            } else {
+                setFlagsRule.disableFlags(Flags.FLAG_MODES_UI);
+            }
         }
     }
 
     @Test
-    public void testZenModeEventLog_setManualZenMode(@TestParameter ModesApiFlag modesApiFlag)
+    public void testZenModeEventLog_setManualZenMode(@TestParameter ModesFlag modesFlag)
             throws IllegalArgumentException {
-        modesApiFlag.applyFlag(mSetFlagsRule);
+        modesFlag.applyFlags(mSetFlagsRule);
         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
         setupZenConfig();
 
         // Turn zen mode on (to important_interruptions)
         // Need to additionally call the looper in order to finish the post-apply-config process
         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
-                modesApiFlag.mOriginForUserActionInSystemUi, "", null, Process.SYSTEM_UID);
+                modesFlag.mOriginForUserActionInSystemUi, "", null, Process.SYSTEM_UID);
 
         // Now turn zen mode off, but via a different package UID -- this should get registered as
         // "not an action by the user" because some other app is changing zen mode
@@ -3062,7 +3068,7 @@
         assertEquals(DNDProtoEnums.MANUAL_RULE, mZenModeEventLogger.getChangedRuleType(0));
         assertEquals(1, mZenModeEventLogger.getNumRulesActive(0));
         assertThat(mZenModeEventLogger.getFromSystemOrSystemUi(0)).isEqualTo(
-                modesApiFlag == ModesApiFlag.DISABLED);
+                modesFlag == ModesFlag.DISABLED);
         assertTrue(mZenModeEventLogger.getIsUserAction(0));
         assertEquals(Process.SYSTEM_UID, mZenModeEventLogger.getPackageUid(0));
         checkDndProtoMatchesSetupZenConfig(mZenModeEventLogger.getPolicyProto(0));
@@ -3091,9 +3097,9 @@
     }
 
     @Test
-    public void testZenModeEventLog_automaticRules(@TestParameter ModesApiFlag modesApiFlag)
+    public void testZenModeEventLog_automaticRules(@TestParameter ModesFlag modesFlag)
             throws IllegalArgumentException {
-        modesApiFlag.applyFlag(mSetFlagsRule);
+        modesFlag.applyFlags(mSetFlagsRule);
         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
         setupZenConfig();
 
@@ -3116,7 +3122,7 @@
         // Event 2: "User" turns off the automatic rule (sets it to not enabled)
         zenRule.setEnabled(false);
         mZenModeHelper.updateAutomaticZenRule(id, zenRule,
-                modesApiFlag.mOriginForUserActionInSystemUi, "", Process.SYSTEM_UID);
+                modesFlag.mOriginForUserActionInSystemUi, "", Process.SYSTEM_UID);
 
         // Add a new system rule
         AutomaticZenRule systemRule = new AutomaticZenRule("systemRule",
@@ -3134,7 +3140,7 @@
                 UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Event 4: "User" deletes the rule
-        mZenModeHelper.removeAutomaticZenRule(systemId, modesApiFlag.mOriginForUserActionInSystemUi,
+        mZenModeHelper.removeAutomaticZenRule(systemId, modesFlag.mOriginForUserActionInSystemUi,
                 "", Process.SYSTEM_UID);
 
         // In total, this represents 4 events
@@ -3282,22 +3288,22 @@
     }
 
     @Test
-    public void testZenModeEventLog_policyChanges(@TestParameter ModesApiFlag modesApiFlag)
+    public void testZenModeEventLog_policyChanges(@TestParameter ModesFlag modesFlag)
             throws IllegalArgumentException {
-        modesApiFlag.applyFlag(mSetFlagsRule);
+        modesFlag.applyFlags(mSetFlagsRule);
         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
         setupZenConfig();
 
         // First just turn zen mode on
         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
-                modesApiFlag.mOriginForUserActionInSystemUi, "", null, Process.SYSTEM_UID);
+                modesFlag.mOriginForUserActionInSystemUi, "", null, Process.SYSTEM_UID);
 
         // Now change the policy slightly; want to confirm that this'll be reflected in the logs
         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
         newConfig.allowAlarms = true;
         newConfig.allowRepeatCallers = false;
         mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
-                modesApiFlag.mOriginForUserActionInSystemUi, Process.SYSTEM_UID);
+                modesFlag.mOriginForUserActionInSystemUi, Process.SYSTEM_UID);
 
         // Turn zen mode off; we want to make sure policy changes do not get logged when zen mode
         // is off.
@@ -3308,7 +3314,7 @@
         newConfig.allowMessages = false;
         newConfig.allowRepeatCallers = true;
         mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
-                modesApiFlag.mOriginForUserActionInSystemUi, Process.SYSTEM_UID);
+                modesFlag.mOriginForUserActionInSystemUi, Process.SYSTEM_UID);
 
         // Total events: we only expect ones for turning on, changing policy, and turning off
         assertEquals(3, mZenModeEventLogger.numLoggedChanges());
@@ -3341,9 +3347,9 @@
     }
 
     @Test
-    public void testZenModeEventLog_ruleCounts(@TestParameter ModesApiFlag modesApiFlag)
+    public void testZenModeEventLog_ruleCounts(@TestParameter ModesFlag modesFlag)
             throws IllegalArgumentException {
-        modesApiFlag.applyFlag(mSetFlagsRule);
+        modesFlag.applyFlags(mSetFlagsRule);
         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
         setupZenConfig();
 
@@ -3447,9 +3453,9 @@
 
     @Test
     public void testZenModeEventLog_noLogWithNoConfigChange(
-            @TestParameter ModesApiFlag modesApiFlag) throws IllegalArgumentException {
+            @TestParameter ModesFlag modesFlag) throws IllegalArgumentException {
         // If evaluateZenMode is called independently of a config change, don't log.
-        modesApiFlag.applyFlag(mSetFlagsRule);
+        modesFlag.applyFlags(mSetFlagsRule);
         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
         setupZenConfig();
 
@@ -3466,11 +3472,11 @@
     }
 
     @Test
-    public void testZenModeEventLog_reassignUid(@TestParameter ModesApiFlag modesApiFlag)
+    public void testZenModeEventLog_reassignUid(@TestParameter ModesFlag modesFlag)
             throws IllegalArgumentException {
         // Test that, only in specific cases, we reassign the calling UID to one associated with
         // the automatic rule owner.
-        modesApiFlag.applyFlag(mSetFlagsRule);
+        modesFlag.applyFlags(mSetFlagsRule);
         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
         setupZenConfig();
 
@@ -3496,7 +3502,7 @@
                 manualRulePolicy,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2,
-                modesApiFlag.mOriginForUserActionInSystemUi, "test", Process.SYSTEM_UID);
+                modesFlag.mOriginForUserActionInSystemUi, "test", Process.SYSTEM_UID);
 
         // Turn on rule 1; call looks like it's from the system. Because setting a condition is
         // typically an automatic (non-user-initiated) action, expect the calling UID to be
@@ -3515,7 +3521,7 @@
         // from the system-provided one.
         zenRule.setEnabled(false);
         mZenModeHelper.updateAutomaticZenRule(id, zenRule,
-                modesApiFlag.mOriginForUserActionInSystemUi, "", Process.SYSTEM_UID);
+                modesFlag.mOriginForUserActionInSystemUi, "", Process.SYSTEM_UID);
 
         // Add a manual rule. Any manual rule changes should not get calling uids reassigned.
         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, UPDATE_ORIGIN_APP,
@@ -3573,9 +3579,9 @@
 
     @Test
     public void testZenModeEventLog_channelsBypassingChanges(
-            @TestParameter ModesApiFlag modesApiFlag) {
+            @TestParameter ModesFlag modesFlag) {
         // Verify that the right thing happens when the canBypassDnd value changes.
-        modesApiFlag.applyFlag(mSetFlagsRule);
+        modesFlag.applyFlags(mSetFlagsRule);
         mTestFlagResolver.setFlagOverride(LOG_DND_STATE_EVENTS, true);
         setupZenConfig();
 
@@ -3847,8 +3853,9 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_MODES_API)
-    public void testUpdateConsolidatedPolicy_modesApiDefaultRulesOnly_takesDeviceDefault() {
+    public void testUpdateConsolidatedPolicy_modesApiDefaultRulesOnly_takesDefault(
+            @TestParameter({"MODES_UI", "MODES_API"}) ModesFlag modesFlag) {
+        modesFlag.applyFlags(mSetFlagsRule);
         setupZenConfig();
 
         // When there's one automatic rule active and it doesn't specify a policy, test that the
@@ -3869,7 +3876,9 @@
 
         // inspect the consolidated policy, which should match the device default settings.
         assertThat(ZenAdapters.notificationPolicyToZenPolicy(mZenModeHelper.mConsolidatedPolicy))
-                .isEqualTo(mZenModeHelper.getDefaultZenPolicy());
+                .isEqualTo(modesFlag == ModesFlag.MODES_UI
+                        ? mZenModeHelper.getDefaultZenPolicy()
+                        : mZenModeHelper.mConfig.toZenPolicy());
     }
 
     @Test
@@ -3904,7 +3913,8 @@
                 UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // since this is the only active rule, the consolidated policy should match the custom
-        // policy for every field specified, and take default values for unspecified things
+        // policy for every field specified, and take default values (from device default or
+        // manual policy) for unspecified things
         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowAlarms());  // custom
         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowMedia());  // custom
         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowSystem());  // default
@@ -3918,8 +3928,9 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_MODES_API)
-    public void testUpdateConsolidatedPolicy_modesApiCustomPolicyOnly_fillInWithDeviceDefault() {
+    public void testUpdateConsolidatedPolicy_modesApiCustomPolicyOnly_fillInWithDefault(
+            @TestParameter({"MODES_UI", "MODES_API"}) ModesFlag modesFlag) {
+        modesFlag.applyFlags(mSetFlagsRule);
         setupZenConfig();
 
         // when there's only one automatic rule active and it has a custom policy, make sure that's
@@ -3948,11 +3959,15 @@
                 UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // since this is the only active rule, the consolidated policy should match the custom
-        // policy for every field specified, and take default values for unspecified things
-        assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isTrue();  // default
-        assertThat(mZenModeHelper.mConsolidatedPolicy.allowMedia()).isTrue();  // default
+        // policy for every field specified, and take default values (from either device default
+        // policy or manual rule) for unspecified things
+        assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isEqualTo(
+                modesFlag == ModesFlag.MODES_UI ? true : false);  // default
+        assertThat(mZenModeHelper.mConsolidatedPolicy.allowMedia()).isEqualTo(
+                modesFlag == ModesFlag.MODES_UI ? true : false);  // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowSystem()).isTrue();  // custom
-        assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isFalse();  // default
+        assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isEqualTo(
+                modesFlag == ModesFlag.MODES_UI ? false : true);  // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowCalls()).isFalse();  // custom
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMessages()).isTrue(); // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers()).isFalse();  // custom
@@ -4022,8 +4037,9 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_MODES_API)
-    public void testUpdateConsolidatedPolicy_modesApiDefaultAndCustomActive_mergesWithDefault() {
+    public void testUpdateConsolidatedPolicy_modesApiDefaultAndCustomActive_mergesWithDefault(
+            @TestParameter({"MODES_UI", "MODES_API"}) ModesFlag modesFlag) {
+        modesFlag.applyFlags(mSetFlagsRule);
         setupZenConfig();
 
         // when there are two rules active, one inheriting the default policy and one setting its
@@ -4071,16 +4087,19 @@
         // now both rules should be on, and the consolidated policy should reflect the most
         // restrictive option of each of the two
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isFalse();  // custom stricter
-        assertThat(mZenModeHelper.mConsolidatedPolicy.allowMedia()).isTrue();  // default
+        assertThat(mZenModeHelper.mConsolidatedPolicy.allowMedia()).isEqualTo(
+                modesFlag == ModesFlag.MODES_UI ? true : false);  // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowSystem()).isFalse();  // default stricter
-        assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isFalse();  // default
+        assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isEqualTo(
+                modesFlag == ModesFlag.MODES_UI ? false : true);  // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowCalls()).isFalse();  // custom stricter
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMessages()).isTrue(); // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowConversations()).isTrue();  // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowRepeatCallers())
                 .isFalse();  // custom stricter
         assertThat(mZenModeHelper.mConsolidatedPolicy.showBadges()).isFalse();  // custom stricter
-        assertThat(mZenModeHelper.mConsolidatedPolicy.showPeeking()).isFalse();  // default stricter
+        assertThat(mZenModeHelper.mConsolidatedPolicy.showPeeking()).isEqualTo(
+                modesFlag == ModesFlag.MODES_UI ? false : true);  // default
     }
 
     @Test
@@ -4134,8 +4153,9 @@
     }
 
     @Test
-    @EnableFlags(Flags.FLAG_MODES_API)
-    public void testUpdateConsolidatedPolicy_ignoresActiveRulesWithInterruptionFilterAll() {
+    public void testUpdateConsolidatedPolicy_ignoresActiveRulesWithInterruptionFilterAll(
+            @TestParameter({"MODES_UI", "MODES_API"}) ModesFlag modesFlag) {
+        modesFlag.applyFlags(mSetFlagsRule);
         setupZenConfig();
 
         // Rules with INTERRUPTION_FILTER_ALL are skipped when calculating consolidated policy.
@@ -4172,10 +4192,12 @@
                 UPDATE_ORIGIN_APP, CUSTOM_PKG_UID);
 
         // Consolidated Policy should be default + rule1.
-        assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isTrue();  // default
+        assertThat(mZenModeHelper.mConsolidatedPolicy.allowAlarms()).isEqualTo(
+                modesFlag == ModesFlag.MODES_UI ? true : false);  // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMedia()).isTrue(); // priority rule
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowSystem()).isTrue();  // priority rule
-        assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isFalse();  // default
+        assertThat(mZenModeHelper.mConsolidatedPolicy.allowReminders()).isEqualTo(
+                modesFlag == ModesFlag.MODES_UI ? false : true);  // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowCalls()).isTrue();  // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowMessages()).isTrue(); // default
         assertThat(mZenModeHelper.mConsolidatedPolicy.allowConversations()).isTrue();  // default
@@ -6251,7 +6273,7 @@
     }
 
     private void checkDndProtoMatchesDefaultZenConfig(DNDPolicyProto dndProto) {
-        if (!Flags.modesApi()) {
+        if (!Flags.modesUi()) {
             checkDndProtoMatchesSetupZenConfig(dndProto);
             return;
         }
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 10eae57..1355092 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -46,7 +46,6 @@
 import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
 import static android.os.Process.SYSTEM_UID;
-import static android.server.wm.ActivityManagerTestBase.isTablet;
 
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.clearInvocations;
 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
@@ -76,7 +75,6 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assume.assumeFalse;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
@@ -124,7 +122,6 @@
 import com.android.server.wm.BackgroundActivityStartController.BalVerdict;
 import com.android.server.wm.LaunchParamsController.LaunchParamsModifier;
 import com.android.server.wm.utils.MockTracker;
-import com.android.window.flags.Flags;
 
 import org.junit.After;
 import org.junit.Before;
@@ -1298,12 +1295,6 @@
      */
     @Test
     public void testDeliverIntentToTopActivityOfNonTopDisplay() {
-        // TODO(b/330152508): Remove check once legacy multi-display behaviour can coexist with
-        //  desktop windowing mode
-        // Ignore test if desktop windowing is enabled on tablets as legacy multi-display
-        // behaviour will not be respected
-        assumeFalse(Flags.enableDesktopWindowingMode() && isTablet());
-
         final ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK,
                 false /* mockGetRootTask */);
 
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index b74da1a..a60d243 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -85,6 +85,8 @@
 import android.content.pm.PackageManager.Property;
 import android.content.res.Resources;
 import android.graphics.Rect;
+import android.platform.test.annotations.DisableFlags;
+import android.platform.test.annotations.EnableFlags;
 import android.platform.test.annotations.Presubmit;
 import android.view.InsetsSource;
 import android.view.InsetsState;
@@ -96,6 +98,7 @@
 import androidx.test.filters.SmallTest;
 
 import com.android.internal.R;
+import com.android.window.flags.Flags;
 
 import libcore.junit.util.compat.CoreCompatChangeRule.DisableCompatChanges;
 import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
@@ -1528,6 +1531,98 @@
                         mActivity.getParent().getConfiguration()), /* delta */  0.01);
     }
 
+    @Test
+    public void testIsVerticalThinLetterboxed() {
+        // Vertical thin letterbox disabled
+        doReturn(-1).when(mActivity.mWmService.mLetterboxConfiguration)
+                .getThinLetterboxHeightPx();
+        assertFalse(mController.isVerticalThinLetterboxed());
+        // Define a Task 100x100
+        final Task task = mock(Task.class);
+        doReturn(new Rect(0, 0, 100, 100)).when(task).getBounds();
+        doReturn(10).when(mActivity.mWmService.mLetterboxConfiguration)
+                .getThinLetterboxHeightPx();
+
+        // Vertical thin letterbox disabled without Task
+        doReturn(null).when(mActivity).getTask();
+        assertFalse(mController.isVerticalThinLetterboxed());
+        // Assign a Task for the Activity
+        doReturn(task).when(mActivity).getTask();
+
+        // (task.width() - act.width()) / 2  = 5 < 10
+        doReturn(new Rect(5, 5, 95, 95)).when(mActivity).getBounds();
+        assertTrue(mController.isVerticalThinLetterboxed());
+
+        // (task.width() - act.width()) / 2  = 10 = 10
+        doReturn(new Rect(10, 10, 90, 90)).when(mActivity).getBounds();
+        assertTrue(mController.isVerticalThinLetterboxed());
+
+        // (task.width() - act.width()) / 2  = 11 > 10
+        doReturn(new Rect(11, 11, 89, 89)).when(mActivity).getBounds();
+        assertFalse(mController.isVerticalThinLetterboxed());
+    }
+
+    @Test
+    public void testIsHorizontalThinLetterboxed() {
+        // Horizontal thin letterbox disabled
+        doReturn(-1).when(mActivity.mWmService.mLetterboxConfiguration)
+                .getThinLetterboxWidthPx();
+        assertFalse(mController.isHorizontalThinLetterboxed());
+        // Define a Task 100x100
+        final Task task = mock(Task.class);
+        doReturn(new Rect(0, 0, 100, 100)).when(task).getBounds();
+        doReturn(10).when(mActivity.mWmService.mLetterboxConfiguration)
+                .getThinLetterboxWidthPx();
+
+        // Vertical thin letterbox disabled without Task
+        doReturn(null).when(mActivity).getTask();
+        assertFalse(mController.isHorizontalThinLetterboxed());
+        // Assign a Task for the Activity
+        doReturn(task).when(mActivity).getTask();
+
+        // (task.height() - act.height()) / 2  = 5 < 10
+        doReturn(new Rect(5, 5, 95, 95)).when(mActivity).getBounds();
+        assertTrue(mController.isHorizontalThinLetterboxed());
+
+        // (task.height() - act.height()) / 2  = 10 = 10
+        doReturn(new Rect(10, 10, 90, 90)).when(mActivity).getBounds();
+        assertTrue(mController.isHorizontalThinLetterboxed());
+
+        // (task.height() - act.height()) / 2  = 11 > 10
+        doReturn(new Rect(11, 11, 89, 89)).when(mActivity).getBounds();
+        assertFalse(mController.isHorizontalThinLetterboxed());
+    }
+
+    @Test
+    @EnableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_REACHABILITY)
+    public void testAllowReachabilityForThinLetterboxWithFlagEnabled() {
+        spyOn(mController);
+        doReturn(true).when(mController).isVerticalThinLetterboxed();
+        assertFalse(mController.allowVerticalReachabilityForThinLetterbox());
+        doReturn(true).when(mController).isHorizontalThinLetterboxed();
+        assertFalse(mController.allowHorizontalReachabilityForThinLetterbox());
+
+        doReturn(false).when(mController).isVerticalThinLetterboxed();
+        assertTrue(mController.allowVerticalReachabilityForThinLetterbox());
+        doReturn(false).when(mController).isHorizontalThinLetterboxed();
+        assertTrue(mController.allowHorizontalReachabilityForThinLetterbox());
+    }
+
+    @Test
+    @DisableFlags(Flags.FLAG_DISABLE_THIN_LETTERBOXING_REACHABILITY)
+    public void testAllowReachabilityForThinLetterboxWithFlagDisabled() {
+        spyOn(mController);
+        doReturn(true).when(mController).isVerticalThinLetterboxed();
+        assertTrue(mController.allowVerticalReachabilityForThinLetterbox());
+        doReturn(true).when(mController).isHorizontalThinLetterboxed();
+        assertTrue(mController.allowHorizontalReachabilityForThinLetterbox());
+
+        doReturn(false).when(mController).isVerticalThinLetterboxed();
+        assertTrue(mController.allowVerticalReachabilityForThinLetterbox());
+        doReturn(false).when(mController).isHorizontalThinLetterboxed();
+        assertTrue(mController.allowHorizontalReachabilityForThinLetterbox());
+    }
+
     private void mockThatProperty(String propertyName, boolean value) throws Exception {
         Property property = new Property(propertyName, /* value */ value, /* packageName */ "",
                 /* className */ "");
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 8677738..6b605ec 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -3646,11 +3646,27 @@
     }
 
     @Test
+    public void testIsReachabilityEnabled_thisLetterbox_false() {
+        // Case when the reachability would be enabled otherwise
+        setUpDisplaySizeWithApp(/* dw */ 1000, /* dh */ 2800);
+        mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+        mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
+        prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
+        mActivity.getWindowConfiguration().setBounds(null);
+
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ false);
+
+        assertFalse(mActivity.mLetterboxUiController.isVerticalReachabilityEnabled());
+        assertFalse(mActivity.mLetterboxUiController.isHorizontalReachabilityEnabled());
+    }
+
+    @Test
     public void testIsHorizontalReachabilityEnabled_splitScreen_false() {
         mAtm.mDevEnableNonResizableMultiWindow = true;
         setUpDisplaySizeWithApp(2800, 1000);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
         final TestSplitOrganizer organizer =
                 new TestSplitOrganizer(mAtm, mActivity.getDisplayContent());
 
@@ -3673,6 +3689,7 @@
         setUpDisplaySizeWithApp(1000, 2800);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
         final TestSplitOrganizer organizer =
                 new TestSplitOrganizer(mAtm, mActivity.getDisplayContent());
 
@@ -3694,6 +3711,7 @@
         setUpDisplaySizeWithApp(1000, 2800);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
         // Unresizable landscape-only activity.
         prepareUnresizable(mActivity, 1.1f, SCREEN_ORIENTATION_LANDSCAPE);
@@ -3715,6 +3733,7 @@
         setUpDisplaySizeWithApp(/* dw */ 1000, /* dh */ 2800);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
 
@@ -3731,6 +3750,7 @@
         setUpDisplaySizeWithApp(/* dw */ 2800, /* dh */ 1000);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
 
@@ -3747,6 +3767,7 @@
         // Portrait display
         setUpDisplaySizeWithApp(1400, 1600);
         mActivity.mWmService.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
         // 16:9f unresizable portrait app
         prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
@@ -3760,6 +3781,7 @@
         // Landscape display
         setUpDisplaySizeWithApp(1600, 1500);
         mActivity.mWmService.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
         // 16:9f unresizable landscape app
         prepareMinAspectRatio(mActivity, OVERRIDE_MIN_ASPECT_RATIO_LARGE_VALUE,
@@ -3773,6 +3795,7 @@
         setUpDisplaySizeWithApp(2800, 1000);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
         // Unresizable portrait-only activity.
         prepareUnresizable(mActivity, 1.1f, SCREEN_ORIENTATION_PORTRAIT);
@@ -3794,6 +3817,7 @@
         setUpDisplaySizeWithApp(1800, 2200);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsHorizontalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
         // Unresizable portrait-only activity.
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_PORTRAIT);
@@ -3815,6 +3839,7 @@
         setUpDisplaySizeWithApp(2200, 1800);
         mActivity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
         mWm.mLetterboxConfiguration.setIsVerticalReachabilityEnabled(true);
+        setUpAllowThinLetterboxed(/* thinLetterboxAllowed */ true);
 
         // Unresizable landscape-only activity.
         prepareUnresizable(mActivity, SCREEN_ORIENTATION_LANDSCAPE);
@@ -5011,6 +5036,14 @@
         assertFalse(activity.shouldSendCompatFakeFocus());
     }
 
+    private void setUpAllowThinLetterboxed(boolean thinLetterboxAllowed) {
+        spyOn(mActivity.mLetterboxUiController);
+        doReturn(thinLetterboxAllowed).when(mActivity.mLetterboxUiController)
+                .allowVerticalReachabilityForThinLetterbox();
+        doReturn(thinLetterboxAllowed).when(mActivity.mLetterboxUiController)
+                .allowHorizontalReachabilityForThinLetterbox();
+    }
+
     private int getExpectedSplitSize(int dimensionToSplit) {
         int dividerWindowWidth =
                 mActivity.mWmService.mContext.getResources().getDimensionPixelSize(
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index 83e4151..afa6698 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -487,6 +487,16 @@
         // Flush EVENT_APPEARED.
         mController.dispatchPendingEvents();
 
+        // Even if the activity is not launched in an organized TaskFragment, it is still considered
+        // as the remote activity to the organizer process. Because when the task becomes visible,
+        // the organizer process needs to be interactive (unfrozen) to receive TaskFragment events.
+        activity.setVisibleRequested(true);
+        activity.setState(ActivityRecord.State.RESUMED, "test");
+        assertTrue(organizerProc.hasVisibleActivities());
+        activity.setVisibleRequested(false);
+        activity.setState(ActivityRecord.State.STOPPED, "test");
+        assertFalse(organizerProc.hasVisibleActivities());
+
         // Make sure the activity belongs to the same app, but it is in a different pid.
         activity.info.applicationInfo.uid = uid;
         doReturn(pid + 1).when(activity).getPid();
diff --git a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
index 40537c8..6d53c27 100644
--- a/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
+++ b/services/usb/java/com/android/server/usb/UsbProfileGroupSettingsManager.java
@@ -16,6 +16,8 @@
 
 package com.android.server.usb;
 
+import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
+
 import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
 
 import android.Manifest;
@@ -43,6 +45,7 @@
 import android.os.Environment;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
 import android.service.usb.UsbProfileGroupSettingsManagerProto;
 import android.service.usb.UsbSettingsAccessoryPreferenceProto;
 import android.service.usb.UsbSettingsDevicePreferenceProto;
@@ -939,13 +942,24 @@
     }
 
     /**
-     * @return true if any application in foreground have set restrict_usb_overlay_activities as
-     * true in manifest file. The application needs to have MANAGE_USB permission.
+     * @return true if the user has not finished the setup process or if there are any
+     * foreground applications with MANAGE_USB permission and restrict_usb_overlay_activities
+     * enabled in the manifest file.
      */
     private boolean shouldRestrictOverlayActivities() {
 
         if (!Flags.allowRestrictionOfOverlayActivities()) return false;
 
+        if (Settings.Secure.getIntForUser(
+                mContext.getContentResolver(),
+                USER_SETUP_COMPLETE,
+                /* defaultValue= */ 1,
+                UserHandle.CURRENT.getIdentifier())
+                == 0) {
+            Slog.d(TAG, "restricting usb overlay activities as setup is not complete");
+            return true;
+        }
+
         List<ActivityManager.RunningAppProcessInfo> appProcessInfos = mActivityManager
                 .getRunningAppProcesses();
 
diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp
index f0bea3f..2909e66 100644
--- a/tests/UsbManagerTests/Android.bp
+++ b/tests/UsbManagerTests/Android.bp
@@ -43,6 +43,9 @@
         "libmultiplejvmtiagentsinterferenceagent",
         "libstaticjvmtiagent",
     ],
+    libs: [
+        "android.test.mock",
+    ],
     certificate: "platform",
     platform_apis: true,
     test_suites: ["device-tests"],
diff --git a/tests/UsbManagerTests/src/com/android/server/usbtest/UsbProfileGroupSettingsManagerTest.java b/tests/UsbManagerTests/src/com/android/server/usbtest/UsbProfileGroupSettingsManagerTest.java
index 4780d8a..87b26a6 100644
--- a/tests/UsbManagerTests/src/com/android/server/usbtest/UsbProfileGroupSettingsManagerTest.java
+++ b/tests/UsbManagerTests/src/com/android/server/usbtest/UsbProfileGroupSettingsManagerTest.java
@@ -16,6 +16,8 @@
 
 package com.android.server.usbtest;
 
+import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
+
 import static com.android.server.usb.UsbProfileGroupSettingsManager.PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES;
 
 import static org.mockito.ArgumentMatchers.any;
@@ -32,16 +34,20 @@
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.content.pm.PackageManager.Property;
 import android.content.pm.UserInfo;
 import android.content.res.Resources;
 import android.hardware.usb.UsbDevice;
 import android.os.UserHandle;
 import android.os.UserManager;
+import android.provider.Settings;
+import android.test.mock.MockContentResolver;
 
 import androidx.test.runner.AndroidJUnit4;
 
 import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.internal.util.test.FakeSettingsProvider;
 import com.android.server.usb.UsbHandlerManager;
 import com.android.server.usb.UsbProfileGroupSettingsManager;
 import com.android.server.usb.UsbSettingsManager;
@@ -69,6 +75,7 @@
 public class UsbProfileGroupSettingsManagerTest {
 
     private static final String TEST_PACKAGE_NAME = "testPkg";
+
     @Mock
     private Context mContext;
     @Mock
@@ -85,43 +92,78 @@
     private UserManager mUserManager;
     @Mock
     private UsbUserSettingsManager mUsbUserSettingsManager;
-    @Mock private Property mProperty;
-    private ActivityManager.RunningAppProcessInfo mRunningAppProcessInfo;
-    private PackageInfo mPackageInfo;
-    private UsbProfileGroupSettingsManager mUsbProfileGroupSettingsManager;
+    @Mock
+    private Property mRestrictUsbOverlayActivitiesProperty;
+    @Mock
+    private UsbDevice mUsbDevice;
+
+    private MockContentResolver mContentResolver;
     private MockitoSession mStaticMockSession;
 
+    private UsbProfileGroupSettingsManager mUsbProfileGroupSettingsManager;
+
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
-
-        mRunningAppProcessInfo = new ActivityManager.RunningAppProcessInfo();
-        mRunningAppProcessInfo.pkgList = new String[]{TEST_PACKAGE_NAME};
-        mPackageInfo = new PackageInfo();
-        mPackageInfo.packageName = TEST_PACKAGE_NAME;
-        mPackageInfo.applicationInfo = Mockito.mock(ApplicationInfo.class);
-
-        when(mContext.getPackageManager()).thenReturn(mPackageManager);
-        when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
-        when(mContext.getResources()).thenReturn(Mockito.mock(Resources.class));
-        when(mContext.createPackageContextAsUser(anyString(), anyInt(), any(UserHandle.class)))
-                .thenReturn(mContext);
-        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
-
-        mUsbProfileGroupSettingsManager = new UsbProfileGroupSettingsManager(mContext, mUserHandle,
-                mUsbSettingsManager, mUsbHandlerManager);
-
         mStaticMockSession = ExtendedMockito.mockitoSession()
                 .mockStatic(Flags.class)
                 .strictness(Strictness.WARN)
                 .startMocking();
 
-        when(mPackageManager.getPackageInfo(TEST_PACKAGE_NAME, 0)).thenReturn(mPackageInfo);
-        when(mPackageManager.getProperty(eq(PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES),
-                eq(TEST_PACKAGE_NAME))).thenReturn(mProperty);
+        when(mUsbSettingsManager.getSettingsForUser(anyInt())).thenReturn(mUsbUserSettingsManager);
         when(mUserManager.getEnabledProfiles(anyInt()))
                 .thenReturn(List.of(Mockito.mock(UserInfo.class)));
-        when(mUsbSettingsManager.getSettingsForUser(anyInt())).thenReturn(mUsbUserSettingsManager);
+
+        mContentResolver = new MockContentResolver();
+        mContentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
+
+        when(mContext.getContentResolver()).thenReturn(mContentResolver);
+        when(mContext.getPackageManager()).thenReturn(mPackageManager);
+        when(mContext.getResources()).thenReturn(Mockito.mock(Resources.class));
+        when(mContext.getSystemService(Context.USER_SERVICE)).thenReturn(mUserManager);
+        when(mContext.getSystemService(ActivityManager.class)).thenReturn(mActivityManager);
+        when(mContext.createPackageContextAsUser(anyString(), anyInt(), any(UserHandle.class)))
+                .thenReturn(mContext);
+
+        mUsbProfileGroupSettingsManager = new UsbProfileGroupSettingsManager(
+                mContext, mUserHandle, mUsbSettingsManager, mUsbHandlerManager);
+
+        setupDefaultConfiguration();
+    }
+
+    /**
+     * Setups the following configuration
+     *
+     * <ul>
+     * <li>Flag is enabled
+     * <li>Device setup has completed
+     * <li>There is a foreground activity with MANAGE_USB permission
+     * <li>The foreground activity has PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES enabled
+     * </ul>
+     */
+    private void setupDefaultConfiguration() throws NameNotFoundException {
+        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
+
+        Settings.Secure.putInt(mContentResolver, USER_SETUP_COMPLETE, 1);
+
+        ActivityManager.RunningAppProcessInfo mRunningAppProcessInfo =
+                new ActivityManager.RunningAppProcessInfo();
+        mRunningAppProcessInfo.pkgList = new String[] { TEST_PACKAGE_NAME };
+        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
+
+        PackageInfo mPackageInfo = new PackageInfo();
+        mPackageInfo.packageName = TEST_PACKAGE_NAME;
+        mPackageInfo.applicationInfo = Mockito.mock(ApplicationInfo.class);
+        when(mPackageManager.getPackageInfo(TEST_PACKAGE_NAME, 0)).thenReturn(mPackageInfo);
+        when(mPackageManager.getPackagesHoldingPermissions(
+                new String[] { android.Manifest.permission.MANAGE_USB },
+                PackageManager.MATCH_SYSTEM_ONLY))
+                .thenReturn(List.of(mPackageInfo));
+
+        when(mRestrictUsbOverlayActivitiesProperty.getBoolean()).thenReturn(true);
+        when(mPackageManager.getProperty(
+                eq(PROPERTY_RESTRICT_USB_OVERLAY_ACTIVITIES), eq(TEST_PACKAGE_NAME)))
+                .thenReturn(mRestrictUsbOverlayActivitiesProperty);
     }
 
     @After
@@ -130,66 +172,59 @@
     }
 
     @Test
-    public void testDeviceAttached_flagTrueWithoutForegroundActivity_resolveActivityCalled() {
-        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
+    public void testDeviceAttached_foregroundActivityWithManifestField_resolveActivityNotCalled() {
+        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);
+
+        verify(mUsbUserSettingsManager, times(0)).queryIntentActivities(any(Intent.class));
+    }
+
+    @Test
+    public void testDeviceAttached_noForegroundActivity_resolveActivityCalled() {
         when(mActivityManager.getRunningAppProcesses()).thenReturn(new ArrayList<>());
-        when(mPackageManager.getPackagesHoldingPermissions(
-                new String[]{android.Manifest.permission.MANAGE_USB},
-                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(List.of(mPackageInfo));
-        UsbDevice device = Mockito.mock(UsbDevice.class);
-        mUsbProfileGroupSettingsManager.deviceAttached(device);
+
+        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);
+
         verify(mUsbUserSettingsManager).queryIntentActivities(any(Intent.class));
     }
 
     @Test
     public void testDeviceAttached_noForegroundActivityWithUsbPermission_resolveActivityCalled() {
-        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
-        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
         when(mPackageManager.getPackagesHoldingPermissions(
-                new String[]{android.Manifest.permission.MANAGE_USB},
-                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(new ArrayList<>());
-        UsbDevice device = Mockito.mock(UsbDevice.class);
-        mUsbProfileGroupSettingsManager.deviceAttached(device);
+                new String[] { android.Manifest.permission.MANAGE_USB },
+                PackageManager.MATCH_SYSTEM_ONLY))
+                .thenReturn(new ArrayList<>());
+
+        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);
+
         verify(mUsbUserSettingsManager).queryIntentActivities(any(Intent.class));
     }
 
     @Test
-    public void testDeviceAttached_foregroundActivityWithManifestField_resolveActivityNotCalled() {
-        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
-        when(mProperty.getBoolean()).thenReturn(true);
-        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
-        when(mPackageManager.getPackagesHoldingPermissions(
-                new String[]{android.Manifest.permission.MANAGE_USB},
-                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(List.of(mPackageInfo));
-        UsbDevice device = Mockito.mock(UsbDevice.class);
-        mUsbProfileGroupSettingsManager.deviceAttached(device);
-        verify(mUsbUserSettingsManager, times(0))
-                .queryIntentActivities(any(Intent.class));
-    }
+    public void testDeviceAttached_restricUsbOverlayPropertyDisabled_resolveActivityCalled() {
+        when(mRestrictUsbOverlayActivitiesProperty.getBoolean()).thenReturn(false);
 
-    @Test
-    public void testDeviceAttached_foregroundActivityWithoutManifestField_resolveActivityCalled() {
-        when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(true);
-        when(mProperty.getBoolean()).thenReturn(false);
-        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
-        when(mPackageManager.getPackagesHoldingPermissions(
-                new String[]{android.Manifest.permission.MANAGE_USB},
-                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(List.of(mPackageInfo));
-        UsbDevice device = Mockito.mock(UsbDevice.class);
-        mUsbProfileGroupSettingsManager.deviceAttached(device);
+        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);
+
         verify(mUsbUserSettingsManager).queryIntentActivities(any(Intent.class));
     }
 
     @Test
-    public void testDeviceAttached_flagFalseForegroundActivity_resolveActivityCalled() {
+    public void testDeviceAttached_flagFalse_resolveActivityCalled() {
         when(Flags.allowRestrictionOfOverlayActivities()).thenReturn(false);
-        when(mProperty.getBoolean()).thenReturn(true);
-        when(mActivityManager.getRunningAppProcesses()).thenReturn(List.of(mRunningAppProcessInfo));
-        when(mPackageManager.getPackagesHoldingPermissions(
-                new String[]{android.Manifest.permission.MANAGE_USB},
-                PackageManager.MATCH_SYSTEM_ONLY)).thenReturn(List.of(mPackageInfo));
-        UsbDevice device = Mockito.mock(UsbDevice.class);
-        mUsbProfileGroupSettingsManager.deviceAttached(device);
+
+        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);
+
         verify(mUsbUserSettingsManager).queryIntentActivities(any(Intent.class));
     }
+
+    @Test
+    public void
+            testDeviceAttached_setupNotCompleteAndNoBlockingActivities_resolveActivityNotCalled() {
+        when(mRestrictUsbOverlayActivitiesProperty.getBoolean()).thenReturn(false);
+        Settings.Secure.putInt(mContentResolver, USER_SETUP_COMPLETE, 0);
+
+        mUsbProfileGroupSettingsManager.deviceAttached(mUsbDevice);
+
+        verify(mUsbUserSettingsManager, times(0)).queryIntentActivities(any(Intent.class));
+    }
 }
diff --git a/wifi/wifi.aconfig b/wifi/wifi.aconfig
index 3c734bc..c5bc039 100644
--- a/wifi/wifi.aconfig
+++ b/wifi/wifi.aconfig
@@ -9,3 +9,11 @@
     bug: "313038031"
     is_fixed_read_only: true
 }
+
+flag {
+    name: "network_provider_battery_charging_status"
+    is_exported: true
+    namespace: "wifi"
+    description: "Control the API that allows setting / reading the NetworkProviderInfo's battery charging status"
+    bug: "305067231"
+}