diff --git a/core/java/com/android/internal/util/ContrastColorUtil.java b/core/java/com/android/internal/util/ContrastColorUtil.java index 8b3c1337c0c8d..7a712e50e6a8c 100644 --- a/core/java/com/android/internal/util/ContrastColorUtil.java +++ b/core/java/com/android/internal/util/ContrastColorUtil.java @@ -291,10 +291,10 @@ public class ContrastColorUtil { * 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 other the color to ensure contrast against. Assumed to be lighter than {@code color} + * @param findFg if true, we assume {@code 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 + * @return a color with the same hue as {@code color}, potentially darkened to meet the * contrast ratio. */ public static int findContrastColor(int color, int other, boolean findFg, double minRatio) { @@ -331,7 +331,7 @@ public class ContrastColorUtil { * @param color the color to start searching from. * @param backgroundColor the color to ensure contrast against. * @param minRatio the minimum contrast ratio required. - * @return the same color as {@param color} with potentially modified alpha to meet contrast + * @return the same color as {@code color} with potentially modified alpha to meet contrast */ public static int findAlphaToMeetContrast(int color, int backgroundColor, double minRatio) { int fg = color; @@ -361,10 +361,10 @@ public class ContrastColorUtil { * 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 darker than {@param color} - * @param findFg if true, we assume {@param color} is a foreground, otherwise a background. + * @param other the color to ensure contrast against. Assumed to be darker than {@code color} + * @param findFg if true, we assume {@code 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 + * @return a color with the same hue as {@code color}, potentially lightened to meet the * contrast ratio. */ public static int findContrastColorAgainstDark(int color, int other, boolean findFg, @@ -393,7 +393,8 @@ public class ContrastColorUtil { low = l; } } - return findFg ? fg : bg; + hsl[2] = high; + return ColorUtilsFromCompat.HSLToColor(hsl); } public static int ensureTextContrastOnBlack(int color) { @@ -452,7 +453,7 @@ public class ContrastColorUtil { } /** - * Resolves {@param color} to an actual color if it is {@link Notification#COLOR_DEFAULT} + * Resolves {@code color} to an actual color if it is {@link Notification#COLOR_DEFAULT} */ public static int resolveColor(Context context, int color, boolean defaultBackgroundIsDark) { if (color == Notification.COLOR_DEFAULT) { diff --git a/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java b/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java new file mode 100644 index 0000000000000..9da720cbfa877 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/util/ContrastColorUtilTest.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +package com.android.internal.util; + +import static androidx.core.graphics.ColorUtils.calculateContrast; + +import static com.google.common.truth.Truth.assertThat; + +import android.graphics.Color; + +import androidx.test.filters.SmallTest; + +import junit.framework.TestCase; + +public class ContrastColorUtilTest extends TestCase { + + @SmallTest + public void testEnsureTextContrastAgainstDark() { + int darkBg = 0xFF35302A; + + int blueContrastColor = ContrastColorUtil.ensureTextContrast(Color.BLUE, darkBg, true); + assertContrastIsWithinRange(blueContrastColor, darkBg, 4.5, 4.75); + + int redContrastColor = ContrastColorUtil.ensureTextContrast(Color.RED, darkBg, true); + assertContrastIsWithinRange(redContrastColor, darkBg, 4.5, 4.75); + + final int darkGreen = 0xff008800; + int greenContrastColor = ContrastColorUtil.ensureTextContrast(darkGreen, darkBg, true); + assertContrastIsWithinRange(greenContrastColor, darkBg, 4.5, 4.75); + + int grayContrastColor = ContrastColorUtil.ensureTextContrast(Color.DKGRAY, darkBg, true); + assertContrastIsWithinRange(grayContrastColor, darkBg, 4.5, 4.75); + + int selfContrastColor = ContrastColorUtil.ensureTextContrast(darkBg, darkBg, true); + assertContrastIsWithinRange(selfContrastColor, darkBg, 4.5, 4.75); + } + + @SmallTest + public void testEnsureTextContrastAgainstLight() { + int lightBg = 0xFFFFF8F2; + + final int lightBlue = 0xff8888ff; + int blueContrastColor = ContrastColorUtil.ensureTextContrast(lightBlue, lightBg, false); + assertContrastIsWithinRange(blueContrastColor, lightBg, 4.5, 4.75); + + int redContrastColor = ContrastColorUtil.ensureTextContrast(Color.RED, lightBg, false); + assertContrastIsWithinRange(redContrastColor, lightBg, 4.5, 4.75); + + int greenContrastColor = ContrastColorUtil.ensureTextContrast(Color.GREEN, lightBg, false); + assertContrastIsWithinRange(greenContrastColor, lightBg, 4.5, 4.75); + + int grayContrastColor = ContrastColorUtil.ensureTextContrast(Color.LTGRAY, lightBg, false); + assertContrastIsWithinRange(grayContrastColor, lightBg, 4.5, 4.75); + + int selfContrastColor = ContrastColorUtil.ensureTextContrast(lightBg, lightBg, false); + assertContrastIsWithinRange(selfContrastColor, lightBg, 4.5, 4.75); + } + + private void assertContrastIsWithinRange(int foreground, int background, + double minContrast, double maxContrast) { + assertContrastIsAtLeast(foreground, background, minContrast); + assertContrastIsAtMost(foreground, background, maxContrast); + } + + private void assertContrastIsAtLeast(int foreground, int background, double minContrast) { + try { + assertThat(calculateContrast(foreground, background)).isAtLeast(minContrast); + } catch (AssertionError e) { + throw new AssertionError( + String.format("Insufficient contrast: foreground=#%08x background=#%08x", + foreground, background), e); + } + } + + private void assertContrastIsAtMost(int foreground, int background, double maxContrast) { + try { + assertThat(calculateContrast(foreground, background)).isAtMost(maxContrast); + } catch (AssertionError e) { + throw new AssertionError( + String.format("Excessive contrast: foreground=#%08x background=#%08x", + foreground, background), e); + } + } + +}