Merge "use new theme colors on custom notifications"
This commit is contained in:
@@ -489,7 +489,6 @@
|
||||
|
||||
<style name="TextAppearance.NotificationInfo">
|
||||
<item name="android:fontFamily">@*android:string/config_headlineFontFamily</item>
|
||||
<item name="android:textColor">@color/notification_primary_text_color</item>
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.NotificationInfo.Secondary">
|
||||
@@ -498,7 +497,6 @@
|
||||
</style>
|
||||
|
||||
<style name="TextAppearance.NotificationInfo.Title">
|
||||
<item name="android:textColor">@color/notification_primary_text_color</item>
|
||||
<item name="android:textStyle">bold</item>
|
||||
</style>
|
||||
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user