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

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

Do not filter out some colors

Colors specified manually using the public WallpaperColors
constructor should not be blacklisted.

Test: runtest -x tests/Internal/src/android/app/WallpaperColorsTest.java
Test: runtest -x tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
Change-Id: I96faf413e3629c247220d825bb7c3480ed2f1003
Fixes: 64361146
parent 143c678b
Loading
Loading
Loading
Loading
+11 −5
Original line number Original line Diff line number Diff line
@@ -49,7 +49,7 @@ public final class WallpaperColors implements Parcelable {
     * eg. A launcher may set its text color to black if this flag is specified.
     * eg. A launcher may set its text color to black if this flag is specified.
     * @hide
     * @hide
     */
     */
    public static final int HINT_SUPPORTS_DARK_TEXT = 0x1;
    public static final int HINT_SUPPORTS_DARK_TEXT = 1 << 0;


    /**
    /**
     * Specifies that dark theme is preferred over the current wallpaper for best presentation.
     * Specifies that dark theme is preferred over the current wallpaper for best presentation.
@@ -57,7 +57,13 @@ public final class WallpaperColors implements Parcelable {
     * eg. A launcher may set its drawer color to black if this flag is specified.
     * eg. A launcher may set its drawer color to black if this flag is specified.
     * @hide
     * @hide
     */
     */
    public static final int HINT_SUPPORTS_DARK_THEME = 0x2;
    public static final int HINT_SUPPORTS_DARK_THEME = 1 << 1;

    /**
     * Specifies that this object was generated by extracting colors from a bitmap.
     * @hide
     */
    public static final int HINT_FROM_BITMAP = 1 << 2;


    // Maximum size that a bitmap can have to keep our calculations sane
    // Maximum size that a bitmap can have to keep our calculations sane
    private static final int MAX_BITMAP_SIZE = 112;
    private static final int MAX_BITMAP_SIZE = 112;
@@ -180,13 +186,13 @@ public final class WallpaperColors implements Parcelable {
            }
            }
        }
        }


        int hints = calculateHints(bitmap);
        int hints = calculateDarkHints(bitmap);


        if (shouldRecycle) {
        if (shouldRecycle) {
            bitmap.recycle();
            bitmap.recycle();
        }
        }


        return new WallpaperColors(primary, secondary, tertiary, hints);
        return new WallpaperColors(primary, secondary, tertiary, HINT_FROM_BITMAP | hints);
    }
    }


    /**
    /**
@@ -348,7 +354,7 @@ public final class WallpaperColors implements Parcelable {
     * @param source What to read.
     * @param source What to read.
     * @return Whether image supports dark text or not.
     * @return Whether image supports dark text or not.
     */
     */
    private static int calculateHints(Bitmap source) {
    private static int calculateDarkHints(Bitmap source) {
        if (source == null) {
        if (source == null) {
            return 0;
            return 0;
        }
        }
+13 −8
Original line number Original line Diff line number Diff line
@@ -111,18 +111,19 @@ public class Tonal implements ExtractionType {


        final List<Color> mainColors = inWallpaperColors.getMainColors();
        final List<Color> mainColors = inWallpaperColors.getMainColors();
        final int mainColorsSize = mainColors.size();
        final int mainColorsSize = mainColors.size();
        final boolean supportsDarkText = (inWallpaperColors.getColorHints() &
        final int hints = inWallpaperColors.getColorHints();
                WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
        final boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
        final boolean generatedFromBitmap = (hints & WallpaperColors.HINT_FROM_BITMAP) != 0;


        if (mainColorsSize == 0) {
        if (mainColorsSize == 0) {
            return false;
            return false;
        }
        }
        // Tonal is not really a sort, it takes a color from the extracted
        // palette and finds a best fit amongst a collection of pre-defined
        // palettes. The best fit is tweaked to be closer to the source color
        // and replaces the original palette


        // Get the most preeminent, non-blacklisted color.
        // Decide what's the best color to use.
        // We have 2 options:
        // • Just pick the primary color
        // • Filter out blacklisted colors. This is useful when palette is generated
        //   automatically from a bitmap.
        Color bestColor = null;
        Color bestColor = null;
        final float[] hsl = new float[3];
        final float[] hsl = new float[3];
        for (int i = 0; i < mainColorsSize; i++) {
        for (int i = 0; i < mainColorsSize; i++) {
@@ -132,7 +133,7 @@ public class Tonal implements ExtractionType {
                    Color.blue(colorValue), hsl);
                    Color.blue(colorValue), hsl);


            // Stop when we find a color that meets our criteria
            // Stop when we find a color that meets our criteria
            if (!isBlacklisted(hsl)) {
            if (!generatedFromBitmap || !isBlacklisted(hsl)) {
                bestColor = color;
                bestColor = color;
                break;
                break;
            }
            }
@@ -143,6 +144,10 @@ public class Tonal implements ExtractionType {
            return false;
            return false;
        }
        }


        // Tonal is not really a sort, it takes a color from the extracted
        // palette and finds a best fit amongst a collection of pre-defined
        // palettes. The best fit is tweaked to be closer to the source color
        // and replaces the original palette.
        int colorValue = bestColor.toArgb();
        int colorValue = bestColor.toArgb();
        ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
        ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
                hsl);
                hsl);
+15 −7
Original line number Original line Diff line number Diff line
@@ -36,12 +36,12 @@ public class WallpaperColorsTest {
        final Color color = Color.valueOf(Color.WHITE);
        final Color color = Color.valueOf(Color.WHITE);
        // Default should not support dark text!
        // Default should not support dark text!
        WallpaperColors colors = new WallpaperColors(color, null, null, 0);
        WallpaperColors colors = new WallpaperColors(color, null, null, 0);
        Assert.assertTrue("Default behavior is not to support dark text",
        Assert.assertTrue("Default behavior is not to support dark text.",
                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);
                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);


        // Override it
        // Override it
        colors = new WallpaperColors(color, null, null, WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
        colors = new WallpaperColors(color, null, null, WallpaperColors.HINT_SUPPORTS_DARK_TEXT);
        Assert.assertFalse("Forcing dark text support doesn't work",
        Assert.assertFalse("Forcing dark text support doesn't work.",
                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);
                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);
    }
    }


@@ -57,15 +57,18 @@ public class WallpaperColorsTest {
        int hints = WallpaperColors.fromBitmap(image).getColorHints();
        int hints = WallpaperColors.fromBitmap(image).getColorHints();
        boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
        boolean supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
        boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
        boolean supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
        Assert.assertTrue("White surface should support dark text", supportsDarkText);
        boolean fromBitmap = (hints & WallpaperColors.HINT_FROM_BITMAP) != 0;
        Assert.assertFalse("White surface shouldn't support dark theme", supportsDarkTheme);
        Assert.assertTrue("White surface should support dark text.", supportsDarkText);
        Assert.assertFalse("White surface shouldn't support dark theme.", supportsDarkTheme);
        Assert.assertTrue("From bitmap should be true if object was created "
                + "using WallpaperColors#fromBitmap.", fromBitmap);


        canvas.drawColor(Color.BLACK);
        canvas.drawColor(Color.BLACK);
        hints = WallpaperColors.fromBitmap(image).getColorHints();
        hints = WallpaperColors.fromBitmap(image).getColorHints();
        supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
        supportsDarkText = (hints & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
        supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
        supportsDarkTheme = (hints & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;
        Assert.assertFalse("Black surface shouldn't support dark text", supportsDarkText);
        Assert.assertFalse("Black surface shouldn't support dark text.", supportsDarkText);
        Assert.assertTrue("Black surface should support dark theme", supportsDarkTheme);
        Assert.assertTrue("Black surface should support dark theme.", supportsDarkTheme);


        Paint paint = new Paint();
        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setStyle(Paint.Style.FILL);
@@ -75,7 +78,12 @@ public class WallpaperColorsTest {
        supportsDarkText = (WallpaperColors.fromBitmap(image)
        supportsDarkText = (WallpaperColors.fromBitmap(image)
                .getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
                .getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
        Assert.assertFalse("Light surface shouldn't support dark text "
        Assert.assertFalse("Light surface shouldn't support dark text "
                + "when it contains dark pixels", supportsDarkText);
                + "when it contains dark pixels.", supportsDarkText);

        WallpaperColors colors = new WallpaperColors(Color.valueOf(Color.GREEN), null, null);
        fromBitmap = (colors.getColorHints() & WallpaperColors.HINT_FROM_BITMAP) != 0;
        Assert.assertFalse("Object created from public constructor should not contain "
                + "HINT_FROM_BITMAP.", fromBitmap);
    }
    }


    /**
    /**
+26 −7
Original line number Original line Diff line number Diff line
@@ -99,20 +99,39 @@ public class TonalTest {
    }
    }


    @Test
    @Test
    public void tonal_excludeBlacklistedColor() {
    public void tonal_blacklistTest() {
        // Make sure that palette generation will fail.
        // Make sure that palette generation will fail.
        Tonal tonal = new Tonal(InstrumentationRegistry.getContext());
        final Tonal tonal = new Tonal(InstrumentationRegistry.getContext());


        // Creating a WallpaperColors object that contains *only* blacklisted colors.
        // Creating a WallpaperColors object that contains *only* blacklisted colors.
        float[] hsl = tonal.getBlacklistedColors().get(0).getCenter();
        final float[] hsl = tonal.getBlacklistedColors().get(0).getCenter();
        WallpaperColors colors = new WallpaperColors(Color.valueOf(ColorUtils.HSLToColor(hsl)),
        final int blacklistedColor = ColorUtils.HSLToColor(hsl);
                null, null, 0);
        WallpaperColors colorsFromBitmap = new WallpaperColors(Color.valueOf(blacklistedColor),
                null, null, WallpaperColors.HINT_FROM_BITMAP);


        // Make sure that palette generation will fail
        // Make sure that palette generation will fail
        GradientColors normal = new GradientColors();
        final GradientColors normal = new GradientColors();
        tonal.extractInto(colors, normal, new GradientColors(),
        tonal.extractInto(colorsFromBitmap, normal, new GradientColors(),
                new GradientColors());
                new GradientColors());
        assertTrue("Cannot generate a tonal palette from blacklisted colors.",
        assertTrue("Cannot generate a tonal palette from blacklisted colors.",
                normal.getMainColor() == Tonal.MAIN_COLOR_DARK);
                normal.getMainColor() == Tonal.MAIN_COLOR_DARK);
    }
    }

    @Test
    public void tonal_ignoreBlacklistTest() {
        final Tonal tonal = new Tonal(InstrumentationRegistry.getContext());

        // Creating a WallpaperColors object that contains *only* blacklisted colors.
        final float[] hsl = tonal.getBlacklistedColors().get(0).getCenter();
        final int blacklistedColor = ColorUtils.HSLToColor(hsl);
        WallpaperColors colors = new WallpaperColors(Color.valueOf(blacklistedColor),
                null, null);

        // Blacklist should be ignored when HINT_FROM_BITMAP isn't present.
        final GradientColors normal = new GradientColors();
        tonal.extractInto(colors, normal, new GradientColors(),
                new GradientColors());
        assertTrue("Blacklist should never be used on WallpaperColors generated using "
                + "default constructor.", normal.getMainColor() == blacklistedColor);
    }
}
}