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

Commit 7231e7b6 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "More conservative dark text calculation"

parents 1c3a6989 a291d19e
Loading
Loading
Loading
Loading
+33 −33
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package android.app;

import static com.android.internal.util.NotificationColorUtil.satisfiesTextContrast;
import static com.android.internal.util.ContrastColorUtil.satisfiesTextContrast;

import android.annotation.ColorInt;
import android.annotation.DrawableRes;
@@ -79,7 +79,7 @@ import android.widget.RemoteViews;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.NotificationColorUtil;
import com.android.internal.util.ContrastColorUtil;
import com.android.internal.util.Preconditions;

import java.lang.annotation.Retention;
@@ -3176,7 +3176,7 @@ public class Notification implements Parcelable
        private Style mStyle;
        private ArrayList<Action> mActions = new ArrayList<Action>(MAX_ACTION_BUTTONS);
        private ArrayList<Person> mPersonList = new ArrayList<>();
        private NotificationColorUtil mColorUtil;
        private ContrastColorUtil mColorUtil;
        private boolean mIsLegacy;
        private boolean mIsLegacyInitialized;

@@ -3307,9 +3307,9 @@ public class Notification implements Parcelable
            }
        }

        private NotificationColorUtil getColorUtil() {
        private ContrastColorUtil getColorUtil() {
            if (mColorUtil == null) {
                mColorUtil = NotificationColorUtil.getInstance(mContext);
                mColorUtil = ContrastColorUtil.getInstance(mContext);
            }
            return mColorUtil;
        }
@@ -4427,7 +4427,7 @@ public class Notification implements Parcelable

        private CharSequence processTextSpans(CharSequence text) {
            if (hasForegroundColor()) {
                return NotificationColorUtil.clearColorSpans(text);
                return ContrastColorUtil.clearColorSpans(text);
            }
            return text;
        }
@@ -4473,20 +4473,20 @@ public class Notification implements Parcelable
                    || mTextColorsAreForBackground != backgroundColor) {
                mTextColorsAreForBackground = backgroundColor;
                if (!hasForegroundColor() || !isColorized()) {
                    mPrimaryTextColor = NotificationColorUtil.resolvePrimaryColor(mContext,
                    mPrimaryTextColor = ContrastColorUtil.resolvePrimaryColor(mContext,
                            backgroundColor);
                    mSecondaryTextColor = NotificationColorUtil.resolveSecondaryColor(mContext,
                    mSecondaryTextColor = ContrastColorUtil.resolveSecondaryColor(mContext,
                            backgroundColor);
                    if (backgroundColor != COLOR_DEFAULT && isColorized()) {
                        mPrimaryTextColor = NotificationColorUtil.findAlphaToMeetContrast(
                        mPrimaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
                                mPrimaryTextColor, backgroundColor, 4.5);
                        mSecondaryTextColor = NotificationColorUtil.findAlphaToMeetContrast(
                        mSecondaryTextColor = ContrastColorUtil.findAlphaToMeetContrast(
                                mSecondaryTextColor, backgroundColor, 4.5);
                    }
                } else {
                    double backLum = NotificationColorUtil.calculateLuminance(backgroundColor);
                    double textLum = NotificationColorUtil.calculateLuminance(mForegroundColor);
                    double contrast = NotificationColorUtil.calculateContrast(mForegroundColor,
                    double backLum = ContrastColorUtil.calculateLuminance(backgroundColor);
                    double textLum = ContrastColorUtil.calculateLuminance(mForegroundColor);
                    double contrast = ContrastColorUtil.calculateContrast(mForegroundColor,
                            backgroundColor);
                    // We only respect the given colors if worst case Black or White still has
                    // contrast
@@ -4496,46 +4496,46 @@ public class Notification implements Parcelable
                                    && !satisfiesTextContrast(backgroundColor, Color.WHITE);
                    if (contrast < 4.5f) {
                        if (backgroundLight) {
                            mSecondaryTextColor = NotificationColorUtil.findContrastColor(
                            mSecondaryTextColor = ContrastColorUtil.findContrastColor(
                                    mForegroundColor,
                                    backgroundColor,
                                    true /* findFG */,
                                    4.5f);
                            mPrimaryTextColor = NotificationColorUtil.changeColorLightness(
                            mPrimaryTextColor = ContrastColorUtil.changeColorLightness(
                                    mSecondaryTextColor, -LIGHTNESS_TEXT_DIFFERENCE_LIGHT);
                        } else {
                            mSecondaryTextColor =
                                    NotificationColorUtil.findContrastColorAgainstDark(
                                    ContrastColorUtil.findContrastColorAgainstDark(
                                    mForegroundColor,
                                    backgroundColor,
                                    true /* findFG */,
                                    4.5f);
                            mPrimaryTextColor = NotificationColorUtil.changeColorLightness(
                            mPrimaryTextColor = ContrastColorUtil.changeColorLightness(
                                    mSecondaryTextColor, -LIGHTNESS_TEXT_DIFFERENCE_DARK);
                        }
                    } else {
                        mPrimaryTextColor = mForegroundColor;
                        mSecondaryTextColor = NotificationColorUtil.changeColorLightness(
                        mSecondaryTextColor = ContrastColorUtil.changeColorLightness(
                                mPrimaryTextColor, backgroundLight ? LIGHTNESS_TEXT_DIFFERENCE_LIGHT
                                        : LIGHTNESS_TEXT_DIFFERENCE_DARK);
                        if (NotificationColorUtil.calculateContrast(mSecondaryTextColor,
                        if (ContrastColorUtil.calculateContrast(mSecondaryTextColor,
                                backgroundColor) < 4.5f) {
                            // oh well the secondary is not good enough
                            if (backgroundLight) {
                                mSecondaryTextColor = NotificationColorUtil.findContrastColor(
                                mSecondaryTextColor = ContrastColorUtil.findContrastColor(
                                        mSecondaryTextColor,
                                        backgroundColor,
                                        true /* findFG */,
                                        4.5f);
                            } else {
                                mSecondaryTextColor
                                        = NotificationColorUtil.findContrastColorAgainstDark(
                                        = ContrastColorUtil.findContrastColorAgainstDark(
                                        mSecondaryTextColor,
                                        backgroundColor,
                                        true /* findFG */,
                                        4.5f);
                            }
                            mPrimaryTextColor = NotificationColorUtil.changeColorLightness(
                            mPrimaryTextColor = ContrastColorUtil.changeColorLightness(
                                    mSecondaryTextColor, backgroundLight
                                            ? -LIGHTNESS_TEXT_DIFFERENCE_LIGHT
                                            : -LIGHTNESS_TEXT_DIFFERENCE_DARK);
@@ -5247,7 +5247,7 @@ public class Notification implements Parcelable
                ColorStateList[] outResultColor = null;
                int background = resolveBackgroundColor();
                if (isLegacy()) {
                    title = NotificationColorUtil.clearColorSpans(title);
                    title = ContrastColorUtil.clearColorSpans(title);
                } else {
                    outResultColor = new ColorStateList[1];
                    title = ensureColorSpanContrast(title, background, outResultColor);
@@ -5260,7 +5260,7 @@ public class Notification implements Parcelable
                    // There's a span spanning the full text, let's take it and use it as the
                    // background color
                    background = outResultColor[0].getDefaultColor();
                    int textColor = NotificationColorUtil.resolvePrimaryColor(mContext,
                    int textColor = ContrastColorUtil.resolvePrimaryColor(mContext,
                            background);
                    button.setTextColor(R.id.action0, textColor);
                    rippleColor = textColor;
@@ -5321,7 +5321,7 @@ public class Notification implements Parcelable
                            int[] colors = textColor.getColors();
                            int[] newColors = new int[colors.length];
                            for (int i = 0; i < newColors.length; i++) {
                                newColors[i] = NotificationColorUtil.ensureLargeTextContrast(
                                newColors[i] = ContrastColorUtil.ensureLargeTextContrast(
                                        colors[i], background, mInNightMode);
                            }
                            textColor = new ColorStateList(textColor.getStates().clone(),
@@ -5341,7 +5341,7 @@ public class Notification implements Parcelable
                    } else if (resultSpan instanceof ForegroundColorSpan) {
                        ForegroundColorSpan originalSpan = (ForegroundColorSpan) resultSpan;
                        int foregroundColor = originalSpan.getForegroundColor();
                        foregroundColor = NotificationColorUtil.ensureLargeTextContrast(
                        foregroundColor = ContrastColorUtil.ensureLargeTextContrast(
                                foregroundColor, background, mInNightMode);
                        if (fullLength) {
                            outResultColor[0] = ColorStateList.valueOf(foregroundColor);
@@ -5441,14 +5441,14 @@ public class Notification implements Parcelable
                    com.android.internal.R.color.notification_material_background_color);
            if (mN.color == COLOR_DEFAULT) {
                ensureColors();
                color = NotificationColorUtil.resolveDefaultColor(mContext, background);
                color = ContrastColorUtil.resolveDefaultColor(mContext, background);
            } else {
                color = NotificationColorUtil.resolveContrastColor(mContext, mN.color,
                color = ContrastColorUtil.resolveContrastColor(mContext, mN.color,
                        background, mInNightMode);
            }
            if (Color.alpha(color) < 255) {
                // alpha doesn't go well for color filters, so let's blend it manually
                color = NotificationColorUtil.compositeColors(color, background);
                color = ContrastColorUtil.compositeColors(color, background);
            }
            mCachedContrastColorIsFor = mN.color;
            return mCachedContrastColor = color;
@@ -5460,10 +5460,10 @@ public class Notification implements Parcelable
            }
            int background = mContext.getColor(
                    com.android.internal.R.color.notification_material_background_color);
            mNeutralColor = NotificationColorUtil.resolveDefaultColor(mContext, background);
            mNeutralColor = ContrastColorUtil.resolveDefaultColor(mContext, background);
            if (Color.alpha(mNeutralColor) < 255) {
                // alpha doesn't go well for color filters, so let's blend it manually
                mNeutralColor = NotificationColorUtil.compositeColors(mNeutralColor, background);
                mNeutralColor = ContrastColorUtil.compositeColors(mNeutralColor, background);
            }
            return mNeutralColor;
        }
@@ -5472,7 +5472,7 @@ public class Notification implements Parcelable
            if (mCachedAmbientColorIsFor == mN.color && mCachedAmbientColorIsFor != COLOR_INVALID) {
                return mCachedAmbientColor;
            }
            final int contrasted = NotificationColorUtil.resolveAmbientColor(mContext, mN.color);
            final int contrasted = ContrastColorUtil.resolveAmbientColor(mContext, mN.color);

            mCachedAmbientColorIsFor = mN.color;
            return mCachedAmbientColor = contrasted;
@@ -7833,7 +7833,7 @@ public class Notification implements Parcelable
            // notification color. Otherwise, just use the passed-in color.
            int tintColor = mBuilder.shouldTintActionButtons() || mBuilder.isColorized()
                    ? color
                    : NotificationColorUtil.resolveColor(mBuilder.mContext,
                    : ContrastColorUtil.resolveColor(mBuilder.mContext,
                            Notification.COLOR_DEFAULT);

            button.setDrawableTint(R.id.action0, false, tintColor,
+25 −3
Original line number Diff line number Diff line
@@ -25,12 +25,15 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
import android.util.Size;

import com.android.internal.graphics.ColorUtils;
import com.android.internal.graphics.palette.Palette;
import com.android.internal.graphics.palette.VariationalKMeansQuantizer;
import com.android.internal.util.ContrastColorUtil;

import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -44,6 +47,8 @@ import java.util.List;
 */
public final class WallpaperColors implements Parcelable {

    private static final boolean DEBUG_DARK_PIXELS = false;

    /**
     * Specifies that dark text is preferred over the current wallpaper for best presentation.
     * <p>
@@ -83,8 +88,8 @@ public final class WallpaperColors implements Parcelable {
    private static final float BRIGHT_IMAGE_MEAN_LUMINANCE = 0.75f;
    // We also check if the image has dark pixels in it,
    // to avoid bright images with some dark spots.
    private static final float DARK_PIXEL_LUMINANCE = 0.45f;
    private static final float MAX_DARK_AREA = 0.05f;
    private static final float DARK_PIXEL_CONTRAST = 6f;
    private static final float MAX_DARK_AREA = 0.025f;

    private final ArrayList<Color> mMainColors;
    private int mColorHints;
@@ -382,8 +387,13 @@ public final class WallpaperColors implements Parcelable {
            final int alpha = Color.alpha(pixels[i]);
            // Make sure we don't have a dark pixel mass that will
            // make text illegible.
            if (luminance < DARK_PIXEL_LUMINANCE && alpha != 0) {
            final boolean satisfiesTextContrast = ContrastColorUtil
                    .calculateContrast(pixels[i], Color.BLACK) > DARK_PIXEL_CONTRAST;
            if (!satisfiesTextContrast && alpha != 0) {
                darkPixels++;
                if (DEBUG_DARK_PIXELS) {
                    pixels[i] = Color.RED;
                }
            }
            totalLuminance += luminance;
        }
@@ -397,6 +407,18 @@ public final class WallpaperColors implements Parcelable {
            hints |= HINT_SUPPORTS_DARK_THEME;
        }

        if (DEBUG_DARK_PIXELS) {
            try (FileOutputStream out = new FileOutputStream("/data/pixels.png")) {
                source.setPixels(pixels, 0, source.getWidth(), 0, 0, source.getWidth(),
                        source.getHeight());
                source.compress(Bitmap.CompressFormat.PNG, 100, out);
            } catch (Exception e) {
                e.printStackTrace();
            }
            Log.d("WallpaperColors", "l: " + meanLuminance + ", d: " + darkPixels +
                    " maxD: " + maxDarkPixels + " numPixels: " + pixels.length);
        }

        return hints;
    }

+2 −2
Original line number Diff line number Diff line
@@ -68,7 +68,7 @@ import android.view.ViewStub;
import android.widget.AdapterView.OnItemClickListener;

import com.android.internal.R;
import com.android.internal.util.NotificationColorUtil;
import com.android.internal.util.ContrastColorUtil;
import com.android.internal.util.Preconditions;

import java.lang.annotation.ElementType;
@@ -2155,7 +2155,7 @@ public class RemoteViews implements Parcelable, Filter {
                View v = viewsToProcess.pop();
                if (v instanceof TextView) {
                    TextView textView = (TextView) v;
                    textView.setText(NotificationColorUtil.clearColorSpans(textView.getText()));
                    textView.setText(ContrastColorUtil.clearColorSpans(textView.getText()));
                    textView.setTextColor(textColor);
                }
                if (v instanceof ViewGroup) {
+12 −12
Original line number Diff line number Diff line
@@ -48,13 +48,13 @@ import java.util.WeakHashMap;
 *
 * @hide
 */
public class NotificationColorUtil {
public class ContrastColorUtil {

    private static final String TAG = "NotificationColorUtil";
    private static final String TAG = "ContrastColorUtil";
    private static final boolean DEBUG = false;

    private static final Object sLock = new Object();
    private static NotificationColorUtil sInstance;
    private static ContrastColorUtil sInstance;

    private final ImageUtils mImageUtils = new ImageUtils();
    private final WeakHashMap<Bitmap, Pair<Boolean, Integer>> mGrayscaleBitmapCache =
@@ -62,16 +62,16 @@ public class NotificationColorUtil {

    private final int mGrayscaleIconMaxSize; // @dimen/notification_large_icon_width (64dp)

    public static NotificationColorUtil getInstance(Context context) {
    public static ContrastColorUtil getInstance(Context context) {
        synchronized (sLock) {
            if (sInstance == null) {
                sInstance = new NotificationColorUtil(context);
                sInstance = new ContrastColorUtil(context);
            }
            return sInstance;
        }
    }

    private NotificationColorUtil(Context context) {
    private ContrastColorUtil(Context context) {
        mGrayscaleIconMaxSize = context.getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.notification_large_icon_width);
    }
@@ -470,7 +470,7 @@ public class NotificationColorUtil {
     */
    public static int resolveContrastColor(Context context, int notificationColor,
            int backgroundColor) {
        return NotificationColorUtil.resolveContrastColor(context, notificationColor,
        return ContrastColorUtil.resolveContrastColor(context, notificationColor,
                backgroundColor, false /* isDark */);
    }

@@ -489,7 +489,7 @@ public class NotificationColorUtil {
        final int resolvedColor = resolveColor(context, notificationColor);

        int color = resolvedColor;
        color = NotificationColorUtil.ensureTextContrast(color, backgroundColor, isDark);
        color = ContrastColorUtil.ensureTextContrast(color, backgroundColor, isDark);

        if (color != resolvedColor) {
            if (DEBUG){
@@ -497,7 +497,7 @@ public class NotificationColorUtil {
                        "Enhanced contrast of notification for %s"
                                + " and %s (over background) by changing #%s to %s",
                        context.getPackageName(),
                        NotificationColorUtil.contrastChange(resolvedColor, color, backgroundColor),
                        ContrastColorUtil.contrastChange(resolvedColor, color, backgroundColor),
                        Integer.toHexString(resolvedColor), Integer.toHexString(color)));
            }
        }
@@ -523,7 +523,7 @@ public class NotificationColorUtil {
        final int resolvedColor = resolveColor(context, notificationColor);

        int color = resolvedColor;
        color = NotificationColorUtil.ensureTextContrastOnBlack(color);
        color = ContrastColorUtil.ensureTextContrastOnBlack(color);

        if (color != resolvedColor) {
            if (DEBUG){
@@ -531,7 +531,7 @@ public class NotificationColorUtil {
                        "Ambient contrast of notification for %s is %s (over black)"
                                + " by changing #%s to #%s",
                        context.getPackageName(),
                        NotificationColorUtil.contrastChange(resolvedColor, color, Color.BLACK),
                        ContrastColorUtil.contrastChange(resolvedColor, color, Color.BLACK),
                        Integer.toHexString(resolvedColor), Integer.toHexString(color)));
            }
        }
@@ -609,7 +609,7 @@ public class NotificationColorUtil {
    }

    public static boolean satisfiesTextContrast(int backgroundColor, int foregroundColor) {
        return NotificationColorUtil.calculateContrast(foregroundColor, backgroundColor) >= 4.5;
        return ContrastColorUtil.calculateContrast(foregroundColor, backgroundColor) >= 4.5;
    }

    /**
+3 −3
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ import android.widget.TextView;

import com.android.internal.R;
import com.android.internal.graphics.ColorUtils;
import com.android.internal.util.NotificationColorUtil;
import com.android.internal.util.ContrastColorUtil;

import java.util.ArrayList;
import java.util.List;
@@ -315,13 +315,13 @@ public class MessagingLayout extends FrameLayout {
    }

    private int findColor(CharSequence senderName, int layoutColor) {
        double luminance = NotificationColorUtil.calculateLuminance(layoutColor);
        double luminance = ContrastColorUtil.calculateLuminance(layoutColor);
        float shift = Math.abs(senderName.hashCode()) % 5 / 4.0f - 0.5f;

        // we need to offset the range if the luminance is too close to the borders
        shift += Math.max(COLOR_SHIFT_AMOUNT / 2.0f / 100 - luminance, 0);
        shift -= Math.max(COLOR_SHIFT_AMOUNT / 2.0f / 100 - (1.0f - luminance), 0);
        return NotificationColorUtil.getShiftedColor(layoutColor,
        return ContrastColorUtil.getShiftedColor(layoutColor,
                (int) (shift * COLOR_SHIFT_AMOUNT));
    }

Loading