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

Commit 8b94ef69 authored by Lucas Dupin's avatar Lucas Dupin Committed by Android (Google) Code Review
Browse files

Merge "Add theme style flag to WallpaperColors" into oc-dr1-dev

parents 00d83ea5 4bd24f36
Loading
Loading
Loading
Loading
+29 −14
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.util.Size;

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

@@ -50,6 +51,14 @@ public final class WallpaperColors implements Parcelable {
     */
    public static final int HINT_SUPPORTS_DARK_TEXT = 0x1;

    /**
     * Specifies that dark theme is preferred over the current wallpaper for best presentation.
     * <p>
     * eg. A launcher may set its drawer color to black if this flag is specified.
     * @hide
     */
    public static final int HINT_SUPPORTS_DARK_THEME = 0x2;

    // Maximum size that a bitmap can have to keep our calculations sane
    private static final int MAX_BITMAP_SIZE = 112;

@@ -61,8 +70,10 @@ public final class WallpaperColors implements Parcelable {
    // present in at least MIN_COLOR_OCCURRENCE of the image
    private static final float MIN_COLOR_OCCURRENCE = 0.05f;

    // Decides when dark theme is optimal for this wallpaper
    private static final float DARK_THEME_MEAN_LUMINANCE = 0.25f;
    // Minimum mean luminosity that an image needs to have to support dark text
    private static final float BRIGHT_IMAGE_MEAN_LUMINANCE = 0.9f;
    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;
@@ -169,10 +180,7 @@ public final class WallpaperColors implements Parcelable {
            }
        }

        int hints = 0;
        if (calculateDarkTextSupport(bitmap)) {
            hints |= HINT_SUPPORTS_DARK_TEXT;
        }
        int hints = calculateHints(bitmap);
        return new WallpaperColors(primary, secondary, tertiary, hints);
    }

@@ -335,9 +343,9 @@ public final class WallpaperColors implements Parcelable {
     * @param source What to read.
     * @return Whether image supports dark text or not.
     */
    private static boolean calculateDarkTextSupport(Bitmap source) {
    private static int calculateHints(Bitmap source) {
        if (source == null) {
            return false;
            return 0;
        }

        int[] pixels = new int[source.getWidth() * source.getHeight()];
@@ -349,22 +357,29 @@ public final class WallpaperColors implements Parcelable {

        // This bitmap was already resized to fit the maximum allowed area.
        // Let's just loop through the pixels, no sweat!
        float[] tmpHsl = new float[3];
        for (int i = 0; i < pixels.length; i++) {
            final float luminance = Color.luminance(pixels[i]);
            ColorUtils.colorToHSL(pixels[i], tmpHsl);
            final float luminance = tmpHsl[2];
            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) {
                darkPixels++;
                if (darkPixels > maxDarkPixels) {
                    return false;
            }
            totalLuminance += luminance;
        }

            totalLuminance += luminance;
        int hints = 0;
        double meanLuminance = totalLuminance / pixels.length;
        if (meanLuminance > BRIGHT_IMAGE_MEAN_LUMINANCE && darkPixels < maxDarkPixels) {
            hints |= HINT_SUPPORTS_DARK_TEXT;
        }
        return totalLuminance / pixels.length > BRIGHT_IMAGE_MEAN_LUMINANCE;
        if (meanLuminance < DARK_THEME_MEAN_LUMINANCE) {
            hints |= HINT_SUPPORTS_DARK_THEME;
        }

        return hints;
    }

    private static Size calculateOptimalSize(int width, int height) {
+4 −9
Original line number Diff line number Diff line
@@ -4576,15 +4576,10 @@ public class StatusBar extends SystemUI implements DemoMode,
        final boolean useDarkText = mColorExtractor.getColors(which, true /* ignoreVisibility */)
                .supportsDarkText();
        // And wallpaper defines if QS should be light or dark.
        boolean useDarkTheme = false;
        final WallpaperColors systemColors =
                mColorExtractor.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
        if (systemColors != null) {
            int mainColor = systemColors.getPrimaryColor().toArgb();
            float[] hsl = new float[3];
            ColorUtils.colorToHSL(mainColor, hsl);
            useDarkTheme = hsl[2] < 0.2f;
        }
        WallpaperColors systemColors = mColorExtractor
                .getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
        final boolean useDarkTheme = systemColors != null
                && (systemColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_THEME) != 0;

        // Enable/disable dark UI.
        if (isUsingDarkTheme() != useDarkTheme) {
+80 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 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 android.app;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class WallpaperColorsTest {

    @Test
    public void supportsDarkTextOverrideTest() {
        final Color color = Color.valueOf(Color.WHITE);
        // Default should not support dark text!
        WallpaperColors colors = new WallpaperColors(color, null, null, 0);
        Assert.assertTrue("Default behavior is not to support dark text",
                (colors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) == 0);

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

    /**
     * Sanity check to guarantee that white supports dark text and black doesn't
     */
    @Test
    public void colorHintsTest() {
        Bitmap image = Bitmap.createBitmap(30, 30, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(image);

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

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

        Paint paint = new Paint();
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.BLACK);
        canvas.drawColor(Color.WHITE);
        canvas.drawRect(0, 0, 8, 8, paint);
        supportsDarkText = (WallpaperColors.fromBitmap(image)
                .getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
        Assert.assertFalse("Light surface shouldn't support dark text "
                + "when it contains dark pixels", supportsDarkText);
    }
}