summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/graphics/IconPalette.java
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2017-01-27 08:45:49 -0800
committerTony Wickham <twickham@google.com>2017-01-27 12:43:31 -0800
commitf79877c04c071b7ae1618395f0a1dce134fec36e (patch)
tree2bf2e66b101825b4d9e98f2077dc8cfcf1cf48f6 /src/com/android/launcher3/graphics/IconPalette.java
parent5cfd1158ec1e4a19689217e9fbddd0fd795b2611 (diff)
downloadandroid_packages_apps_Trebuchet-f79877c04c071b7ae1618395f0a1dce134fec36e.tar.gz
android_packages_apps_Trebuchet-f79877c04c071b7ae1618395f0a1dce134fec36e.tar.bz2
android_packages_apps_Trebuchet-f79877c04c071b7ae1618395f0a1dce134fec36e.zip
Ensure notification icons have enough contrast with background.
This uses the same color calculations as the system, except that we use the extracted notification background instead of assuming it is white. Bug: 32410600 Change-Id: I7be8b9459ca38d01a6780758898541e69ec42576
Diffstat (limited to 'src/com/android/launcher3/graphics/IconPalette.java')
-rw-r--r--src/com/android/launcher3/graphics/IconPalette.java102
1 files changed, 102 insertions, 0 deletions
diff --git a/src/com/android/launcher3/graphics/IconPalette.java b/src/com/android/launcher3/graphics/IconPalette.java
index 58ad449d6..27aeaba34 100644
--- a/src/com/android/launcher3/graphics/IconPalette.java
+++ b/src/com/android/launcher3/graphics/IconPalette.java
@@ -16,14 +16,22 @@
package com.android.launcher3.graphics;
+import android.app.Notification;
+import android.content.Context;
import android.graphics.Color;
import android.support.v4.graphics.ColorUtils;
+import android.util.Log;
+
+import com.android.launcher3.R;
/**
* Contains colors based on the dominant color of an icon.
*/
public class IconPalette {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "IconPalette";
+
public int backgroundColor;
public int textColor;
public int secondaryColor;
@@ -36,6 +44,100 @@ public class IconPalette {
return palette;
}
+ /**
+ * Resolves a color such that it has enough contrast to be used as the
+ * color of an icon or text on the given background color.
+ *
+ * @return a color of the same hue with enough contrast against the background.
+ *
+ * This was copied from com.android.internal.util.NotificationColorUtil.
+ */
+ public static int resolveContrastColor(Context context, int color, int background) {
+ final int resolvedColor = resolveColor(context, color);
+
+ int contrastingColor = ensureTextContrast(resolvedColor, background);
+
+ if (contrastingColor != resolvedColor) {
+ if (DEBUG){
+ Log.w(TAG, String.format(
+ "Enhanced contrast of notification for %s " +
+ "%s (over background) by changing #%s to %s",
+ context.getPackageName(),
+ contrastChange(resolvedColor, contrastingColor, background),
+ Integer.toHexString(resolvedColor), Integer.toHexString(contrastingColor)));
+ }
+ }
+ return contrastingColor;
+ }
+
+ /**
+ * Resolves {@param color} to an actual color if it is {@link Notification#COLOR_DEFAULT}
+ *
+ * This was copied from com.android.internal.util.NotificationColorUtil.
+ */
+ private static int resolveColor(Context context, int color) {
+ if (color == Notification.COLOR_DEFAULT) {
+ return context.getColor(R.color.notification_icon_default_color);
+ }
+ return color;
+ }
+
+ /** For debugging. This was copied from com.android.internal.util.NotificationColorUtil. */
+ private static String contrastChange(int colorOld, int colorNew, int bg) {
+ return String.format("from %.2f:1 to %.2f:1",
+ ColorUtils.calculateContrast(colorOld, bg),
+ ColorUtils.calculateContrast(colorNew, bg));
+ }
+
+ /**
+ * Finds a text color with sufficient contrast over bg that has the same hue as the original
+ * color.
+ *
+ * This was copied from com.android.internal.util.NotificationColorUtil.
+ */
+ private static int ensureTextContrast(int color, int bg) {
+ return findContrastColor(color, bg, true, 4.5);
+ }
+ /**
+ * Finds a suitable color such that there's enough contrast.
+ *
+ * @param color the color to start searching from.
+ * @param other the color to ensure contrast against. Assumed to be lighter than {@param color}
+ * @param findFg if true, we assume {@param color} is a foreground, otherwise a background.
+ * @param minRatio the minimum contrast ratio required.
+ * @return a color with the same hue as {@param color}, potentially darkened to meet the
+ * contrast ratio.
+ *
+ * This was copied from com.android.internal.util.NotificationColorUtil.
+ */
+ private static int findContrastColor(int color, int other, boolean findFg, double minRatio) {
+ int fg = findFg ? color : other;
+ int bg = findFg ? other : color;
+ if (ColorUtils.calculateContrast(fg, bg) >= minRatio) {
+ return color;
+ }
+
+ double[] lab = new double[3];
+ ColorUtils.colorToLAB(findFg ? fg : bg, lab);
+
+ double low = 0, high = lab[0];
+ final double a = lab[1], b = lab[2];
+ for (int i = 0; i < 15 && high - low > 0.00001; i++) {
+ final double l = (low + high) / 2;
+ if (findFg) {
+ fg = ColorUtils.LABToColor(l, a, b);
+ } else {
+ bg = ColorUtils.LABToColor(l, a, b);
+ }
+ if (ColorUtils.calculateContrast(fg, bg) > minRatio) {
+ low = l;
+ } else {
+ high = l;
+ }
+ }
+ return ColorUtils.LABToColor(low, a, b);
+ }
+
private static int getMutedColor(int color) {
int alpha = (int) (255 * 0.15f);
return ColorUtils.compositeColors(ColorUtils.setAlphaComponent(color, alpha), Color.WHITE);