summaryrefslogtreecommitdiffstats
path: root/src/com/android/launcher3/dynamicui
diff options
context:
space:
mode:
authorTony Wickham <twickham@google.com>2016-04-01 16:00:49 -0700
committerTony Wickham <twickham@google.com>2016-05-09 15:41:38 -0700
commit462b5cca7bb1d5e24fb8277b0cfe238cc2e1e980 (patch)
treeb3bca05af635632cc3966094cca670baf6ef295c /src/com/android/launcher3/dynamicui
parent34a2d31f3208c64f6ebf403f8a0cb6ea96461747 (diff)
downloadandroid_packages_apps_Trebuchet-462b5cca7bb1d5e24fb8277b0cfe238cc2e1e980.tar.gz
android_packages_apps_Trebuchet-462b5cca7bb1d5e24fb8277b0cfe238cc2e1e980.tar.bz2
android_packages_apps_Trebuchet-462b5cca7bb1d5e24fb8277b0cfe238cc2e1e980.zip
Extract color for the hotseat.
- Only considers the bottom fourth of the wallpaper - Is translucent black or white depending on how dark/light the wallpaper is - Hotseat extends behind the nav bar Bug: 27230217 Change-Id: Id4ea6ee91b4dd221b4c277d22d5041cab178801d
Diffstat (limited to 'src/com/android/launcher3/dynamicui')
-rw-r--r--src/com/android/launcher3/dynamicui/ColorExtractionService.java14
-rw-r--r--src/com/android/launcher3/dynamicui/ExtractedColors.java86
-rw-r--r--src/com/android/launcher3/dynamicui/ExtractionUtils.java44
3 files changed, 114 insertions, 30 deletions
diff --git a/src/com/android/launcher3/dynamicui/ColorExtractionService.java b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
index 95a62b957..89594f407 100644
--- a/src/com/android/launcher3/dynamicui/ColorExtractionService.java
+++ b/src/com/android/launcher3/dynamicui/ColorExtractionService.java
@@ -32,6 +32,9 @@ import com.android.launcher3.LauncherSettings;
*/
public class ColorExtractionService extends IntentService {
+ /** The fraction of the wallpaper to extract colors for use on the hotseat. */
+ private static final float HOTSEAT_FRACTION = 1f / 4;
+
public ColorExtractionService() {
super("ColorExtractionService");
}
@@ -44,10 +47,21 @@ public class ColorExtractionService extends IntentService {
if (wallpaperManager.getWallpaperInfo() != null) {
// We can't extract colors from live wallpapers, so just use the default color always.
extractedColors.updatePalette(null);
+ extractedColors.updateHotseatPalette(null);
} else {
Bitmap wallpaper = ((BitmapDrawable) wallpaperManager.getDrawable()).getBitmap();
Palette palette = Palette.from(wallpaper).generate();
extractedColors.updatePalette(palette);
+ // We extract colors for the hotseat separately,
+ // since it only considers the lower part of the wallpaper.
+ // TODO(twickham): update Palette library to 23.3.1 or higher,
+ // which fixes a bug with using regions (b/28349435).
+ Palette hotseatPalette = Palette.from(wallpaper)
+ .setRegion(0, (int) (wallpaper.getHeight() * (1f - HOTSEAT_FRACTION)),
+ wallpaper.getWidth(), wallpaper.getHeight())
+ .clearFilters()
+ .generate();
+ extractedColors.updateHotseatPalette(hotseatPalette);
}
// Save the extracted colors and wallpaper id to LauncherProvider.
diff --git a/src/com/android/launcher3/dynamicui/ExtractedColors.java b/src/com/android/launcher3/dynamicui/ExtractedColors.java
index 4d17ff764..e545288a0 100644
--- a/src/com/android/launcher3/dynamicui/ExtractedColors.java
+++ b/src/com/android/launcher3/dynamicui/ExtractedColors.java
@@ -18,6 +18,7 @@ package com.android.launcher3.dynamicui;
import android.content.Context;
import android.graphics.Color;
+import android.support.v4.graphics.ColorUtils;
import android.support.v7.graphics.Palette;
import android.util.Log;
@@ -35,26 +36,30 @@ public class ExtractedColors {
// These color profile indices should NOT be changed, since they are used when saving and
// loading extracted colors. New colors should always be added at the end.
- public static final int DEFAULT_INDEX = 0;
- public static final int VIBRANT_INDEX = 1;
- public static final int VIBRANT_DARK_INDEX = 2;
- public static final int VIBRANT_LIGHT_INDEX = 3;
- public static final int MUTED_INDEX = 4;
- public static final int MUTED_DARK_INDEX = 5;
- public static final int MUTED_LIGHT_INDEX = 6;
-
- public static final int NUM_COLOR_PROFILES = 7;
+ public static final int VERSION_INDEX = 0;
+ public static final int HOTSEAT_INDEX = 1;
+ // public static final int VIBRANT_INDEX = 2;
+ // public static final int VIBRANT_DARK_INDEX = 3;
+ // public static final int VIBRANT_LIGHT_INDEX = 4;
+ // public static final int MUTED_INDEX = 5;
+ // public static final int MUTED_DARK_INDEX = 6;
+ // public static final int MUTED_LIGHT_INDEX = 7;
+
+ public static final int NUM_COLOR_PROFILES = 1;
+ private static final int VERSION = 1;
private static final String COLOR_SEPARATOR = ",";
private int[] mColors;
public ExtractedColors() {
- mColors = new int[NUM_COLOR_PROFILES];
+ // The first entry is reserved for the version number.
+ mColors = new int[NUM_COLOR_PROFILES + 1];
+ mColors[VERSION_INDEX] = VERSION;
}
public void setColorAtIndex(int index, int color) {
- if (index >= 0 && index < mColors.length) {
+ if (index > VERSION_INDEX && index < mColors.length) {
mColors[index] = color;
} else {
Log.e(TAG, "Attempted to set a color at an invalid index " + index);
@@ -89,17 +94,21 @@ public class ExtractedColors {
*/
public void load(Context context) {
String encodedString = Utilities.getPrefs(context).getString(
- ExtractionUtils.EXTRACTED_COLORS_PREFERENCE_KEY, DEFAULT_COLOR + "");
+ ExtractionUtils.EXTRACTED_COLORS_PREFERENCE_KEY, VERSION + "");
decodeFromString(encodedString);
+
+ if (mColors[VERSION_INDEX] != VERSION) {
+ ExtractionUtils.startColorExtractionService(context);
+ }
}
/** @param index must be one of the index values defined at the top of this class. */
- public int getColor(int index) {
- if (index >= 0 && index < mColors.length) {
+ public int getColor(int index, int defaultColor) {
+ if (index > VERSION_INDEX && index < mColors.length) {
return mColors[index];
}
- return DEFAULT_COLOR;
+ return defaultColor;
}
/**
@@ -112,20 +121,39 @@ public class ExtractedColors {
setColorAtIndex(i, ExtractedColors.DEFAULT_COLOR);
}
} else {
- setColorAtIndex(ExtractedColors.DEFAULT_INDEX,
- ExtractedColors.DEFAULT_COLOR);
- setColorAtIndex(ExtractedColors.VIBRANT_INDEX,
- palette.getVibrantColor(ExtractedColors.DEFAULT_COLOR));
- setColorAtIndex(ExtractedColors.VIBRANT_DARK_INDEX,
- palette.getDarkVibrantColor(ExtractedColors.DEFAULT_DARK));
- setColorAtIndex(ExtractedColors.VIBRANT_LIGHT_INDEX,
- palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
- setColorAtIndex(ExtractedColors.MUTED_INDEX,
- palette.getMutedColor(ExtractedColors.DEFAULT_COLOR));
- setColorAtIndex(ExtractedColors.MUTED_DARK_INDEX,
- palette.getDarkMutedColor(ExtractedColors.DEFAULT_DARK));
- setColorAtIndex(ExtractedColors.MUTED_LIGHT_INDEX,
- palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
+ // We currently don't use any of the colors defined by the Palette API,
+ // but this is how we would add them if we ever need them.
+
+ // setColorAtIndex(ExtractedColors.VIBRANT_INDEX,
+ // palette.getVibrantColor(ExtractedColors.DEFAULT_COLOR));
+ // setColorAtIndex(ExtractedColors.VIBRANT_DARK_INDEX,
+ // palette.getDarkVibrantColor(ExtractedColors.DEFAULT_DARK));
+ // setColorAtIndex(ExtractedColors.VIBRANT_LIGHT_INDEX,
+ // palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
+ // setColorAtIndex(ExtractedColors.MUTED_INDEX,
+ // palette.getMutedColor(DEFAULT_COLOR));
+ // setColorAtIndex(ExtractedColors.MUTED_DARK_INDEX,
+ // palette.getDarkMutedColor(ExtractedColors.DEFAULT_DARK));
+ // setColorAtIndex(ExtractedColors.MUTED_LIGHT_INDEX,
+ // palette.getLightVibrantColor(ExtractedColors.DEFAULT_LIGHT));
+ }
+ }
+
+ /**
+ * The hotseat's color is defined as follows:
+ * - 12% black for super light wallpaper
+ * - 18% white for super dark
+ * - 25% white otherwise
+ */
+ public void updateHotseatPalette(Palette hotseatPalette) {
+ int hotseatColor;
+ if (hotseatPalette != null && ExtractionUtils.isSuperLight(hotseatPalette)) {
+ hotseatColor = ColorUtils.setAlphaComponent(Color.BLACK, (int) (0.12f * 255));
+ } else if (hotseatPalette != null && ExtractionUtils.isSuperDark(hotseatPalette)) {
+ hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.18f * 255));
+ } else {
+ hotseatColor = ColorUtils.setAlphaComponent(Color.WHITE, (int) (0.25f * 255));
}
+ setColorAtIndex(HOTSEAT_INDEX, hotseatColor);
}
}
diff --git a/src/com/android/launcher3/dynamicui/ExtractionUtils.java b/src/com/android/launcher3/dynamicui/ExtractionUtils.java
index 0b28ba6f9..6dc0035ee 100644
--- a/src/com/android/launcher3/dynamicui/ExtractionUtils.java
+++ b/src/com/android/launcher3/dynamicui/ExtractionUtils.java
@@ -20,11 +20,15 @@ import android.app.WallpaperManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
+import android.graphics.Color;
+import android.support.v4.graphics.ColorUtils;
+import android.support.v7.graphics.Palette;
import com.android.launcher3.Utilities;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.util.List;
/**
* Contains helper fields and methods related to extracting colors from the wallpaper.
@@ -34,6 +38,7 @@ public class ExtractionUtils {
public static final String WALLPAPER_ID_PREFERENCE_KEY = "pref_wallpaperId";
private static final int FLAG_SET_SYSTEM = 1 << 0; // TODO: use WallpaperManager.FLAG_SET_SYSTEM
+ private static final float MIN_CONTRAST_RATIO = 2f;
/**
* Extract colors in the :wallpaper-chooser process, if the wallpaper id has changed.
@@ -46,12 +51,17 @@ public class ExtractionUtils {
@Override
public void run() {
if (hasWallpaperIdChanged(context)) {
- context.startService(new Intent(context, ColorExtractionService.class));
+ startColorExtractionService(context);
}
}
});
}
+ /** Starts the {@link ColorExtractionService} without checking the wallpaper id */
+ public static void startColorExtractionService(Context context) {
+ context.startService(new Intent(context, ColorExtractionService.class));
+ }
+
private static boolean hasWallpaperIdChanged(Context context) {
if (!Utilities.isNycOrAbove()) {
// TODO: update an id in sharedprefs in onWallpaperChanged broadcast, and read it here.
@@ -72,4 +82,36 @@ public class ExtractionUtils {
return -1;
}
}
+
+ public static boolean isSuperLight(Palette p) {
+ return !isLegibleOnWallpaper(Color.WHITE, p.getSwatches());
+ }
+
+ public static boolean isSuperDark(Palette p) {
+ return !isLegibleOnWallpaper(Color.BLACK, p.getSwatches());
+ }
+
+ /**
+ * Given a color, returns true if that color is legible on
+ * the given wallpaper color swatches, else returns false.
+ */
+ private static boolean isLegibleOnWallpaper(int color, List<Palette.Swatch> wallpaperSwatches) {
+ int legiblePopulation = 0;
+ int illegiblePopulation = 0;
+ for (Palette.Swatch swatch : wallpaperSwatches) {
+ if (isLegible(color, swatch.getRgb())) {
+ legiblePopulation += swatch.getPopulation();
+ } else {
+ illegiblePopulation += swatch.getPopulation();
+ }
+ }
+ return legiblePopulation > illegiblePopulation;
+ }
+
+ /** @return Whether the foreground color is legible on the background color. */
+ private static boolean isLegible(int foreground, int background) {
+ background = ColorUtils.setAlphaComponent(background, 255);
+ return ColorUtils.calculateContrast(foreground, background) >= MIN_CONTRAST_RATIO;
+ }
+
}