SystemUI: Add dual-tone light and dark themes for QS

Author: Danny Lin <danny@kdrag0n.dev>
Date:   Wed Oct 6 18:40:30 2021 -0700

    SystemUI: Make QS panel change on UI mode changes

    This is a prerequisite for making the QS panel follow the light system
    theme setting.

    Change-Id: Iac4c96ccb3845812ca3df820bf27dc533816f72e
    Signed-off-by: althafvly <althafvly@gmail.com>

Author: Danny Lin <danny@kdrag0n.dev>
Date:   Wed Oct 6 18:41:11 2021 -0700

    Revert "Do not re-inflate QS and SB when CONFIG_UI_MODE"

    This is a prerequisite for making the QS panel follow the light system
    mode setting.

    Change-Id: Ibad399ece587505559cc73febdda2f2d8558e94d

Author: Danny Lin <danny@kdrag0n.dev>
Date:   Mon Oct 11 19:24:58 2021 -0700

    SystemUI: Follow light/dark theme in quick settings

    Android 12's dual-tone style where the quick settings panel is always
    dark makes the light theme look like a second-class citizen. Pure black
    also looks out-of-place next to QS tiles and the notification panel
    because dynamic themes don't affect it at all.

    Revert to the ~Beta 1 style where quick settings used the same theme as
    the notification shade.

    - colorAccentPrimary has been replaced with colorAccent for contrast in
      light mode, because colorAccentPrimary is system_accent1_100 (dark
      accent color)
    - Footer chips have been converted to surfaces (similar to QS tiles and
      notifications), which makes more sense with the new style
    - The QS background is now the same as the notification shade background
      in both light and dark modes

    Demo screenshots (with dual-tone commit):
    https://twitter.com/kdrag0n/status/1445922541218922496

    [kdrag0n: ported to 12L]

    Change-Id: I3d45b72f0f119e100505409d178ab8f698993881

Author: Danny Lin <danny@kdrag0n.dev>
Date:   Mon Oct 11 19:25:02 2021 -0700

    SystemUI: Initialize QS tiles in inactive state

    Now that the QS fragment is recreated when changing the UI mode (so that
    it follows light/dark themes), all tiles flash with active color briefly
    because the new views become visible before states are refreshed.

    Initializing tiles in the inactive state is much less disruptive, and
    the effect is very hard to see as compared to the active color because
    the background color is much less prominent.

    Change-Id: I048171d503f5533e91bab486b8805ac15c329f31

Author: Danny Lin <danny@kdrag0n.dev>
Date:   Mon Oct 11 19:25:08 2021 -0700

    SystemUI: Add dual-tone light and dark themes for QS

    Google's dual-tone QS design where the notification panel has a
    semantically higher elevation adds depth to the notification+QS shade,
    and we don't necessarily have to give it up just because our QS has
    light and dark themes.

    To preserve the dual-tone effect, use a darker background color for the
    QS section:

    Light:
        Notifications: neutral1 20 (surface_light)
        Notification panel: neutral1 50 (light BG)
        QS background: neutral1 100 (darker light BG / surface_header_light)
        Inactive QS tiles: neutral1 20 (surface_light)

    Dark:
        Notifications: neutral1 800 (surface_dark)
        Notification panel: neutral1 900 (dark BG)
        QS background: neutral1 950 (surface_header_dark_sysui modulated to L* 5)
        Inactive QS tiles: neutral1 800 (surface_dark)

    The dark QS background could be neutral1 0 (black) like it was before,
    but I don't think it looks as good because it can't be tinted based on
    the active wallpaper and thus stands out from other colors.

    Unfortunately, Google's current CAM16-based modulation causes hue shifts
    in extreme light and dark shades (e.g. L* = 98 / 5), but we'll fix this
    by generating and overlaying modulated surface colors in our
    ThemeOverlayController implementation.

    Demo screenshots: https://twitter.com/kdrag0n/status/1445922541218922496

    Change-Id: Icdc4957ecb4e0201377351f1a3e1c6928d6b3955

Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Mon May 30 00:13:02 2022 +0530

    SystemUI: Calculate paged QS tiles height properly

    When QS is re-inflated during UI mode change and we're on the
    3rd or higher QS page, the first QS page is misaligned and
    hence height returns 0, resulting in footer and media panel
    position overlapping the QS panel. Return the maximum height
    among all present QS pages to fix this issue.

    Change-Id: I539babdb75c114cc44b4213ff114d4272be22ef6

Author: Xayah <zds1249475336@gmail.com>
Date:   Fri Aug 19 13:46:08 2022 -0400

    SystemUI: Reset to textColorPrimaryInverse for light theme

    * Most of them have been replaced with textColorOnAccent in b1444e4, which is not in harmony with light theme.

    Change-Id: I72a3a33e4e4a4fc9f23458d2c0000ca4c3fbae7d

Author: althafvly <althafvly@gmail.com>
Date:   Wed Sep 28 21:06:43 2022 +0530

    SystemUI: QSCustomizer: Fix QS tile reset text color

    - https://gitlab.com/LineageOS/issues/android/-/issues/4873

    Change-Id: I49a599f10f68c0c576ec863b919936a3b171f2c6

Author: althafvly <althafvly@gmail.com>
Date:   Wed Oct 5 11:30:49 2022 +0530

    SystemUI: BatteryMeterView: Set white tint in darkmode

    Change-Id: I399e47088d52b43029f1e2a26bc05323ac2785f2

Author: althafvly <althafvly@gmail.com>
Date:   Tue Oct 4 18:34:08 2022 +0530

    SystemUI: Re-inflate QS and SB when CONFIG_SCREEN_LAYOUT

    - It was removed in a13, needed for light theme change in landscape.

    Change-Id: I1872f5d90e6f6b8debecbc69eb80c3a11d8984e2

Author: ReallySnow <reallysnow233@gmail.com>
Date:   Thu Sep 15 13:38:48 2022 +0800

    SystemUI: Follow light/dark theme in SplitShade Header

    * Google's default implementation is dark, which means
      it doesn't need to follow the light/dark color change,
      but we broke it, so add it to complete the SplitShade
      Header color change

    Co-authored-by: Col_or <col_or@qq.com>
    Change-Id: I5464039885197eeb43bd31b822bfcba7a1b08776

Author: Tim Zimmermann <tim@linux4.de>
Date:   Thu Mar 16 07:26:59 2023 +0100

    SystemUI: Follow light/dark theme in new QS footer actions

    * Needed after 2feceb2
    * Only settings and power button needed to be changed

    Change-Id: I14b04ba206d31784d9e5a1351d1fcbb1d258e52b

Author: Pranav Vashi <neobuddy89@gmail.com>
Date:   Wed Dec 13 23:24:29 2023 +0530

    SystemUI: Use themewrapper for QSCustomizer and tune colorUnavailable

    * Restores behvavior from A13 for colorUnavailable, shadeDisabled is now unused.

    Change-Id: Id9673ccd0a3d096b7376cfb8ed0daabb7e127e11
    Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>

Author: Adithya R <gh0strider.2k18.reborn@gmail.com>
Date:   Thu Jan 19 14:37:43 2023 +0530

    SystemUI: Remove visibility check in setting QSCarrier color

    This fixes a corner case where the signal icon color is incorrect:
    Have dual sim -> switch to dark theme -> turn off one sim -> switch
    to light theme -> turn the other sim back on. QS carrier signal
    is colored white instead of black.

    Ensure that the signal icon color is always up to date, by removing
    visibility check, to avoid this issue.

    Fixes: 816b8ddf ("Follow light/dark theme in SplitShade Header")
    Change-Id: I092c06053fc4bc8d9ca51d1d31128da27ef6a823

Author: elluzion <dyrex2004@gmail.com>
Date:   Mon Dec 7 20:39:40 2020 +0100

    SystemUI: Use proper Resolver background color

    Change-Id: I3c0c89349a38d4606311c4849cf3dedad772c382

Author: minaripenguin <minaripenguin@users.noreply.github.com>
Date:   Sat Apr 8 19:12:10 2023 +0800

    SystemUI: Define colorPrimary/colorSecondary colors for dual tone QS

    * this is needed by context/context wrappers/utils to determine which color/s to be applied for functions like setTint/Utils getters etc.

    fixes: white qs header icons tint issue on light theme

    Change-Id: Ief06b853f9b89a3111715a938c0fadc236b88b1b
    Signed-off-by: minaripenguin <minaripenguin@users.noreply.github.com>

Change-Id: I8f078e7668fffc7ab97202fde922169bf6ed5350
diff --git a/core/res/res/color/surface_header_dark_sysui.xml b/core/res/res/color/surface_header_dark_sysui.xml
new file mode 100644
index 0000000..ec070c9
--- /dev/null
+++ b/core/res/res/color/surface_header_dark_sysui.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:color="@color/system_neutral1_500" android:lStar="5" />
+</selector>
diff --git a/core/res/res/values-night/themes_device_defaults.xml b/core/res/res/values-night/themes_device_defaults.xml
index 7cfdba7..970dba3 100644
--- a/core/res/res/values-night/themes_device_defaults.xml
+++ b/core/res/res/values-night/themes_device_defaults.xml
@@ -87,7 +87,7 @@
 
     <style name="Theme.DeviceDefault.Resolver" parent="Theme.DeviceDefault.ResolverCommon">
         <item name="windowLightNavigationBar">false</item>
-        <item name="colorBackgroundFloating">@android:color/GM2_grey_800</item>
+        <item name="colorBackgroundFloating">?android:attr/colorPrimary</item>
         <item name="textColorSecondary">@android:color/resolver_text_color_secondary_dark</item>
     </style>
 
diff --git a/core/res/res/values-night/values.xml b/core/res/res/values-night/values.xml
index 1571fab..0683c20 100644
--- a/core/res/res/values-night/values.xml
+++ b/core/res/res/values-night/values.xml
@@ -22,6 +22,7 @@
         <item name="colorSecondary">@color/secondary_device_default_settings</item>
         <item name="colorAccent">@color/accent_device_default_dark</item>
         <item name="colorError">@color/error_color_device_default_dark</item>
+        <item name="colorSurfaceHeader">@color/surface_header_dark_sysui</item>
         <item name="colorControlNormal">?attr/textColorPrimary</item>
         <item name="alertDialogTheme">@style/Theme.DeviceDefault.Dialog.Alert</item>
         <item name="forceDarkAllowed">false</item>
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
index 5d85fba..0c7c46d 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSTile.java
@@ -154,7 +154,7 @@
     @ProvidesInterface(version = State.VERSION)
     public static class State {
         public static final int VERSION = 1;
-        public static final int DEFAULT_STATE = Tile.STATE_ACTIVE;
+        public static final int DEFAULT_STATE = Tile.STATE_INACTIVE;
 
         public Icon icon;
         public Supplier<Icon> iconSupplier;
diff --git a/packages/SystemUI/res/values-night/styles.xml b/packages/SystemUI/res/values-night/styles.xml
index b6971d3..670af5f 100644
--- a/packages/SystemUI/res/values-night/styles.xml
+++ b/packages/SystemUI/res/values-night/styles.xml
@@ -14,7 +14,8 @@
      limitations under the License.
 -->
 
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+           xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
 
     <style name="Theme.SystemUI.DayNightDialog" parent="@android:style/Theme.DeviceDefault.Dialog"/>
 
@@ -24,6 +25,36 @@
         <item name="android:windowIsFloating">true</item>
     </style>
 
+    <style name="Theme.SystemUI.QuickSettings" parent="@*android:style/Theme.DeviceDefault.SystemUI">
+        <item name="isQsTheme">true</item>
+        <item name="lightIconTheme">@style/QSIconTheme</item>
+        <item name="darkIconTheme">@style/QSIconTheme</item>
+        <item name="android:colorError">@*android:color/error_color_material_dark</item>
+        <item name="android:windowIsFloating">true</item>
+        <item name="android:homeAsUpIndicator">@drawable/ic_arrow_back</item>
+
+        <item name="surfaceBright">?androidprv:attr/materialColorSurfaceBright</item>
+        <item name="android:colorBackground">?attr/surfaceBright</item>
+        <item name="scHigh">?androidprv:attr/materialColorSurfaceContainerHigh</item>
+        <item name="primary">?androidprv:attr/materialColorPrimary</item>
+        <item name="tertiary">?androidprv:attr/materialColorTertiary</item>
+        <item name="onSurface">?androidprv:attr/materialColorOnSurface</item>
+        <item name="onSurfaceVariant">?androidprv:attr/materialColorOnSurfaceVariant</item>
+        <item name="outline">?androidprv:attr/materialColorOutline</item>
+
+        <item name="shadeActive">?android:attr/colorAccent</item>
+        <item name="onShadeActive">?android:attr/textColorPrimaryInverse</item>
+        <item name="onShadeActiveVariant">?android:attr/textColorSecondaryInverse</item>
+        <item name="shadeInactive">@android:color/system_neutral1_800</item>
+        <item name="onShadeInactive">?android:attr/textColorPrimary</item>
+        <item name="onShadeInactiveVariant">?android:attr/textColorSecondary</item>
+        <item name="shadeDisabled">@color/shade_disabled</item>
+        <item name="underSurface">@android:color/system_neutral1_900</item>
+        <item name="android:itemTextAppearance">@style/Control.MenuItem</item>
+        <item name="android:colorPrimary">@*android:color/system_neutral1_0</item>
+        <item name="android:colorSecondary">@*android:color/system_neutral1_50</item>
+    </style>
+
     <!-- Screenshots -->
     <style name="LongScreenshotActivity" parent="@android:style/Theme.DeviceDefault.DayNight">
         <item name="android:windowNoTitle">true</item>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index c6b0205..344cd6e 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -389,11 +389,11 @@
         <item name="containerStyle">@style/AuthCredentialPinPasswordContainerStyle</item>
     </style>
 
-    <style name="Theme.SystemUI.QuickSettings" parent="@*android:style/Theme.DeviceDefault">
+    <style name="Theme.SystemUI.QuickSettings" parent="@*android:style/Theme.DeviceDefault.SystemUI">
         <item name="isQsTheme">true</item>
         <item name="lightIconTheme">@style/QSIconTheme</item>
         <item name="darkIconTheme">@style/QSIconTheme</item>
-        <item name="android:colorError">@*android:color/error_color_material_dark</item>
+        <item name="android:colorError">@*android:color/error_color_material_light</item>
         <item name="android:windowIsFloating">true</item>
         <item name="android:homeAsUpIndicator">@drawable/ic_arrow_back</item>
 
@@ -406,15 +406,17 @@
         <item name="onSurfaceVariant">?androidprv:attr/materialColorOnSurfaceVariant</item>
         <item name="outline">?androidprv:attr/materialColorOutline</item>
 
-        <item name="shadeActive">@color/material_dynamic_primary90</item>
-        <item name="onShadeActive">@color/material_dynamic_primary10</item>
-        <item name="onShadeActiveVariant">@color/material_dynamic_primary30</item>
-        <item name="shadeInactive">@color/material_dynamic_neutral20</item>
-        <item name="onShadeInactive">@color/material_dynamic_neutral90</item>
-        <item name="onShadeInactiveVariant">@color/material_dynamic_neutral_variant80</item>
-        <item name="shadeDisabled">@color/shade_disabled</item>
-        <item name="underSurface">@color/material_dynamic_neutral0</item>
+        <item name="shadeActive">?android:attr/colorAccent</item>
+        <item name="onShadeActive">?android:attr/textColorPrimaryInverse</item>
+        <item name="onShadeActiveVariant">?android:attr/textColorSecondaryInverse</item>
+        <item name="shadeInactive">@*android:color/surface_light</item>
+        <item name="onShadeInactive">?android:attr/textColorPrimary</item>
+        <item name="onShadeInactiveVariant">?android:attr/textColorSecondary</item>
+        <item name="shadeDisabled">@*android:color/surface_light</item>
+        <item name="underSurface">@android:color/system_neutral1_100</item>
         <item name="android:itemTextAppearance">@style/Control.MenuItem</item>
+        <item name="android:colorPrimary">@*android:color/system_neutral1_900</item>
+        <item name="android:colorSecondary">@*android:color/system_neutral1_800</item>
     </style>
 
     <!-- Cannot double inherit. Use Theme.SystemUI.QuickSettings in code to match -->
@@ -681,7 +683,7 @@
 
     <style name="QSCustomizeToolbar" parent="@*android:style/Widget.DeviceDefault.Toolbar">
         <item name="android:textColor">?attr/onSurface</item>
-        <item name="android:elevation">10dp</item>
+        <item name="android:elevation">0dp</item>
     </style>
 
     <!-- Media controls always have light background -->
diff --git a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
index b1a153a..8d61cef 100644
--- a/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
+++ b/packages/SystemUI/src/com/android/systemui/battery/BatteryMeterView.java
@@ -126,12 +126,19 @@
         updateShowPercent();
         mDualToneHandler = new DualToneHandler(context);
         // Init to not dark at all.
-        onDarkChanged(new ArrayList<Rect>(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT);
+        if (isNightMode()) {
+            onDarkChanged(new ArrayList<Rect>(), 0, DarkIconDispatcher.DEFAULT_ICON_TINT);
+        }
 
         setClipChildren(false);
         setClipToPadding(false);
     }
 
+    private boolean isNightMode() {
+        return (mContext.getResources().getConfiguration().uiMode
+                & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;
+    }
+
     private void setupLayoutTransition() {
         LayoutTransition transition = new LayoutTransition();
         transition.setDuration(200);
diff --git a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
index 81a5206..5aa7ceb 100644
--- a/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
+++ b/packages/SystemUI/src/com/android/systemui/fragments/FragmentHostManager.java
@@ -59,7 +59,8 @@
     private final LeakDetector mLeakDetector;
     private final InterestingConfigChanges mConfigChanges = new InterestingConfigChanges(
             ActivityInfo.CONFIG_FONT_SCALE | ActivityInfo.CONFIG_LOCALE
-                    | ActivityInfo.CONFIG_ASSETS_PATHS);
+                    | ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_ASSETS_PATHS
+                    | ActivityInfo.CONFIG_UI_MODE);
     private final FragmentService mManager;
     private final ExtensionFragmentManager mPlugins = new ExtensionFragmentManager();
 
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 1af2306..705d6bb 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -23,6 +23,7 @@
 import android.util.AttributeSet;
 import android.util.TypedValue;
 import android.view.LayoutInflater;
+import android.view.ContextThemeWrapper;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
@@ -67,13 +68,15 @@
     public QSCustomizer(Context context, AttributeSet attrs) {
         super(context, attrs);
 
-        LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this);
+        Context themedContext =
+                new ContextThemeWrapper(context, R.style.Theme_SystemUI_QuickSettings);
+        LayoutInflater.from(themedContext).inflate(R.layout.qs_customize_panel_content, this);
         mClipper = new QSDetailClipper(findViewById(R.id.customize_container));
         Toolbar toolbar = findViewById(com.android.internal.R.id.action_bar);
         TypedValue value = new TypedValue();
-        mContext.getTheme().resolveAttribute(android.R.attr.homeAsUpIndicator, value, true);
+        themedContext.getTheme().resolveAttribute(android.R.attr.homeAsUpIndicator, value, true);
         toolbar.setNavigationIcon(
-                getResources().getDrawable(value.resourceId, mContext.getTheme()));
+                getResources().getDrawable(value.resourceId, themedContext.getTheme()));
 
         toolbar.getMenu().add(Menu.NONE, MENU_RESET, 0, com.android.internal.R.string.reset)
                 .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
index cd895ff..b92aec9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
@@ -110,7 +110,7 @@
     private val colorOffstate = Utils.getColorAttrDefaultColor(context, R.attr.shadeInactive)
     private val colorInactive = if (isRoundQS()) Utils.applyAlpha(INACTIVE_ALPHA, colorOffstate)
             else colorOffstate
-    private val colorUnavailable = Utils.getColorAttrDefaultColor(context, R.attr.shadeDisabled)
+    private val colorUnavailable = Utils.applyAlpha(UNAVAILABLE_ALPHA, colorInactive)
 
     private val overlayColorActive = Utils.applyAlpha(
         /* alpha= */ 0.11f,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
index 3d73a39..c7ddce2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/ShadeHeaderController.kt
@@ -98,6 +98,7 @@
     private val privacyIconsController: HeaderPrivacyIconsController,
     private val insetsProvider: StatusBarContentInsetsProvider,
     private val configurationController: ConfigurationController,
+    private val context: Context,
     private val variableDateViewControllerFactory: VariableDateViewController.Factory,
     @Named(SHADE_HEADER) private val batteryMeterViewController: BatteryMeterViewController,
     private val dumpManager: DumpManager,
@@ -150,6 +151,7 @@
     private var cutout: DisplayCutout? = null
     private var lastInsets: WindowInsets? = null
     private var nextAlarmIntent: PendingIntent? = null
+    private var textColorPrimary = Color.TRANSPARENT
 
     private var privacyChipVisible = false
     private var qsDisabled = false
@@ -300,6 +302,10 @@
                 updateCarrierGroupPadding()
                 clock.onDensityOrFontScaleChanged()
             }
+
+            override fun onUiModeChanged() {
+                updateResources()
+            }
         }
 
     private val nextAlarmCallback =
@@ -381,6 +387,7 @@
         demoModeController.addCallback(demoModeReceiver)
         statusBarIconController.addIconGroup(iconManager)
         nextAlarmController.addCallback(nextAlarmCallback)
+        updateResources()
         systemIconsHoverContainer.setOnHoverListener(
             statusOverlayHoverListenerFactory.createListener(systemIconsHoverContainer)
         )
@@ -585,6 +592,25 @@
         header.setPadding(padding, header.paddingTop, padding, header.paddingBottom)
         updateQQSPaddings()
         qsBatteryModeController.updateResources()
+
+        val fillColor = Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
+        val fillColorInverse = Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimaryInverse)
+        iconManager.setTint(fillColor, fillColorInverse)
+        val textColor = Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimary)
+        val textColorInverse = Utils.getColorAttrDefaultColor(context, android.R.attr.textColorPrimaryInverse)
+        val colorStateList = Utils.getColorAttr(context, android.R.attr.textColorPrimary)
+        if (textColor != textColorPrimary) {
+            val textColorSecondary = Utils.getColorAttrDefaultColor(context,
+                    android.R.attr.textColorSecondary)
+            textColorPrimary = textColor
+            if (iconManager != null) {
+                iconManager.setTint(textColor, textColorInverse)
+            }
+            clock.setTextColor(textColorPrimary)
+            date.setTextColor(textColorPrimary)
+            mShadeCarrierGroup.updateColors(textColorPrimary, colorStateList)
+            batteryIcon.updateColors(textColorPrimary, textColorSecondary, textColorPrimary)
+        }
     }
 
     private fun updateQQSPaddings() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
index 6ca0ad4..727a187 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrier.java
@@ -152,6 +152,11 @@
                         com.android.settingslib.R.string.not_default_data_content_description));
     }
 
+    public void updateColors(ColorStateList colorStateList) {
+        mMobileRoaming.setImageTintList(colorStateList);
+        mMobileSignal.setImageTintList(colorStateList);
+    }
+
     @VisibleForTesting
     View getRSSIView() {
         return mMobileGroup;
diff --git a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java
index e84fb48..a5bcfea 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/carrier/ShadeCarrierGroup.java
@@ -18,8 +18,11 @@
 
 import android.annotation.StyleRes;
 import android.content.Context;
+import android.content.res.ColorStateList;
+import android.graphics.PorterDuff;
 import android.util.AttributeSet;
 import android.view.View;
+import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
@@ -58,6 +61,19 @@
         return findViewById(R.id.shade_carrier_divider2);
     }
 
+    public void updateColors(int color, ColorStateList colorStateList) {
+        getNoSimTextView().setTextColor(color);
+        ShadeCarrier[] shadeCarriers = { getCarrier1View(), getCarrier2View(), getCarrier3View() };
+        for (ShadeCarrier shadeCarrier : shadeCarriers) {
+            for (int i = 0; i < shadeCarrier.getChildCount(); i++) {
+                shadeCarrier.updateColors(colorStateList);
+                if (shadeCarrier.getChildAt(i) instanceof TextView) {
+                    ((TextView) shadeCarrier.getChildAt(i)).setTextColor(color);
+                }
+            }
+        }
+    }
+
     public void updateTextAppearance(@StyleRes int resId) {
         FontSizeUtils.updateFontSizeFromStyle(getNoSimTextView(), resId);
         getCarrier1View().updateTextAppearance(resId);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 8ddd816..65155ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -222,6 +222,7 @@
     private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
 
     private GradientColors mColors;
+    private GradientColors mBehindColors;
     private boolean mNeedsDrawableColorUpdate;
 
     private float mAdditionalScrimBehindAlphaKeyguard = 0f;
@@ -364,6 +365,7 @@
         mKeyguardTransitionInteractor = keyguardTransitionInteractor;
         mWallpaperRepository = wallpaperRepository;
         mMainDispatcher = mainDispatcher;
+        mBehindColors = new GradientColors();
     }
 
     @Override
@@ -951,7 +953,7 @@
                 mNotificationsAlpha = behindAlpha;
                 mNotificationsTint = behindTint;
                 mBehindAlpha = QS_CLIP_SCRIM_ALPHA;
-                mBehindTint = Color.BLACK;
+                mBehindTint = Color.TRANSPARENT;
             } else {
                 mBehindAlpha = behindAlpha;
                 if (mState == ScrimState.KEYGUARD && mTransitionToFullShadeProgress > 0.0f) {
@@ -1138,7 +1140,7 @@
                     && !mBlankScreen;
 
             mScrimInFront.setColors(mColors, animateScrimInFront);
-            mScrimBehind.setColors(mColors, animateBehindScrim);
+            mScrimBehind.setColors(mBehindColors, animateBehindScrim);
             mNotificationsScrim.setColors(mColors, animateScrimNotifications);
 
             dispatchBackScrimState(mScrimBehind.getViewAlpha());
@@ -1503,6 +1505,8 @@
         if (mScrimBehind == null) return;
         int background = Utils.getColorAttr(mScrimBehind.getContext(),
                 com.android.internal.R.attr.materialColorSurfaceDim).getDefaultColor();
+        int surfaceBackground = Utils.getColorAttr(mScrimBehind.getContext(),
+                com.android.internal.R.attr.colorSurfaceHeader).getDefaultColor();
         int accent = Utils.getColorAttr(mScrimBehind.getContext(),
                 com.android.internal.R.attr.materialColorPrimary).getDefaultColor();
         mColors.setMainColor(background);
@@ -1516,6 +1520,11 @@
             state.setSurfaceColor(surface);
         }
 
+        mBehindColors.setMainColor(surfaceBackground);
+        mBehindColors.setSecondaryColor(accent);
+        mBehindColors.setSupportsDarkText(
+                ColorUtils.calculateContrast(mBehindColors.getMainColor(), Color.WHITE) > 4.5);
+
         mNeedsDrawableColorUpdate = true;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 50d49b53..59d0fcf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -82,7 +82,7 @@
             mBehindAlpha = mClipQsScrim ? mQSClipScrimAlpha : mScrimBehindAlphaKeyguard;
             mNotifAlpha = mClipQsScrim ? mScrimBehindAlphaKeyguard : 0;
             if (mClipQsScrim) {
-                updateScrimColor(mScrimBehind, mQSClipScrimAlpha /* alpha */, Color.BLACK);
+                updateScrimColor(mScrimBehind, mQSClipScrimAlpha /* alpha */, Color.TRANSPARENT);
             }
         }
     },
@@ -122,7 +122,7 @@
         @Override
         public void prepare(ScrimState previousState) {
             mBehindAlpha = mClipQsScrim ? mQSClipScrimAlpha : mDefaultScrimAlpha;
-            mBehindTint = mClipQsScrim ? Color.BLACK : mSurfaceColor;
+            mBehindTint = Color.TRANSPARENT;
             mNotifAlpha = mClipQsScrim ? mQSClipScrimAlpha : 0;
             mNotifTint = Color.TRANSPARENT;
             mFrontAlpha = 0f;
@@ -154,10 +154,10 @@
             mBehindAlpha = mClipQsScrim ? mQSClipScrimAlpha : mDefaultScrimAlpha;
             mNotifAlpha = mClipQsScrim ? mQSClipScrimAlpha : mDefaultScrimAlpha;
             mFrontAlpha = 0f;
-            mBehindTint = mClipQsScrim ? Color.TRANSPARENT : Color.BLACK;
+            mBehindTint = Color.TRANSPARENT;
 
             if (mClipQsScrim) {
-                updateScrimColor(mScrimBehind, mQSClipScrimAlpha /* alpha */, Color.BLACK);
+                updateScrimColor(mScrimBehind, mQSClipScrimAlpha /* alpha */, Color.TRANSPARENT);
             }
         }
     },
@@ -259,22 +259,22 @@
                     && !fromAod;
 
             mFrontTint = Color.TRANSPARENT;
-            mBehindTint = Color.BLACK;
+            mBehindTint = Color.TRANSPARENT;
             mBlankScreen = false;
 
             if (mDisplayRequiresBlanking && previousState == ScrimState.AOD) {
                 // Set all scrims black, before they fade transparent.
                 updateScrimColor(mScrimInFront, 1f /* alpha */, Color.BLACK /* tint */);
-                updateScrimColor(mScrimBehind, 1f /* alpha */, Color.BLACK /* tint */);
+                updateScrimColor(mScrimBehind, 1f /* alpha */, Color.TRANSPARENT /* tint */);
 
                 // Scrims should still be black at the end of the transition.
                 mFrontTint = Color.BLACK;
-                mBehindTint = Color.BLACK;
+                mBehindTint = Color.TRANSPARENT;
                 mBlankScreen = true;
             }
 
             if (mClipQsScrim) {
-                updateScrimColor(mScrimBehind, mQSClipScrimAlpha /* alpha */, Color.BLACK);
+                updateScrimColor(mScrimBehind, mQSClipScrimAlpha /* alpha */, Color.TRANSPARENT);
             }
         }
     },
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
index 20d1fff..e91310d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/Clock.java
@@ -39,13 +39,11 @@
 import android.text.style.RelativeSizeSpan;
 import android.util.AttributeSet;
 import android.util.TypedValue;
-import android.view.ContextThemeWrapper;
 import android.view.Display;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.TextView;
 
-import com.android.settingslib.Utils;
 import com.android.systemui.Dependency;
 import com.android.systemui.FontSizeUtils;
 import com.android.systemui.res.R;
@@ -370,13 +368,6 @@
         setTextColor(mNonAdaptedColor);
     }
 
-    // Update text color based when shade scrim changes color.
-    public void onColorsChanged(boolean lightTheme) {
-        final Context context = new ContextThemeWrapper(mContext,
-                lightTheme ? R.style.Theme_SystemUI_LightWallpaper : R.style.Theme_SystemUI);
-        setTextColor(Utils.getColorAttrDefaultColor(context, R.attr.wallpaperTextColor));
-    }
-
     @Override
     public void onDensityOrFontScaleChanged() {
         reloadDimens();