Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 44a55cfb authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge "use new theme colors on custom notifications"

parents 5ae7f220 cc0fbf9c
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -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>

+4 −0
Original line number Diff line number Diff line
@@ -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)) {
+5 −0
Original line number Diff line number Diff line
@@ -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);
        }
+50 −0
Original line number Diff line number Diff line
@@ -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;
+6 −0
Original line number Diff line number Diff line
@@ -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);
Loading