Merge "Apply colors extracted from wallpaper to clock faces."
This commit is contained in:
@@ -22,7 +22,6 @@ import android.app.WallpaperColors;
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.Context;
|
||||
import android.os.Trace;
|
||||
import android.os.UserHandle;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
@@ -32,7 +31,6 @@ import com.android.internal.colorextraction.types.Tonal;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* Class to process wallpaper colors and generate a tonal palette based on them.
|
||||
@@ -222,6 +220,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
|
||||
public static class GradientColors {
|
||||
private int mMainColor;
|
||||
private int mSecondaryColor;
|
||||
private int[] mColorPalette;
|
||||
private boolean mSupportsDarkText;
|
||||
|
||||
public void setMainColor(int mainColor) {
|
||||
@@ -232,6 +231,10 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
|
||||
mSecondaryColor = secondaryColor;
|
||||
}
|
||||
|
||||
public void setColorPalette(int[] colorPalette) {
|
||||
mColorPalette = colorPalette;
|
||||
}
|
||||
|
||||
public void setSupportsDarkText(boolean supportsDarkText) {
|
||||
mSupportsDarkText = supportsDarkText;
|
||||
}
|
||||
@@ -239,6 +242,7 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
|
||||
public void set(GradientColors other) {
|
||||
mMainColor = other.mMainColor;
|
||||
mSecondaryColor = other.mSecondaryColor;
|
||||
mColorPalette = other.mColorPalette;
|
||||
mSupportsDarkText = other.mSupportsDarkText;
|
||||
}
|
||||
|
||||
@@ -250,6 +254,10 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
|
||||
return mSecondaryColor;
|
||||
}
|
||||
|
||||
public int[] getColorPalette() {
|
||||
return mColorPalette;
|
||||
}
|
||||
|
||||
public boolean supportsDarkText() {
|
||||
return mSupportsDarkText;
|
||||
}
|
||||
@@ -283,4 +291,4 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
|
||||
public interface OnColorsChangedListener {
|
||||
void onColorsChanged(ColorExtractor colorExtractor, int which);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,6 +173,7 @@ public class Tonal implements ExtractionType {
|
||||
Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
|
||||
float[] s = fit(palette.s, hsl[1], fitIndex, 0.0f, 1.0f);
|
||||
float[] l = fit(palette.l, hsl[2], fitIndex, 0.0f, 1.0f);
|
||||
int[] colorPalette = getColorPalette(h, s, l);
|
||||
|
||||
if (DEBUG) {
|
||||
StringBuilder builder = new StringBuilder("Tonal Palette - index: " + fitIndex +
|
||||
@@ -209,6 +210,7 @@ public class Tonal implements ExtractionType {
|
||||
// Normal colors:
|
||||
outColorsNormal.setMainColor(mainColor);
|
||||
outColorsNormal.setSecondaryColor(mainColor);
|
||||
outColorsNormal.setColorPalette(colorPalette);
|
||||
|
||||
// Dark colors:
|
||||
// Stops at 4th color, only lighter if dark text is supported
|
||||
@@ -222,6 +224,7 @@ public class Tonal implements ExtractionType {
|
||||
mainColor = getColorInt(primaryIndex, h, s, l);
|
||||
outColorsDark.setMainColor(mainColor);
|
||||
outColorsDark.setSecondaryColor(mainColor);
|
||||
outColorsDark.setColorPalette(colorPalette);
|
||||
|
||||
// Extra Dark:
|
||||
// Stay close to dark colors until dark text is supported
|
||||
@@ -235,6 +238,7 @@ public class Tonal implements ExtractionType {
|
||||
mainColor = getColorInt(primaryIndex, h, s, l);
|
||||
outColorsExtraDark.setMainColor(mainColor);
|
||||
outColorsExtraDark.setSecondaryColor(mainColor);
|
||||
outColorsExtraDark.setColorPalette(colorPalette);
|
||||
|
||||
outColorsNormal.setSupportsDarkText(supportsDarkText);
|
||||
outColorsDark.setSupportsDarkText(supportsDarkText);
|
||||
@@ -262,16 +266,19 @@ public class Tonal implements ExtractionType {
|
||||
* @param inWallpaperColors Colors to read.
|
||||
* @param outGradientColors Destination.
|
||||
*/
|
||||
public static void applyFallback(@Nullable WallpaperColors inWallpaperColors,
|
||||
public void applyFallback(@Nullable WallpaperColors inWallpaperColors,
|
||||
@NonNull GradientColors outGradientColors) {
|
||||
boolean light = inWallpaperColors != null
|
||||
&& (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT)
|
||||
!= 0;
|
||||
final int color = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK;
|
||||
final float[] hsl = new float[3];
|
||||
ColorUtils.colorToHSL(color, hsl);
|
||||
|
||||
outGradientColors.setMainColor(color);
|
||||
outGradientColors.setSecondaryColor(color);
|
||||
outGradientColors.setSupportsDarkText(light);
|
||||
outGradientColors.setColorPalette(getColorPalette(findTonalPalette(hsl[0], hsl[1])));
|
||||
}
|
||||
|
||||
private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) {
|
||||
@@ -281,6 +288,19 @@ public class Tonal implements ExtractionType {
|
||||
return ColorUtils.HSLToColor(mTmpHSL);
|
||||
}
|
||||
|
||||
private int[] getColorPalette(float[] h, float[] s, float[] l) {
|
||||
int[] colorPalette = new int[h.length];
|
||||
for (int i = 0; i < colorPalette.length; i++) {
|
||||
colorPalette[i] = getColorInt(i, h, s, l);
|
||||
}
|
||||
return colorPalette;
|
||||
}
|
||||
|
||||
private int[] getColorPalette(TonalPalette palette) {
|
||||
return getColorPalette(palette.h, palette.s, palette.l);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a given color exists in the blacklist
|
||||
* @param hsl float array with 3 components (H 0..360, S 0..1 and L 0..1)
|
||||
@@ -598,4 +618,4 @@ public class Tonal implements ExtractionType {
|
||||
return numbers;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,10 +54,17 @@ public interface ClockPlugin extends Plugin {
|
||||
*/
|
||||
void setTextColor(int color);
|
||||
|
||||
/**
|
||||
* Sets the color palette for the clock face.
|
||||
* @param supportsDarkText Whether dark text can be displayed.
|
||||
* @param colors Colors that should be used on the clock face, ordered from darker to lighter.
|
||||
*/
|
||||
default void setColorPalette(boolean supportsDarkText, int[] colors) {}
|
||||
|
||||
/**
|
||||
* Notifies that time tick alarm from doze service fired.
|
||||
*/
|
||||
default void dozeTimeTick() { }
|
||||
default void dozeTimeTick() {}
|
||||
|
||||
/**
|
||||
* Set the amount (ratio) that the device has transitioned to doze.
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.android.keyguard;
|
||||
|
||||
import android.app.WallpaperManager;
|
||||
import android.content.Context;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Style;
|
||||
@@ -12,8 +13,10 @@ import android.widget.TextClock;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.internal.colorextraction.ColorExtractor;
|
||||
import com.android.keyguard.clock.ClockManager;
|
||||
import com.android.systemui.Dependency;
|
||||
import com.android.systemui.colorextraction.SysuiColorExtractor;
|
||||
import com.android.systemui.plugins.ClockPlugin;
|
||||
import com.android.systemui.plugins.statusbar.StatusBarStateController;
|
||||
import com.android.systemui.statusbar.StatusBarState;
|
||||
@@ -50,6 +53,8 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
* Maintain state so that a newly connected plugin can be initialized.
|
||||
*/
|
||||
private float mDarkAmount;
|
||||
private boolean mSupportsDarkText;
|
||||
private int[] mColorPalette;
|
||||
|
||||
private final StatusBarStateController.StateListener mStateListener =
|
||||
new StatusBarStateController.StateListener() {
|
||||
@@ -72,6 +77,21 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
|
||||
private ClockManager.ClockChangedListener mClockChangedListener = this::setClockPlugin;
|
||||
|
||||
/**
|
||||
* Listener for changes to the color palette.
|
||||
*
|
||||
* The color palette changes when the wallpaper is changed.
|
||||
*/
|
||||
private SysuiColorExtractor.OnColorsChangedListener mColorsListener = (extractor, which) -> {
|
||||
if ((which & WallpaperManager.FLAG_LOCK) != 0) {
|
||||
if (extractor instanceof SysuiColorExtractor) {
|
||||
updateColors((SysuiColorExtractor) extractor);
|
||||
} else {
|
||||
updateColors(Dependency.get(SysuiColorExtractor.class));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public KeyguardClockSwitch(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -100,6 +120,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
super.onAttachedToWindow();
|
||||
Dependency.get(ClockManager.class).addOnClockChangedListener(mClockChangedListener);
|
||||
Dependency.get(StatusBarStateController.class).addCallback(mStateListener);
|
||||
SysuiColorExtractor colorExtractor = Dependency.get(SysuiColorExtractor.class);
|
||||
colorExtractor.addOnColorsChangedListener(mColorsListener);
|
||||
updateColors(colorExtractor);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -107,6 +130,8 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
super.onDetachedFromWindow();
|
||||
Dependency.get(ClockManager.class).removeOnClockChangedListener(mClockChangedListener);
|
||||
Dependency.get(StatusBarStateController.class).removeCallback(mStateListener);
|
||||
Dependency.get(SysuiColorExtractor.class)
|
||||
.removeOnColorsChangedListener(mColorsListener);
|
||||
}
|
||||
|
||||
private void setClockPlugin(ClockPlugin plugin) {
|
||||
@@ -149,6 +174,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
mClockPlugin.setStyle(getPaint().getStyle());
|
||||
mClockPlugin.setTextColor(getCurrentTextColor());
|
||||
mClockPlugin.setDarkAmount(mDarkAmount);
|
||||
if (mColorPalette != null) {
|
||||
mClockPlugin.setColorPalette(mSupportsDarkText, mColorPalette);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -246,6 +274,16 @@ public class KeyguardClockSwitch extends RelativeLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private void updateColors(SysuiColorExtractor colorExtractor) {
|
||||
ColorExtractor.GradientColors colors = colorExtractor.getColors(WallpaperManager.FLAG_LOCK,
|
||||
true);
|
||||
mSupportsDarkText = colors.supportsDarkText();
|
||||
mColorPalette = colors.getColorPalette();
|
||||
if (mClockPlugin != null) {
|
||||
mClockPlugin.setColorPalette(mSupportsDarkText, mColorPalette);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting (otherwise = VisibleForTesting.NONE)
|
||||
ClockManager.ClockChangedListener getClockChangedListener() {
|
||||
return mClockChangedListener;
|
||||
|
||||
@@ -89,7 +89,17 @@ public class BubbleClockController implements ClockPlugin {
|
||||
@Override
|
||||
public void setTextColor(int color) {
|
||||
mLockClock.setTextColor(color);
|
||||
mDigitalClock.setTextColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
|
||||
if (colorPalette == null || colorPalette.length == 0) {
|
||||
return;
|
||||
}
|
||||
final int length = colorPalette.length;
|
||||
mDigitalClock.setTextColor(colorPalette[Math.max(0, length - 6)]);
|
||||
mAnalogClock.setClockColors(colorPalette[Math.max(0, length - 6)],
|
||||
colorPalette[Math.max(0, length - 3)]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -78,6 +78,16 @@ public class ImageClock extends FrameLayout {
|
||||
mTime.setTimeZone(timeZone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the colors to use on the clock face.
|
||||
* @param dark Darker color obtained from color palette.
|
||||
* @param light Lighter color obtained from color palette.
|
||||
*/
|
||||
public void setClockColors(int dark, int light) {
|
||||
mHourHand.setColorFilter(dark);
|
||||
mMinuteHand.setColorFilter(light);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFinishInflate() {
|
||||
super.onFinishInflate();
|
||||
|
||||
@@ -76,10 +76,12 @@ public class StretchAnalogClock extends View {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the color of the minute hand.
|
||||
* Set the colors to use on the clock face.
|
||||
* @param dark Darker color obtained from color palette.
|
||||
* @param light Lighter color obtained from color palette.
|
||||
*/
|
||||
public void setMinuteHandColor(int color) {
|
||||
mMinutePaint.setColor(color);
|
||||
public void setClockColor(int dark, int light) {
|
||||
mHourPaint.setColor(dark);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -89,8 +89,17 @@ public class StretchAnalogClockController implements ClockPlugin {
|
||||
@Override
|
||||
public void setTextColor(int color) {
|
||||
mLockClock.setTextColor(color);
|
||||
mDigitalClock.setTextColor(color);
|
||||
mAnalogClock.setMinuteHandColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
|
||||
if (colorPalette == null || colorPalette.length == 0) {
|
||||
return;
|
||||
}
|
||||
final int length = colorPalette.length;
|
||||
mDigitalClock.setTextColor(colorPalette[Math.max(0, length - 5)]);
|
||||
mAnalogClock.setClockColor(colorPalette[Math.max(0, length - 5)],
|
||||
colorPalette[Math.max(0, length - 2)]);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -86,6 +86,15 @@ public class TypeClockController implements ClockPlugin {
|
||||
mTypeClock.setTextColor(color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
|
||||
if (colorPalette == null || colorPalette.length == 0) {
|
||||
return;
|
||||
}
|
||||
final int length = colorPalette.length;
|
||||
mTypeClock.setClockColor(colorPalette[Math.max(0, length - 5)]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dozeTimeTick() {
|
||||
mTypeClock.onTimeChanged();
|
||||
|
||||
@@ -43,7 +43,7 @@ public class TypographicClock extends TextView {
|
||||
private final Resources mResources;
|
||||
private final String[] mHours;
|
||||
private final String[] mMinutes;
|
||||
private final int mAccentColor;
|
||||
private int mAccentColor;
|
||||
private Calendar mTime;
|
||||
private String mDescFormat;
|
||||
private TimeZone mTimeZone;
|
||||
@@ -106,6 +106,13 @@ public class TypographicClock extends TextView {
|
||||
mTime.setTimeZone(timeZone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the accent color used on the clock face.
|
||||
*/
|
||||
public void setClockColor(int color) {
|
||||
mAccentColor = color;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
|
||||
@@ -48,6 +48,7 @@ import javax.inject.Singleton;
|
||||
@Singleton
|
||||
public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
|
||||
private static final String TAG = "SysuiColorExtractor";
|
||||
private final Tonal mTonal;
|
||||
private boolean mWallpaperVisible;
|
||||
private boolean mHasBackdrop;
|
||||
// Colors to return when the wallpaper isn't visible
|
||||
@@ -61,6 +62,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
|
||||
@VisibleForTesting
|
||||
public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) {
|
||||
super(context, type);
|
||||
mTonal = type instanceof Tonal ? (Tonal) type : new Tonal(context);
|
||||
mWpHiddenColors = new GradientColors();
|
||||
|
||||
WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
|
||||
@@ -94,7 +96,7 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable {
|
||||
}
|
||||
|
||||
private void updateDefaultGradients(WallpaperColors colors) {
|
||||
Tonal.applyFallback(colors, mWpHiddenColors);
|
||||
mTonal.applyFallback(colors, mWpHiddenColors);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user