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

Commit 1d6300bf authored by Mario Bertschler's avatar Mario Bertschler
Browse files

Color extraction implementation for gradient colors

used by all apps background.

Change-Id: Id7a652815cb3ef61ff4b0a442d8350337014b56d
parent 5c60e714
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ public class ColorExtractionService extends IntentService {
            if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
                extractedColors.updateWallpaperThemePalette(null);
                if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
                    extractedColors.updateAllAppsGradientPalette(null);
                    extractedColors.updateAllAppsGradientPalette(this);
                }
            }
        } else {
@@ -79,10 +79,9 @@ public class ColorExtractionService extends IntentService {
            }

            if (FeatureFlags.QSB_IN_HOTSEAT || FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
                Palette wallpaperPalette = getWallpaperPalette();
                extractedColors.updateWallpaperThemePalette(wallpaperPalette);
                extractedColors.updateWallpaperThemePalette(getWallpaperPalette());
                if (FeatureFlags.LAUNCHER3_GRADIENT_ALL_APPS) {
                    extractedColors.updateAllAppsGradientPalette(wallpaperPalette);
                    extractedColors.updateAllAppsGradientPalette(this);
                }
            }
        }
+14 −9
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.launcher3.dynamicui;

import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Color;
import android.support.annotation.Nullable;
@@ -25,6 +26,7 @@ import android.util.Log;

import com.android.launcher3.Utilities;
import com.android.launcher3.config.FeatureFlags;
import com.android.launcher3.dynamicui.colorextraction.ColorExtractor;

import java.util.Arrays;

@@ -161,14 +163,17 @@ public class ExtractedColors {
                ? defaultColor : wallpaperPalette.getVibrantColor(defaultColor));
    }

    public void updateAllAppsGradientPalette(@Nullable Palette wallpaperPalette) {
        // TODO b/37089857 will be modified to take the system extracted colors into account
        int idx;
        idx = ALLAPPS_GRADIENT_MAIN_INDEX;
        setColorAtIndex(idx, wallpaperPalette == null
                ? DEFAULT_VALUES[idx] : wallpaperPalette.getDarkVibrantColor(DEFAULT_VALUES[idx]));
        idx = ALLAPPS_GRADIENT_SECONDARY_INDEX;
        setColorAtIndex(idx, wallpaperPalette == null
                ? DEFAULT_VALUES[idx] : wallpaperPalette.getVibrantColor(DEFAULT_VALUES[idx]));
    public void updateAllAppsGradientPalette(Context context) {
        // TODO use isAtLeastO when available
        try {
            WallpaperManager.class.getDeclaredMethod("getWallpaperColors", int.class);
            ColorExtractor extractor = new ColorExtractor(context);
            ColorExtractor.GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM);
            setColorAtIndex(ALLAPPS_GRADIENT_MAIN_INDEX, colors.getMainColor());
            setColorAtIndex(ALLAPPS_GRADIENT_SECONDARY_INDEX, colors.getSecondaryColor());
        } catch (NoSuchMethodException e) {
            setColorAtIndex(ALLAPPS_GRADIENT_MAIN_INDEX, Color.WHITE);
            setColorAtIndex(ALLAPPS_GRADIENT_SECONDARY_INDEX, Color.WHITE);
        }
    }
}
+136 −0
Original line number Diff line number Diff line
package com.android.launcher3.dynamicui.colorextraction;

import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Color;
import android.os.Parcelable;
import android.util.Log;

import com.android.launcher3.dynamicui.colorextraction.types.ExtractionType;
import com.android.launcher3.dynamicui.colorextraction.types.Tonal;

import java.lang.reflect.Method;


/**
 * Class to process wallpaper colors and generate a tonal palette based on them.
 *
 * TODO remove this class if available by platform
 */
public class ColorExtractor {
    private static final String TAG = "ColorExtractor";
    private static final int FALLBACK_COLOR = Color.WHITE;

    private int mMainFallbackColor = FALLBACK_COLOR;
    private int mSecondaryFallbackColor = FALLBACK_COLOR;
    private final GradientColors mSystemColors;
    private final GradientColors mLockColors;
    private final Context mContext;
    private final ExtractionType mExtractionType;

    public ColorExtractor(Context context) {
        mContext = context;
        mSystemColors = new GradientColors();
        mLockColors = new GradientColors();
        mExtractionType = new Tonal();
        WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);

        if (wallpaperManager == null) {
            Log.w(TAG, "Can't listen to color changes!");
        } else {
            Parcelable wallpaperColorsObj;
            try {
                Method method = WallpaperManager.class
                        .getDeclaredMethod("getWallpaperColors", int.class);

                wallpaperColorsObj = (Parcelable) method.invoke(wallpaperManager,
                        WallpaperManager.FLAG_SYSTEM);
                extractInto(new WallpaperColorsCompat(wallpaperColorsObj), mSystemColors);
                wallpaperColorsObj = (Parcelable) method.invoke(wallpaperManager,
                        WallpaperManager.FLAG_LOCK);
                extractInto(new WallpaperColorsCompat(wallpaperColorsObj), mLockColors);
            } catch (Exception e) {
                Log.e(TAG, "reflection failed", e);
            }
        }
    }

    public GradientColors getColors(int which) {
        if (which == WallpaperManager.FLAG_LOCK) {
            return mLockColors;
        } else if (which == WallpaperManager.FLAG_SYSTEM) {
            return mSystemColors;
        } else {
            throw new IllegalArgumentException("which should be either FLAG_SYSTEM or FLAG_LOCK");
        }
    }

    private void extractInto(WallpaperColorsCompat inWallpaperColors, GradientColors outGradientColors) {
        applyFallback(outGradientColors);
        if (inWallpaperColors == null) {
            return;
        }
        mExtractionType.extractInto(inWallpaperColors, outGradientColors);
    }

    private void applyFallback(GradientColors outGradientColors) {
        outGradientColors.setMainColor(mMainFallbackColor);
        outGradientColors.setSecondaryColor(mSecondaryFallbackColor);
    }

    public static class GradientColors {
        private int mMainColor = FALLBACK_COLOR;
        private int mSecondaryColor = FALLBACK_COLOR;
        private boolean mSupportsDarkText;

        public void setMainColor(int mainColor) {
            mMainColor = mainColor;
        }

        public void setSecondaryColor(int secondaryColor) {
            mSecondaryColor = secondaryColor;
        }

        public void setSupportsDarkText(boolean supportsDarkText) {
            mSupportsDarkText = supportsDarkText;
        }

        public void set(GradientColors other) {
            mMainColor = other.mMainColor;
            mSecondaryColor = other.mSecondaryColor;
            mSupportsDarkText = other.mSupportsDarkText;
        }

        public int getMainColor() {
            return mMainColor;
        }

        public int getSecondaryColor() {
            return mSecondaryColor;
        }

        public boolean supportsDarkText() {
            return mSupportsDarkText;
        }

        @Override
        public boolean equals(Object o) {
            if (o == null || o.getClass() != getClass()) {
                return false;
            }
            GradientColors other = (GradientColors) o;
            return other.mMainColor == mMainColor &&
                    other.mSecondaryColor == mSecondaryColor &&
                    other.mSupportsDarkText == mSupportsDarkText;
        }

        @Override
        public int hashCode() {
            int code = mMainColor;
            code = 31 * code + mSecondaryColor;
            code = 31 * code + (mSupportsDarkText ? 0 : 1);
            return code;
        }
    }
}
+69 −0
Original line number Diff line number Diff line
package com.android.launcher3.dynamicui.colorextraction;

import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Pair;

import java.util.List;

/**
 * A wrapper around platform implementation of WallpaperColors until the
 * updated SDK is available.
 *
 * TODO remove this class if available by platform
 */
public class WallpaperColorsCompat implements Parcelable {

    private final Parcelable mObject;

    public WallpaperColorsCompat(Parcelable object) {
        mObject = object;
    }

    private Object invokeMethod(String methodName) {
        try {
            return mObject.getClass().getDeclaredMethod(methodName).invoke(mObject);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeParcelable(mObject, i);
    }

    public static final Parcelable.Creator<WallpaperColorsCompat> CREATOR =
            new Parcelable.Creator<WallpaperColorsCompat>() {
                public WallpaperColorsCompat createFromParcel(Parcel source) {
                    Parcelable object = source.readParcelable(null);
                    return new WallpaperColorsCompat(object);
                }

                public WallpaperColorsCompat[] newArray(int size) {
                    return new WallpaperColorsCompat[size];
                }
            };

    public List<Pair<Color, Integer>> getColors() {
        try {
            return (List<Pair<Color, Integer>>) invokeMethod("getColors");
        } catch (Exception e) {
            return null;
        }
    }

    public boolean supportsDarkText() {
        try {
            return (Boolean) invokeMethod("supportsDarkText");
        } catch (Exception e) {
            return false;
        }
    }
}
+23 −0
Original line number Diff line number Diff line
package com.android.launcher3.dynamicui.colorextraction.types;

import com.android.launcher3.dynamicui.colorextraction.ColorExtractor;
import com.android.launcher3.dynamicui.colorextraction.WallpaperColorsCompat;


/**
 * Interface to allow various color extraction implementations.
 *
 * TODO remove this class if available by platform
 */
public interface ExtractionType {

    /**
     * Executes color extraction by reading WallpaperColors and setting
     * main and secondary colors on GradientColors.
     *
     * @param inWallpaperColors where to read from
     * @param outGradientColors object that should receive the colors
     */
    void extractInto(WallpaperColorsCompat inWallpaperColors,
                     ColorExtractor.GradientColors outGradientColors);
}
Loading