Loading core/java/android/app/Notification.java +33 −33 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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 Loading @@ -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); Loading Loading @@ -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); Loading @@ -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; Loading Loading @@ -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(), Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; } Loading @@ -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; Loading Loading @@ -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, Loading core/java/android/app/WallpaperColors.java +25 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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> Loading Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; } Loading core/java/android/widget/RemoteViews.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading core/java/com/android/internal/util/NotificationColorUtil.java→core/java/com/android/internal/util/ContrastColorUtil.java +12 −12 Original line number Diff line number Diff line Loading @@ -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 = Loading @@ -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); } Loading Loading @@ -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 */); } Loading @@ -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){ Loading @@ -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))); } } Loading @@ -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){ Loading @@ -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))); } } Loading Loading @@ -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; } /** Loading core/java/com/android/internal/widget/MessagingLayout.java +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
core/java/android/app/Notification.java +33 −33 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; } Loading Loading @@ -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; } Loading Loading @@ -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 Loading @@ -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); Loading Loading @@ -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); Loading @@ -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; Loading Loading @@ -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(), Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; } Loading @@ -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; Loading Loading @@ -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, Loading
core/java/android/app/WallpaperColors.java +25 −3 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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> Loading Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; } Loading
core/java/android/widget/RemoteViews.java +2 −2 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading
core/java/com/android/internal/util/NotificationColorUtil.java→core/java/com/android/internal/util/ContrastColorUtil.java +12 −12 Original line number Diff line number Diff line Loading @@ -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 = Loading @@ -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); } Loading Loading @@ -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 */); } Loading @@ -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){ Loading @@ -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))); } } Loading @@ -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){ Loading @@ -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))); } } Loading Loading @@ -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; } /** Loading
core/java/com/android/internal/widget/MessagingLayout.java +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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