Merge "Apply colors extracted from wallpaper to clock faces."

This commit is contained in:
Lucas Dupin
2019-02-10 18:12:46 +00:00
committed by Android (Google) Code Review
11 changed files with 136 additions and 14 deletions

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}
}

View File

@@ -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.

View File

@@ -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;

View File

@@ -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

View File

@@ -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();

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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();

View File

@@ -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();

View File

@@ -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