summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/colorextraction/ColorExtractor.java55
-rw-r--r--core/java/com/android/internal/colorextraction/types/ExtractionType.java3
-rw-r--r--core/java/com/android/internal/colorextraction/types/Tonal.java110
-rw-r--r--packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java9
-rw-r--r--tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java17
-rw-r--r--tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java31
7 files changed, 162 insertions, 88 deletions
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
index 2608698f5b63..04819a5999eb 100644
--- a/core/java/com/android/internal/colorextraction/ColorExtractor.java
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -43,10 +43,6 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
private static final String TAG = "ColorExtractor";
- public static final int FALLBACK_COLOR = 0xff83888d;
-
- private int mMainFallbackColor = FALLBACK_COLOR;
- private int mSecondaryFallbackColor = FALLBACK_COLOR;
private final SparseArray<GradientColors[]> mGradientColors;
private final ArrayList<OnColorsChangedListener> mOnColorsChangedListeners;
private final Context mContext;
@@ -73,6 +69,9 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
}
mOnColorsChangedListeners = new ArrayList<>();
+ GradientColors[] systemColors = mGradientColors.get(WallpaperManager.FLAG_SYSTEM);
+ GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
+
WallpaperManager wallpaperManager = mContext.getSystemService(WallpaperManager.class);
if (wallpaperManager == null) {
Log.w(TAG, "Can't listen to color changes!");
@@ -83,23 +82,18 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
Trace.beginSection("ColorExtractor#getWallpaperColors");
mSystemColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
mLockColors = wallpaperManager.getWallpaperColors(WallpaperManager.FLAG_LOCK);
-
- GradientColors[] systemColors = mGradientColors.get(
- WallpaperManager.FLAG_SYSTEM);
- extractInto(mSystemColors,
- systemColors[TYPE_NORMAL],
- systemColors[TYPE_DARK],
- systemColors[TYPE_EXTRA_DARK]);
-
- GradientColors[] lockColors = mGradientColors.get(WallpaperManager.FLAG_LOCK);
- extractInto(mLockColors,
- lockColors[TYPE_NORMAL],
- lockColors[TYPE_DARK],
- lockColors[TYPE_EXTRA_DARK]);
- triggerColorsChanged(WallpaperManager.FLAG_SYSTEM
- | WallpaperManager.FLAG_LOCK);
Trace.endSection();
}
+
+ // Initialize all gradients with the current colors
+ extractInto(mSystemColors,
+ systemColors[TYPE_NORMAL],
+ systemColors[TYPE_DARK],
+ systemColors[TYPE_EXTRA_DARK]);
+ extractInto(mLockColors,
+ lockColors[TYPE_NORMAL],
+ lockColors[TYPE_DARK],
+ lockColors[TYPE_EXTRA_DARK]);
}
/**
@@ -181,25 +175,8 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
private void extractInto(WallpaperColors inWallpaperColors,
GradientColors outGradientColorsNormal, GradientColors outGradientColorsDark,
GradientColors outGradientColorsExtraDark) {
- if (inWallpaperColors == null) {
- applyFallback(outGradientColorsNormal);
- applyFallback(outGradientColorsDark);
- applyFallback(outGradientColorsExtraDark);
- return;
- }
- boolean success = mExtractionType.extractInto(inWallpaperColors, outGradientColorsNormal,
+ mExtractionType.extractInto(inWallpaperColors, outGradientColorsNormal,
outGradientColorsDark, outGradientColorsExtraDark);
- if (!success) {
- applyFallback(outGradientColorsNormal);
- applyFallback(outGradientColorsDark);
- applyFallback(outGradientColorsExtraDark);
- }
- }
-
- private void applyFallback(GradientColors outGradientColors) {
- outGradientColors.setMainColor(mMainFallbackColor);
- outGradientColors.setSecondaryColor(mSecondaryFallbackColor);
- outGradientColors.setSupportsDarkText(false);
}
public void destroy() {
@@ -218,8 +195,8 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
}
public static class GradientColors {
- private int mMainColor = FALLBACK_COLOR;
- private int mSecondaryColor = FALLBACK_COLOR;
+ private int mMainColor;
+ private int mSecondaryColor;
private boolean mSupportsDarkText;
public void setMainColor(int mainColor) {
diff --git a/core/java/com/android/internal/colorextraction/types/ExtractionType.java b/core/java/com/android/internal/colorextraction/types/ExtractionType.java
index 762b54fb1e6b..7000e798f87b 100644
--- a/core/java/com/android/internal/colorextraction/types/ExtractionType.java
+++ b/core/java/com/android/internal/colorextraction/types/ExtractionType.java
@@ -38,9 +38,8 @@ public interface ExtractionType {
* @param outGradientColorsNormal object that should receive normal colors
* @param outGradientColorsDark object that should receive dark colors
* @param outGradientColorsExtraDark object that should receive extra dark colors
- * @return true if successful.
*/
- boolean extractInto(WallpaperColors inWallpaperColors,
+ void extractInto(WallpaperColors inWallpaperColors,
ColorExtractor.GradientColors outGradientColorsNormal,
ColorExtractor.GradientColors outGradientColorsDark,
ColorExtractor.GradientColors outGradientColorsExtraDark);
diff --git a/core/java/com/android/internal/colorextraction/types/Tonal.java b/core/java/com/android/internal/colorextraction/types/Tonal.java
index b8ebe3000d8e..e78ca3844bed 100644
--- a/core/java/com/android/internal/colorextraction/types/Tonal.java
+++ b/core/java/com/android/internal/colorextraction/types/Tonal.java
@@ -44,24 +44,54 @@ public class Tonal implements ExtractionType {
private static final boolean DEBUG = true;
+ public static final int MAIN_COLOR_LIGHT = 0xffe0e0e0;
+ public static final int SECONDARY_COLOR_LIGHT = 0xff9e9e9e;
+ public static final int MAIN_COLOR_DARK = 0xff212121;
+ public static final int SECONDARY_COLOR_DARK = 0xff000000;
+
// Temporary variable to avoid allocations
private float[] mTmpHSL = new float[3];
/**
- * Grab colors from WallpaperColors as set them into GradientColors
+ * Grab colors from WallpaperColors and set them into GradientColors.
+ * Also applies the default gradient in case extraction fails.
+ *
+ * @param inWallpaperColors Input.
+ * @param outColorsNormal Colors for normal theme.
+ * @param outColorsDark Colors for dar theme.
+ * @param outColorsExtraDark Colors for extra dark theme.
+ */
+ public void extractInto(@Nullable WallpaperColors inWallpaperColors,
+ @NonNull GradientColors outColorsNormal, @NonNull GradientColors outColorsDark,
+ @NonNull GradientColors outColorsExtraDark) {
+ boolean success = runTonalExtraction(inWallpaperColors, outColorsNormal, outColorsDark,
+ outColorsExtraDark);
+ if (!success) {
+ applyFallback(inWallpaperColors, outColorsNormal, outColorsDark, outColorsExtraDark);
+ }
+ }
+
+ /**
+ * Grab colors from WallpaperColors and set them into GradientColors.
*
- * @param inWallpaperColors input
- * @param outColorsNormal colors for normal theme
- * @param outColorsDark colors for dar theme
- * @param outColorsExtraDark colors for extra dark theme
- * @return true if successful
+ * @param inWallpaperColors Input.
+ * @param outColorsNormal Colors for normal theme.
+ * @param outColorsDark Colors for dar theme.
+ * @param outColorsExtraDark Colors for extra dark theme.
+ * @return True if succeeded or false if failed.
*/
- public boolean extractInto(@NonNull WallpaperColors inWallpaperColors,
+ private boolean runTonalExtraction(@Nullable WallpaperColors inWallpaperColors,
@NonNull GradientColors outColorsNormal, @NonNull GradientColors outColorsDark,
@NonNull GradientColors outColorsExtraDark) {
+ if (inWallpaperColors == null) {
+ return false;
+ }
+
final List<Color> mainColors = inWallpaperColors.getMainColors();
final int mainColorsSize = mainColors.size();
+ final boolean supportsDarkText = (inWallpaperColors.getColorHints() &
+ WallpaperColors.HINT_SUPPORTS_DARK_TEXT) != 0;
if (mainColorsSize == 0) {
return false;
@@ -120,7 +150,6 @@ public class Tonal implements ExtractionType {
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;
if (DEBUG) {
StringBuilder builder = new StringBuilder("Tonal Palette - index: " + fitIndex +
". Main color: " + Integer.toHexString(getColorInt(fitIndex, h, s, l)) +
@@ -135,21 +164,38 @@ public class Tonal implements ExtractionType {
Log.d(TAG, builder.toString());
}
+ int primaryIndex = fitIndex;
+ int mainColor = getColorInt(primaryIndex, h, s, l);
+
+ // We might want use the fallback in case the extracted color is brighter than our
+ // light fallback or darker than our dark fallback.
+ ColorUtils.colorToHSL(mainColor, mTmpHSL);
+ final float mainLuminosity = mTmpHSL[2];
+ ColorUtils.colorToHSL(MAIN_COLOR_LIGHT, mTmpHSL);
+ final float lightLuminosity = mTmpHSL[2];
+ if (mainLuminosity > lightLuminosity) {
+ return false;
+ }
+ ColorUtils.colorToHSL(MAIN_COLOR_DARK, mTmpHSL);
+ final float darkLuminosity = mTmpHSL[2];
+ if (mainLuminosity < darkLuminosity) {
+ return false;
+ }
+
// Normal colors:
// best fit + a 2 colors offset
- int primaryIndex = fitIndex;
+ outColorsNormal.setMainColor(mainColor);
int secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
- outColorsNormal.setMainColor(getColorInt(primaryIndex, h, s, l));
outColorsNormal.setSecondaryColor(getColorInt(secondaryIndex, h, s, l));
// Dark colors:
// Stops at 4th color, only lighter if dark text is supported
- if (fitIndex < 2) {
+ if (supportsDarkText) {
+ primaryIndex = h.length - 1;
+ } else if (fitIndex < 2) {
primaryIndex = 0;
- } else if (fitIndex < textInversionIndex) {
- primaryIndex = Math.min(fitIndex, 3);
} else {
- primaryIndex = h.length - 1;
+ primaryIndex = Math.min(fitIndex, 3);
}
secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
outColorsDark.setMainColor(getColorInt(primaryIndex, h, s, l));
@@ -157,18 +203,17 @@ public class Tonal implements ExtractionType {
// Extra Dark:
// Stay close to dark colors until dark text is supported
- if (fitIndex < 2) {
+ if (supportsDarkText) {
+ primaryIndex = h.length - 1;
+ } else if (fitIndex < 2) {
primaryIndex = 0;
- } else if (fitIndex < textInversionIndex) {
- primaryIndex = 2;
} else {
- primaryIndex = h.length - 1;
+ primaryIndex = 2;
}
secondaryIndex = primaryIndex + (primaryIndex >= 2 ? -2 : 2);
outColorsExtraDark.setMainColor(getColorInt(primaryIndex, h, s, l));
outColorsExtraDark.setSecondaryColor(getColorInt(secondaryIndex, h, s, l));
- final boolean supportsDarkText = fitIndex >= textInversionIndex;
outColorsNormal.setSupportsDarkText(supportsDarkText);
outColorsDark.setSupportsDarkText(supportsDarkText);
outColorsExtraDark.setSupportsDarkText(supportsDarkText);
@@ -181,6 +226,33 @@ public class Tonal implements ExtractionType {
return true;
}
+ private void applyFallback(@Nullable WallpaperColors inWallpaperColors,
+ GradientColors outColorsNormal, GradientColors outColorsDark,
+ GradientColors outColorsExtraDark) {
+ applyFallback(inWallpaperColors, outColorsNormal);
+ applyFallback(inWallpaperColors, outColorsDark);
+ applyFallback(inWallpaperColors, outColorsExtraDark);
+ }
+
+ /**
+ * Sets the gradient to the light or dark fallbacks based on the current wallpaper colors.
+ *
+ * @param inWallpaperColors Colors to read.
+ * @param outGradientColors Destination.
+ */
+ public static void applyFallback(@Nullable WallpaperColors inWallpaperColors,
+ @NonNull GradientColors outGradientColors) {
+ boolean light = inWallpaperColors != null
+ && (inWallpaperColors.getColorHints() & WallpaperColors.HINT_SUPPORTS_DARK_TEXT)
+ != 0;
+ int innerColor = light ? MAIN_COLOR_LIGHT : MAIN_COLOR_DARK;
+ int outerColor = light ? SECONDARY_COLOR_LIGHT : SECONDARY_COLOR_DARK;
+
+ outGradientColors.setMainColor(innerColor);
+ outGradientColors.setSecondaryColor(outerColor);
+ outGradientColors.setSupportsDarkText(light);
+ }
+
private int getColorInt(int fitIndex, float[] h, float[] s, float[] l) {
mTmpHSL[0] = fract(h[fitIndex]) * 360.0f;
mTmpHSL[1] = s[fitIndex];
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index ccb81172c75c..3c895abd5e88 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -16,6 +16,7 @@
package com.android.systemui.colorextraction;
+import android.app.WallpaperColors;
import android.app.WallpaperManager;
import android.content.Context;
import android.os.Handler;
@@ -47,10 +48,10 @@ public class SysuiColorExtractor extends ColorExtractor {
@VisibleForTesting
public SysuiColorExtractor(Context context, ExtractionType type, boolean registerVisibility) {
super(context, type);
-
mWpHiddenColors = new GradientColors();
- mWpHiddenColors.setMainColor(FALLBACK_COLOR);
- mWpHiddenColors.setSecondaryColor(FALLBACK_COLOR);
+
+ WallpaperColors systemColors = getWallpaperColors(WallpaperManager.FLAG_SYSTEM);
+ updateDefaultGradients(systemColors);
if (registerVisibility) {
try {
@@ -71,6 +72,24 @@ public class SysuiColorExtractor extends ColorExtractor {
}
}
+ private void updateDefaultGradients(WallpaperColors colors) {
+ Tonal.applyFallback(colors, mWpHiddenColors);
+ }
+
+ @Override
+ public void onColorsChanged(WallpaperColors colors, int which) {
+ super.onColorsChanged(colors, which);
+
+ if ((which & WallpaperManager.FLAG_SYSTEM) != 0) {
+ updateDefaultGradients(colors);
+ }
+ }
+
+ @VisibleForTesting
+ GradientColors getFallbackColors() {
+ return mWpHiddenColors;
+ }
+
/**
* Get TYPE_NORMAL colors when wallpaper is visible, or fallback otherwise.
*
diff --git a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
index a81188af85ef..690186e91f55 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/colorextraction/SysuiColorExtractorTests.java
@@ -48,14 +48,12 @@ public class SysuiColorExtractorTests extends SysuiTestCase {
@Test
public void getColors_usesGreyIfWallpaperNotVisible() {
- ColorExtractor.GradientColors fallbackColors = new ColorExtractor.GradientColors();
- fallbackColors.setMainColor(ColorExtractor.FALLBACK_COLOR);
- fallbackColors.setSecondaryColor(ColorExtractor.FALLBACK_COLOR);
-
SysuiColorExtractor extractor = new SysuiColorExtractor(getContext(), new Tonal(), false);
simulateEvent(extractor);
extractor.setWallpaperVisible(false);
+ ColorExtractor.GradientColors fallbackColors = extractor.getFallbackColors();
+
for (int which : sWhich) {
for (int type : sTypes) {
assertEquals("Not using fallback!", extractor.getColors(which, type),
@@ -76,7 +74,6 @@ public class SysuiColorExtractorTests extends SysuiTestCase {
outGradientColorsNormal.set(colors);
outGradientColorsDark.set(colors);
outGradientColorsExtraDark.set(colors);
- return true;
}, false);
simulateEvent(extractor);
extractor.setWallpaperVisible(true);
@@ -91,7 +88,7 @@ public class SysuiColorExtractorTests extends SysuiTestCase {
private void simulateEvent(SysuiColorExtractor extractor) {
// Let's fake a color event
- extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.BLACK), null, null, 0),
+ extractor.onColorsChanged(new WallpaperColors(Color.valueOf(Color.GREEN), null, null, 0),
WallpaperManager.FLAG_SYSTEM | WallpaperManager.FLAG_LOCK);
}
} \ No newline at end of file
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
index 71821472f55e..0060901578cd 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -62,21 +62,6 @@ public class ColorExtractorTest {
}
@Test
- public void getColors_usesFallbackIfFails() {
- ExtractionType alwaysFail =
- (inWallpaperColors, outGradientColorsNormal, outGradientColorsDark,
- outGradientColorsExtraDark) -> false;
- ColorExtractor extractor = new ColorExtractor(mContext, alwaysFail);
- GradientColors colors = extractor.getColors(WallpaperManager.FLAG_SYSTEM);
-
- assertEquals("Should be using the fallback color.",
- colors.getMainColor(), ColorExtractor.FALLBACK_COLOR);
- assertEquals("Should be using the fallback color.",
- colors.getSecondaryColor(), ColorExtractor.FALLBACK_COLOR);
- assertFalse("Dark text support should be false.", colors.supportsDarkText());
- }
-
- @Test
public void getColors_usesExtractedColors() {
GradientColors colorsExpectedNormal = new GradientColors();
colorsExpectedNormal.setMainColor(Color.RED);
@@ -96,8 +81,6 @@ public class ColorExtractorTest {
outGradientColorsNormal.set(colorsExpectedNormal);
outGradientColorsDark.set(colorsExpectedDark);
outGradientColorsExtraDark.set(colorsExpectedExtraDark);
- // Successful extraction
- return true;
};
ColorExtractor extractor = new ColorExtractor(mContext, type);
diff --git a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
index 1e3e8e91d9ef..d408b84109bc 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/types/TonalTest.java
@@ -40,6 +40,31 @@ import java.util.Arrays;
public class TonalTest {
@Test
+ public void extractInto_usesFallback() {
+ GradientColors normal = new GradientColors();
+ Tonal tonal = new Tonal();
+ tonal.extractInto(null, normal, new GradientColors(),
+ new GradientColors());
+ assertFalse("Should use fallback color if WallpaperColors is null.",
+ normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT);
+ }
+
+ @Test
+ public void extractInto_usesFallbackWhenTooLightOrDark() {
+ GradientColors normal = new GradientColors();
+ Tonal tonal = new Tonal();
+ tonal.extractInto(new WallpaperColors(Color.valueOf(0xff000000), null, null, 0),
+ normal, new GradientColors(), new GradientColors());
+ assertTrue("Should use fallback color if WallpaperColors is too dark.",
+ normal.getMainColor() == Tonal.MAIN_COLOR_DARK);
+
+ tonal.extractInto(new WallpaperColors(Color.valueOf(0xffffffff), null, null, 0),
+ normal, new GradientColors(), new GradientColors());
+ assertTrue("Should use fallback color if WallpaperColors is too light.",
+ normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT);
+ }
+
+ @Test
public void colorRange_containsColor() {
Tonal.ColorRange colorRange = new Tonal.ColorRange(new Range<>(0f, 50f),
new Range<>(0f, 1f), new Range<>(0f, 1f));
@@ -72,8 +97,10 @@ public class TonalTest {
// Make sure that palette generation will fail
Tonal tonal = new Tonal();
- boolean success = tonal.extractInto(colors, new GradientColors(), new GradientColors(),
+ GradientColors normal = new GradientColors();
+ tonal.extractInto(colors, normal, new GradientColors(),
new GradientColors());
- assertFalse("Cannot generate a tonal palette from blacklisted colors ", success);
+ assertFalse("Cannot generate a tonal palette from blacklisted colors.",
+ normal.getMainColor() == Tonal.MAIN_COLOR_LIGHT);
}
}