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

Commit 636e081a authored by Mario Bertschler's avatar Mario Bertschler
Browse files

Applying API changes on WallpaperColors.

Bug: 62719001
Change-Id: Iabe2e446bd05c41ec910ed2ad534d623285e7e63
parent b3720063
Loading
Loading
Loading
Loading
+25 −14
Original line number Diff line number Diff line
@@ -15,29 +15,40 @@
 */
package com.android.launcher3.compat;

import android.util.SparseIntArray;

/**
 * A compatibility layer around platform implementation of WallpaperColors
 */
public class WallpaperColorsCompat {

    private final SparseIntArray mColors;
    private final boolean mSupportsDarkText;
    public static final int HINT_SUPPORTS_DARK_TEXT = 0x1;

    private final int mPrimaryColor;
    private final int mSecondaryColor;
    private final int mTertiaryColor;
    private final int mColorHints;

    public WallpaperColorsCompat(SparseIntArray colors, boolean supportsDarkText) {
        mColors = colors;
        mSupportsDarkText = supportsDarkText;
    public WallpaperColorsCompat(int primaryColor, int secondaryColor, int tertiaryColor,
            int colorHints) {
        mPrimaryColor = primaryColor;
        mSecondaryColor = secondaryColor;
        mTertiaryColor = tertiaryColor;
        mColorHints = colorHints;
    }

    /**
     * A map of color code to their occurrences. The bigger the int, the more relevant the color.
     */
    public SparseIntArray getColors() {
        return mColors;
    public int getPrimaryColor() {
        return mPrimaryColor;
    }

    public boolean supportsDarkText() {
        return mSupportsDarkText;
    public int getSecondaryColor() {
        return mSecondaryColor;
    }

    public int getTertiaryColor() {
        return mTertiaryColor;
    }

    public int getColorHints() {
        return mColorHints;
    }

}
+26 −14
Original line number Diff line number Diff line
@@ -15,10 +15,6 @@
 */
package com.android.launcher3.compat;

import static android.app.WallpaperManager.FLAG_SYSTEM;

import static com.android.launcher3.Utilities.getDevicePrefs;

import android.app.WallpaperInfo;
import android.app.WallpaperManager;
import android.app.job.JobInfo;
@@ -45,12 +41,17 @@ import android.support.annotation.Nullable;
import android.support.v7.graphics.Palette;
import android.util.Log;
import android.util.Pair;
import android.util.SparseIntArray;

import com.android.launcher3.Utilities;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import static android.app.WallpaperManager.FLAG_SYSTEM;
import static com.android.launcher3.Utilities.getDevicePrefs;

public class WallpaperManagerCompatVL extends WallpaperManagerCompat {

@@ -154,11 +155,12 @@ public class WallpaperManagerCompatVL extends WallpaperManagerCompat {
            return Pair.create(wallpaperId, null);
        }

        SparseIntArray colorsToOccurrences = new SparseIntArray((parts.length - 2) / 2);
        for (int i = 2; i < parts.length; i += 2) {
            colorsToOccurrences.put(Integer.parseInt(parts[i]), Integer.parseInt(parts[i + 1]));
        }
        return Pair.create(wallpaperId, new WallpaperColorsCompat(colorsToOccurrences, false));
        int primary = parts.length > 2 ? Integer.parseInt(parts[2]) : 0;
        int secondary = parts.length > 3 ? Integer.parseInt(parts[3]) : 0;
        int tertiary = parts.length > 4 ? Integer.parseInt(parts[4]) : 0;

        return Pair.create(wallpaperId, new WallpaperColorsCompat(primary, secondary, tertiary,
                0 /* hints */));
    }

    /**
@@ -262,12 +264,22 @@ public class WallpaperManagerCompatVL extends WallpaperManagerCompat {
                bitmap.recycle();

                StringBuilder builder = new StringBuilder(value);
                List<Pair<Integer,Integer>> colorsToOccurrences = new ArrayList<>();
                for (Palette.Swatch swatch : palette.getSwatches()) {
                    builder.append(',')
                            .append(swatch.getRgb())
                            .append(',')
                            .append(swatch.getPopulation());
                    colorsToOccurrences.add(new Pair(swatch.getRgb(), swatch.getPopulation()));
                }

                Collections.sort(colorsToOccurrences, new Comparator<Pair<Integer, Integer>>() {
                    @Override
                    public int compare(Pair<Integer, Integer> a, Pair<Integer, Integer> b) {
                        return b.second - a.second;
                    }
                });

                for (int i=0; i < Math.min(3, colorsToOccurrences.size()); i++) {
                    builder.append(',').append(colorsToOccurrences.get(i).first);
                }

                value = builder.toString();
            }

+16 −14
Original line number Diff line number Diff line
@@ -22,13 +22,10 @@ import android.graphics.Color;
import android.os.Build;
import android.support.annotation.Nullable;
import android.util.Log;
import android.util.Pair;
import android.util.SparseIntArray;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.List;

@TargetApi(Build.VERSION_CODES.O)
public class WallpaperManagerCompatVOMR1 extends WallpaperManagerCompat {
@@ -41,8 +38,10 @@ public class WallpaperManagerCompatVOMR1 extends WallpaperManagerCompat {
    private final Method mAddOCLMethod;

    private final Method mWCGetMethod;
    private final Method mWCGetColorsMethod;
    private final Method mWCSupportsDarkTextMethod;
    private final Method mWCGetPrimaryColorMethod;
    private final Method mWCGetSecondaryColorMethod;
    private final Method mWCGetTertiaryColorMethod;
    private final Method mWCColorHintsMethod;

    WallpaperManagerCompatVOMR1(Context context) throws Exception {
        mWm = context.getSystemService(WallpaperManager.class);
@@ -53,8 +52,10 @@ public class WallpaperManagerCompatVOMR1 extends WallpaperManagerCompat {

        mWCGetMethod = WallpaperManager.class.getDeclaredMethod("getWallpaperColors", int.class);
        Class wallpaperColorsClass = mWCGetMethod.getReturnType();
        mWCGetColorsMethod = wallpaperColorsClass.getDeclaredMethod("getColors");
        mWCSupportsDarkTextMethod = wallpaperColorsClass.getDeclaredMethod("supportsDarkText");
        mWCGetPrimaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getPrimaryColor");
        mWCGetSecondaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getSecondaryColor");
        mWCGetTertiaryColorMethod = wallpaperColorsClass.getDeclaredMethod("getTertiaryColor");
        mWCColorHintsMethod = wallpaperColorsClass.getDeclaredMethod("getColorHints");
    }

    @Nullable
@@ -98,12 +99,13 @@ public class WallpaperManagerCompatVOMR1 extends WallpaperManagerCompat {
        if (colors == null) {
            return null;
        }
        List<Pair<Color, Integer>> list = (List) mWCGetColorsMethod.invoke(colors);
        boolean supportsDarkText = (Boolean) mWCSupportsDarkTextMethod.invoke(colors);
        SparseIntArray colorMap = new SparseIntArray(list.size());
        for (Pair<Color, Integer> color : list) {
            colorMap.put(color.first.toArgb(), color.second);
        }
        return new WallpaperColorsCompat(colorMap, supportsDarkText);
        Color primary = (Color) mWCGetPrimaryColorMethod.invoke(colors);
        Color secondary = (Color) mWCGetSecondaryColorMethod.invoke(colors);
        Color tertiary = (Color) mWCGetTertiaryColorMethod.invoke(colors);
        int primaryVal = primary != null ? primary.toArgb() : 0;
        int secondaryVal = secondary != null ? secondary.toArgb() : 0;
        int tertiaryVal = tertiary != null ? tertiary.toArgb() : 0;
        int colorHints = (Integer) mWCColorHintsMethod.invoke(colors);
        return new WallpaperColorsCompat(primaryVal, secondaryVal, tertiaryVal, colorHints);
    }
}
+33 −51
Original line number Diff line number Diff line
@@ -24,15 +24,12 @@ import android.support.v4.graphics.ColorUtils;
import android.util.Log;
import android.util.Pair;
import android.util.Range;
import android.util.SparseIntArray;

import com.android.launcher3.R;
import com.android.launcher3.Utilities;
import com.android.launcher3.compat.WallpaperColorsCompat;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;

/**
@@ -52,20 +49,18 @@ public class ColorExtractionAlgorithm {
    private static final float FIT_WEIGHT_S = 1.0f;
    private static final float FIT_WEIGHT_L = 10.0f;

    // When extracting the main color, only consider colors
    // present in at least MIN_COLOR_OCCURRENCE of the image
    private static final float MIN_COLOR_OCCURRENCE = 0.1f;

    // Temporary variable to avoid allocations
    private final float[] mTmpHSL = new float[3];
    private float[] mTmpHSL = new float[3];

    public @Nullable Pair<Integer, Integer> extractInto(WallpaperColorsCompat wallpaperColors) {
        if (wallpaperColors == null) {
    public @Nullable Pair<Integer, Integer> extractInto(WallpaperColorsCompat inWallpaperColors) {
        if (inWallpaperColors == null) {
            return null;
        }

        SparseIntArray colorsArray = wallpaperColors.getColors();
        if (colorsArray.size() == 0) {
        final List<Integer> mainColors = getMainColors(inWallpaperColors);
        final int mainColorsSize = mainColors.size();

        if (mainColorsSize == 0) {
            return null;
        }
        // Tonal is not really a sort, it takes a color from the extracted
@@ -73,35 +68,17 @@ public class ColorExtractionAlgorithm {
        // palettes. The best fit is tweaked to be closer to the source color
        // and replaces the original palette

        List<Pair<Integer, Integer>> colors = new ArrayList<>(colorsArray.size());
        for (int i = colorsArray.size() - 1; i >= 0; i--) {
            colors.add(Pair.create(colorsArray.keyAt(i), colorsArray.valueAt(i)));
        }

        // First find the most representative color in the image
        populationSort(colors);
        // Calculate total
        int total = 0;
        for (Pair<Integer, Integer> weightedColor : colors) {
            total += weightedColor.second;
        }

        // Get bright colors that occur often enough in this image
        Pair<Integer, Integer> bestColor = null;
        float[] hsl = new float[3];
        for (Pair<Integer, Integer> weightedColor : colors) {
            float colorOccurrence = weightedColor.second / (float) total;
            if (colorOccurrence < MIN_COLOR_OCCURRENCE) {
                break;
            }

            int colorValue = weightedColor.first;
        // Get the most preeminent, non-blacklisted color.
        Integer bestColor = 0;
        final float[] hsl = new float[3];
        for (int i = 0; i < mainColorsSize; i++) {
            final int colorValue = mainColors.get(i);
            ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue),
                    Color.blue(colorValue), hsl);

            // Stop when we find a color that meets our criteria
            if (!isBlacklisted(hsl)) {
                bestColor = weightedColor;
                bestColor = colorValue;
                break;
            }
        }
@@ -111,7 +88,7 @@ public class ColorExtractionAlgorithm {
            return null;
        }

        int colorValue = bestColor.first;
        int colorValue = bestColor;
        ColorUtils.RGBToHSL(Color.red(colorValue), Color.green(colorValue), Color.blue(colorValue),
                hsl);

@@ -121,7 +98,6 @@ public class ColorExtractionAlgorithm {

        // Find the palette that contains the closest color
        TonalPalette palette = findTonalPalette(hsl[0]);

        if (palette == null) {
            Log.w(TAG, "Could not find a tonal palette!");
            return null;
@@ -140,8 +116,7 @@ public class ColorExtractionAlgorithm {
        float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f);
        float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f);

        final int textInversionIndex = h.length - 3;

        // Normal colors:
        // best fit + a 2 colors offset
        int primaryIndex = fitIndex;
        int secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
@@ -172,15 +147,6 @@ public class ColorExtractionAlgorithm {
        return false;
    }

    private static void populationSort(@NonNull List<Pair<Integer, Integer>> wallpaperColors) {
        Collections.sort(wallpaperColors, new Comparator<Pair<Integer, Integer>>() {
            @Override
            public int compare(Pair<Integer, Integer> a, Pair<Integer, Integer> b) {
                return b.second - a.second;
            }
        });
    }

    /**
     * Offsets all colors by a delta, clamping values that go beyond what's
     * supported on the color space.
@@ -234,7 +200,9 @@ public class ColorExtractionAlgorithm {
        TonalPalette best = null;
        float error = Float.POSITIVE_INFINITY;

        for (TonalPalette candidate : TONAL_PALETTES) {
        for (int i = 0; i < TONAL_PALETTES.length; i++) {
            final TonalPalette candidate = TONAL_PALETTES[i];

            if (h >= candidate.minHue && h <= candidate.maxHue) {
                best = candidate;
                break;
@@ -757,4 +725,18 @@ public class ColorExtractionAlgorithm {
        }
    }

    private static List<Integer> getMainColors(WallpaperColorsCompat wallpaperColors) {
        LinkedList<Integer> colors = new LinkedList<>();
        if (wallpaperColors.getPrimaryColor() != 0) {
            colors.add(wallpaperColors.getPrimaryColor());
        }
        if (wallpaperColors.getSecondaryColor() != 0) {
            colors.add(wallpaperColors.getSecondaryColor());
        }
        if (wallpaperColors.getTertiaryColor() != 0) {
            colors.add(wallpaperColors.getTertiaryColor());
        }
        return colors;
    }

}
+3 −1
Original line number Diff line number Diff line
@@ -78,7 +78,9 @@ public class WallpaperColorInfo implements WallpaperManagerCompat.OnColorsChange
            mMainColor = FALLBACK_COLOR;
            mSecondaryColor = FALLBACK_COLOR;
        }
        mSupportsDarkText = wallpaperColors != null ? wallpaperColors.supportsDarkText() : false;
        mSupportsDarkText = wallpaperColors != null
                ? (wallpaperColors.getColorHints()
                    & WallpaperColorsCompat.HINT_SUPPORTS_DARK_TEXT) > 0 : false;
        float[] hsl = new float[3];
        ColorUtils.colorToHSL(mMainColor, hsl);
        mIsDark = hsl[2] < 0.2f;