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

Commit e1bb9986 authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Invert custom views in dark mode

Invert custom view colors (in Y'UV space) if its background isn't dark,
we're in dark mode, and app doesn't target Q.

Change-Id: I74f557315c5e7e91ee7ec01d1535dac40f921524
Fixes: 112767229
Test: send custom notification from pre Q app with black background
Test: send custom notification from pre Q app with white background
Test: send custom notification from pre Q app with green background
Test: send custom notification from Q app with white background
parent a75a6ee0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@
    <item type="id" name="panel_alpha_animator_tag"/>
    <item type="id" name="panel_alpha_animator_start_tag"/>
    <item type="id" name="panel_alpha_animator_end_tag"/>
    <item type="id" name="cross_fade_layer_type_changed_tag"/>

    <!-- Whether the icon is from a notification for which targetSdk < L -->
    <item type="id" name="icon_is_pre_L"/>
+11 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar;
import android.view.View;

import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;

/**
@@ -92,11 +93,17 @@ public class CrossFadeHelper {

    private static void updateLayerType(View view, float alpha) {
        if (view.hasOverlappingRendering() && alpha > 0.0f && alpha < 1.0f) {
            if (view.getLayerType() != View.LAYER_TYPE_HARDWARE) {
                view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        } else if (view.getLayerType() == View.LAYER_TYPE_HARDWARE) {
                view.setTag(R.id.cross_fade_layer_type_changed_tag, true);
            }
        } else if (view.getLayerType() == View.LAYER_TYPE_HARDWARE
                && view.getTag(R.id.cross_fade_layer_type_changed_tag) != null) {
            if (view.getTag(R.id.cross_fade_layer_type_changed_tag) != null) {
                view.setLayerType(View.LAYER_TYPE_NONE, null);
            }
        }
    }

    public static void fadeIn(final View view) {
        fadeIn(view, ANIMATION_DURATION_LENGTH, 0);
@@ -114,7 +121,7 @@ public class CrossFadeHelper {
                .setStartDelay(delay)
                .setInterpolator(Interpolators.ALPHA_IN)
                .withEndAction(null);
        if (view.hasOverlappingRendering()) {
        if (view.hasOverlappingRendering() && view.getLayerType() != View.LAYER_TYPE_HARDWARE) {
            view.animate().withLayer();
        }
    }
+48 −0
Original line number Diff line number Diff line
@@ -17,8 +17,15 @@
package com.android.systemui.statusbar.notification.row.wrapper;

import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Paint;
import android.os.Build;
import android.view.View;

import com.android.internal.graphics.ColorUtils;
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;

@@ -41,6 +48,47 @@ public class NotificationCustomViewWrapper extends NotificationViewWrapper {
        mView.setAlpha(visible ? 1.0f : 0.0f);
    }

    @Override
    public void onReinflated() {
        super.onReinflated();

        Configuration configuration = mView.getResources().getConfiguration();
        boolean nightMode = (configuration.uiMode & Configuration.UI_MODE_NIGHT_MASK)
                == Configuration.UI_MODE_NIGHT_YES;

        float[] hsl = new float[] {0f, 0f, 0f};
        ColorUtils.colorToHSL(mBackgroundColor, hsl);
        boolean backgroundIsDark = Color.alpha(mBackgroundColor) == 0
                || hsl[1] == 0 && hsl[2] < 0.5;
        boolean backgroundHasColor = hsl[1] > 0;

        // Let's invert the notification colors when we're in night mode and
        // the notification background isn't colorized.
        if (!backgroundIsDark && !backgroundHasColor && nightMode
                && mRow.getEntry().targetSdk < Build.VERSION_CODES.Q) {
            Paint paint = new Paint();
            ColorMatrix matrix = new ColorMatrix();
            ColorMatrix tmp = new ColorMatrix();
            // Inversion should happen on Y'UV space to conseve the colors and
            // only affect the luminosity.
            matrix.setRGB2YUV();
            tmp.set(new float[]{
                    -1f, 0f, 0f, 0f, 255f,
                    0f, 1f, 0f, 0f, 0f,
                    0f, 0f, 1f, 0f, 0f,
                    0f, 0f, 0f, 1f, 0f
            });
            matrix.postConcat(tmp);
            tmp.setYUV2RGB();
            matrix.postConcat(tmp);
            paint.setColorFilter(new ColorMatrixColorFilter(matrix));
            mView.setLayerType(View.LAYER_TYPE_HARDWARE, paint);

            hsl[2] = 1f - hsl[2];
            mBackgroundColor = ColorUtils.HSLToColor(hsl);
        }
    }

    @Override
    protected boolean shouldClearBackgroundOnReapply() {
        return false;
+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ public abstract class NotificationViewWrapper implements TransformableView {
    protected final View mView;
    protected final ExpandableNotificationRow mRow;

    private int mBackgroundColor = 0;
    protected int mBackgroundColor = 0;

    public static NotificationViewWrapper wrap(Context ctx, View v, ExpandableNotificationRow row) {
        if (v.getId() == com.android.internal.R.id.status_bar_latest_event_content) {