diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 0697c5c0084c6..6c0635a3ce515 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -489,7 +489,6 @@
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java
index 4c9c2f95b35cb..414d62092ab23 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCustomViewWrapper.java
@@ -47,6 +47,10 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper {
public void onContentUpdated(ExpandableNotificationRow row) {
super.onContentUpdated(row);
+ // Custom views will most likely use just white or black as their text color.
+ // We need to scan through and replace these colors by Material NEXT colors.
+ ensureThemeOnChildren();
+
// Let's invert the notification colors when we're in night mode and
// the notification background isn't colorized.
if (needsInversion(mBackgroundColor, mView)) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationDecoratedCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationDecoratedCustomViewWrapper.java
index 49a8d56e1e65d..79648457c521c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationDecoratedCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationDecoratedCustomViewWrapper.java
@@ -43,6 +43,11 @@ public class NotificationDecoratedCustomViewWrapper extends NotificationTemplate
if (childIndex != null && childIndex != -1) {
mWrappedView = container.getChildAt(childIndex);
}
+
+ // Custom views will most likely use just white or black as their text color.
+ // We need to scan through and replace these colors by Material NEXT colors.
+ ensureThemeOnChildren();
+
if (needsInversion(resolveBackgroundColor(), mWrappedView)) {
invertViewLuminosity(mWrappedView);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 416c5af934008..2d706a48e90d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -29,11 +29,13 @@ import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
+import android.view.ContextThemeWrapper;
import android.view.NotificationHeaderView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.graphics.ColorUtils;
import com.android.internal.util.ContrastColorUtil;
@@ -55,6 +57,9 @@ public abstract class NotificationViewWrapper implements TransformableView {
private final Rect mTmpRect = new Rect();
protected int mBackgroundColor = 0;
+ private int mLightTextColor;
+ private int mDarkTextColor;
+ private int mDefaultTextColor;
public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) {
if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {
@@ -110,6 +115,15 @@ public abstract class NotificationViewWrapper implements TransformableView {
mBackgroundColor = backgroundColor;
mView.setBackground(new ColorDrawable(Color.TRANSPARENT));
}
+ mLightTextColor = mView.getContext().getColor(
+ com.android.internal.R.color.notification_primary_text_color_light);
+ mDarkTextColor = mView.getContext().getColor(
+ R.color.notification_primary_text_color_dark);
+
+ Context themedContext = new ContextThemeWrapper(mView.getContext(),
+ R.style.Theme_DeviceDefault_DayNight);
+ mDefaultTextColor = Utils.getColorAttr(themedContext, R.attr.textColorPrimary)
+ .getDefaultColor();
}
protected boolean needsInversion(int defaultBackgroundColor, View view) {
@@ -187,6 +201,42 @@ public abstract class NotificationViewWrapper implements TransformableView {
return false;
}
+ protected void ensureThemeOnChildren() {
+ if (mView == null) {
+ return;
+ }
+
+ // Notifications with custom backgrounds should not be adjusted
+ if (mBackgroundColor != Color.TRANSPARENT
+ || getBackgroundColor(mView) != Color.TRANSPARENT) {
+ return;
+ }
+
+ // Now let's check if there's unprotected text somewhere, and apply the theme if we find it.
+ if (!(mView instanceof ViewGroup)) {
+ return;
+ }
+ processChildrenTextColor((ViewGroup) mView);
+ }
+
+ private void processChildrenTextColor(ViewGroup viewGroup) {
+ if (viewGroup == null) {
+ return;
+ }
+
+ for (int i = 0; i < viewGroup.getChildCount(); i++) {
+ View child = viewGroup.getChildAt(i);
+ if (child instanceof TextView) {
+ int foreground = ((TextView) child).getCurrentTextColor();
+ if (foreground == mLightTextColor || foreground == mDarkTextColor) {
+ ((TextView) child).setTextColor(mDefaultTextColor);
+ }
+ } else if (child instanceof ViewGroup) {
+ processChildrenTextColor((ViewGroup) child);
+ }
+ }
+ }
+
protected int getBackgroundColor(View view) {
if (view == null) {
return Color.TRANSPARENT;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
index d08b2b78d00b6..2101ea1766a18 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
@@ -81,12 +81,15 @@ public class NotificationContentViewTest extends SysuiTestCase {
View mockContracted = mock(NotificationHeaderView.class);
when(mockContracted.findViewById(com.android.internal.R.id.feedback))
.thenReturn(mockContracted);
+ when(mockContracted.getContext()).thenReturn(mContext);
View mockExpanded = mock(NotificationHeaderView.class);
when(mockExpanded.findViewById(com.android.internal.R.id.feedback))
.thenReturn(mockExpanded);
+ when(mockExpanded.getContext()).thenReturn(mContext);
View mockHeadsUp = mock(NotificationHeaderView.class);
when(mockHeadsUp.findViewById(com.android.internal.R.id.feedback))
.thenReturn(mockHeadsUp);
+ when(mockHeadsUp.getContext()).thenReturn(mContext);
mView.setContractedChild(mockContracted);
mView.setExpandedChild(mockExpanded);
@@ -107,18 +110,21 @@ public class NotificationContentViewTest extends SysuiTestCase {
when(mockContracted.animate()).thenReturn(mock(ViewPropertyAnimator.class));
when(mockContracted.findViewById(com.android.internal.R.id.expand_button)).thenReturn(
mockContractedEB);
+ when(mockContracted.getContext()).thenReturn(mContext);
View mockExpandedEB = mock(NotificationExpandButton.class);
View mockExpanded = mock(NotificationHeaderView.class);
when(mockExpanded.animate()).thenReturn(mock(ViewPropertyAnimator.class));
when(mockExpanded.findViewById(com.android.internal.R.id.expand_button)).thenReturn(
mockExpandedEB);
+ when(mockExpanded.getContext()).thenReturn(mContext);
View mockHeadsUpEB = mock(NotificationExpandButton.class);
View mockHeadsUp = mock(NotificationHeaderView.class);
when(mockHeadsUp.animate()).thenReturn(mock(ViewPropertyAnimator.class));
when(mockHeadsUp.findViewById(com.android.internal.R.id.expand_button)).thenReturn(
mockHeadsUpEB);
+ when(mockHeadsUp.getContext()).thenReturn(mContext);
// Set up all 3 child forms
mView.setContractedChild(mockContracted);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
index 085bd900debc9..93a9e597ca908 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapperTest.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.row.wrapper;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import android.content.Context;
import android.testing.AndroidTestingRunner;
@@ -49,6 +50,7 @@ public class NotificationViewWrapperTest extends SysuiTestCase {
public void setup() throws Exception {
allowTestableLooperAsMainThread();
mView = mock(View.class);
+ when(mView.getContext()).thenReturn(mContext);
NotificationTestHelper helper = new NotificationTestHelper(
mContext,
mDependency,