Commit 0107486c authored by linus_lee's avatar linus_lee Committed by Danny Baumann
Browse files

Eleven: Make sure we have vibrant colors for all default colors

Change-Id: I4be163e75fc35d3b139439c504d769d17d980ace
parent 657192dc
...@@ -121,7 +121,7 @@ ...@@ -121,7 +121,7 @@
<color name="letter_tile_default_color">#cccccc</color> <color name="letter_tile_default_color">#cccccc</color>
<color name="letter_tile_font_color">#ffffff</color> <color name="letter_tile_font_color">#ffffff</color>
<array name="letter_tile_colors"> <array name="letter_tile_colors">
<item>#9237A2</item> <item>#883397</item>
<item>#4B498C</item> <item>#4B498C</item>
<item>#4E5BA7</item> <item>#4E5BA7</item>
<item>#41A4F4</item> <item>#41A4F4</item>
...@@ -130,4 +130,15 @@ ...@@ -130,4 +130,15 @@
<item>#B9BF45</item> <item>#B9BF45</item>
<item>#757578</item> <item>#757578</item>
</array> </array>
<array name="letter_tile_vibrant_dark_colors">
<item>#b74bc9</item>
<item>#6967bf</item>
<item>#2a315a</item>
<item>#07497d</item>
<item>#0c6c64</item>
<item>#415a2a</item>
<item>#5f6322</item>
<item>#505052</item>
</array>
</resources> </resources>
...@@ -33,7 +33,6 @@ import android.database.MatrixCursor; ...@@ -33,7 +33,6 @@ import android.database.MatrixCursor;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.media.AudioManager; import android.media.AudioManager;
import android.media.AudioManager.OnAudioFocusChangeListener; import android.media.AudioManager.OnAudioFocusChangeListener;
import android.media.MediaMetadataRetriever;
import android.media.MediaMetadata; import android.media.MediaMetadata;
import android.media.MediaPlayer; import android.media.MediaPlayer;
import android.media.audiofx.AudioEffect; import android.media.audiofx.AudioEffect;
...@@ -52,7 +51,6 @@ import android.os.SystemClock; ...@@ -52,7 +51,6 @@ import android.os.SystemClock;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.provider.MediaStore.Audio.AlbumColumns; import android.provider.MediaStore.Audio.AlbumColumns;
import android.provider.MediaStore.Audio.AudioColumns; import android.provider.MediaStore.Audio.AudioColumns;
import android.support.v7.graphics.Palette;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
...@@ -66,7 +64,7 @@ import com.cyanogenmod.eleven.provider.MusicPlaybackState; ...@@ -66,7 +64,7 @@ import com.cyanogenmod.eleven.provider.MusicPlaybackState;
import com.cyanogenmod.eleven.provider.RecentStore; import com.cyanogenmod.eleven.provider.RecentStore;
import com.cyanogenmod.eleven.provider.SongPlayCount; import com.cyanogenmod.eleven.provider.SongPlayCount;
import com.cyanogenmod.eleven.service.MusicPlaybackTrack; import com.cyanogenmod.eleven.service.MusicPlaybackTrack;
import com.cyanogenmod.eleven.utils.ApolloUtils; import com.cyanogenmod.eleven.utils.BitmapWithColors;
import com.cyanogenmod.eleven.utils.Lists; import com.cyanogenmod.eleven.utils.Lists;
import com.cyanogenmod.eleven.utils.SrtManager; import com.cyanogenmod.eleven.utils.SrtManager;
...@@ -496,8 +494,7 @@ public class MusicPlaybackService extends Service { ...@@ -496,8 +494,7 @@ public class MusicPlaybackService extends Service {
// to improve perf, instead of hitting the disk cache or file cache, store the bitmaps in memory // to improve perf, instead of hitting the disk cache or file cache, store the bitmaps in memory
private String mCachedKey; private String mCachedKey;
private Bitmap[] mCachedBitmap = new Bitmap[2]; private BitmapWithColors[] mCachedBitmapWithColors = new BitmapWithColors[2];
private int mCachedBitmapAccentColor = 0;
/** /**
* Image cache * Image cache
...@@ -1475,7 +1472,7 @@ public class MusicPlaybackService extends Service { ...@@ -1475,7 +1472,7 @@ public class MusicPlaybackService extends Service {
mSession.setPlaybackState(new PlaybackState.Builder() mSession.setPlaybackState(new PlaybackState.Builder()
.setState(playState, position(), 1.0f).build()); .setState(playState, position(), 1.0f).build());
} else if (what.equals(META_CHANGED) || what.equals(QUEUE_CHANGED)) { } else if (what.equals(META_CHANGED) || what.equals(QUEUE_CHANGED)) {
Bitmap albumArt = getAlbumArt(false); Bitmap albumArt = getAlbumArt(false).getBitmap();
if (albumArt != null) { if (albumArt != null) {
// RemoteControlClient wants to recycle the bitmaps thrown at it, so we need // RemoteControlClient wants to recycle the bitmaps thrown at it, so we need
// to make sure not to hand out our cache copy // to make sure not to hand out our cache copy
...@@ -1522,7 +1519,7 @@ public class MusicPlaybackService extends Service { ...@@ -1522,7 +1519,7 @@ public class MusicPlaybackService extends Service {
Intent nowPlayingIntent = new Intent("com.cyanogenmod.eleven.AUDIO_PLAYER") Intent nowPlayingIntent = new Intent("com.cyanogenmod.eleven.AUDIO_PLAYER")
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent clickIntent = PendingIntent.getActivity(this, 0, nowPlayingIntent, 0); PendingIntent clickIntent = PendingIntent.getActivity(this, 0, nowPlayingIntent, 0);
Bitmap artwork = getAlbumArt(false); BitmapWithColors artwork = getAlbumArt(false);
if (mNotificationPostTime == 0) { if (mNotificationPostTime == 0) {
mNotificationPostTime = System.currentTimeMillis(); mNotificationPostTime = System.currentTimeMillis();
...@@ -1530,7 +1527,7 @@ public class MusicPlaybackService extends Service { ...@@ -1530,7 +1527,7 @@ public class MusicPlaybackService extends Service {
Notification.Builder builder = new Notification.Builder(this) Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_notification) .setSmallIcon(R.drawable.ic_notification)
.setLargeIcon(artwork) .setLargeIcon(artwork.getBitmap())
.setContentIntent(clickIntent) .setContentIntent(clickIntent)
.setContentTitle(getTrackName()) .setContentTitle(getTrackName())
.setContentText(text) .setContentText(text)
...@@ -1547,23 +1544,7 @@ public class MusicPlaybackService extends Service { ...@@ -1547,23 +1544,7 @@ public class MusicPlaybackService extends Service {
getString(R.string.accessibility_next), getString(R.string.accessibility_next),
retrievePlaybackAction(NEXT_ACTION)); retrievePlaybackAction(NEXT_ACTION));
if (mCachedBitmapAccentColor == 0 && artwork != null) { builder.setColor(artwork.getVibrantDarkColor());
// Generate a new Palette from the current artwork
final Palette p = Palette.generate(artwork);
if (p != null) {
// Check for dark vibrant colors, then vibrant
Palette.Swatch swatch = p.getDarkVibrantSwatch();
if (swatch == null) {
swatch = p.getVibrantSwatch();
}
if (swatch != null) {
mCachedBitmapAccentColor = swatch.getRgb();
}
}
}
if (mCachedBitmapAccentColor != 0) {
builder.setColor(mCachedBitmapAccentColor);
}
return builder.build(); return builder.build();
} }
...@@ -2680,7 +2661,7 @@ public class MusicPlaybackService extends Service { ...@@ -2680,7 +2661,7 @@ public class MusicPlaybackService extends Service {
* Currently Has no impact on the artwork size if one exists * Currently Has no impact on the artwork size if one exists
* @return The album art for the current album. * @return The album art for the current album.
*/ */
public Bitmap getAlbumArt(boolean smallBitmap) { public BitmapWithColors getAlbumArt(boolean smallBitmap) {
final String albumName = getAlbumName(); final String albumName = getAlbumName();
final String artistName = getArtistName(); final String artistName = getArtistName();
final long albumId = getAlbumId(); final long albumId = getAlbumId();
...@@ -2688,23 +2669,23 @@ public class MusicPlaybackService extends Service { ...@@ -2688,23 +2669,23 @@ public class MusicPlaybackService extends Service {
final int targetIndex = smallBitmap ? 0 : 1; final int targetIndex = smallBitmap ? 0 : 1;
// if the cached key matches and we have the bitmap, return it // if the cached key matches and we have the bitmap, return it
if (key.equals(mCachedKey) && mCachedBitmap[targetIndex] != null) { if (key.equals(mCachedKey) && mCachedBitmapWithColors[targetIndex] != null) {
return mCachedBitmap[targetIndex]; return mCachedBitmapWithColors[targetIndex];
} }
// otherwise get the artwork (or defaultartwork if none found) // otherwise get the artwork (or defaultartwork if none found)
final Bitmap bitmap = mImageFetcher.getArtwork(albumName, albumId, artistName, smallBitmap); final BitmapWithColors bitmap = mImageFetcher.getArtwork(albumName,
albumId, artistName, smallBitmap);
// if the key is different, clear the bitmaps first // if the key is different, clear the bitmaps first
if (!key.equals(mCachedKey)) { if (!key.equals(mCachedKey)) {
mCachedBitmap[0] = null; mCachedBitmapWithColors[0] = null;
mCachedBitmap[1] = null; mCachedBitmapWithColors[1] = null;
mCachedBitmapAccentColor = 0;
} }
// store the new key and bitmap // store the new key and bitmap
mCachedKey = key; mCachedKey = key;
mCachedBitmap[targetIndex] = bitmap; mCachedBitmapWithColors[targetIndex] = bitmap;
return bitmap; return bitmap;
} }
......
...@@ -114,7 +114,7 @@ public class AppWidgetLarge extends AppWidgetBase { ...@@ -114,7 +114,7 @@ public class AppWidgetLarge extends AppWidgetBase {
final CharSequence trackName = service.getTrackName(); final CharSequence trackName = service.getTrackName();
final CharSequence artistName = service.getArtistName(); final CharSequence artistName = service.getArtistName();
final CharSequence albumName = service.getAlbumName(); final CharSequence albumName = service.getAlbumName();
final Bitmap bitmap = service.getAlbumArt(true); final Bitmap bitmap = service.getAlbumArt(true).getBitmap();
// Set the titles and artwork // Set the titles and artwork
appWidgetView.setTextViewText(R.id.app_widget_large_line_one, trackName); appWidgetView.setTextViewText(R.id.app_widget_large_line_one, trackName);
......
...@@ -119,7 +119,7 @@ public class AppWidgetLargeAlternate extends AppWidgetBase { ...@@ -119,7 +119,7 @@ public class AppWidgetLargeAlternate extends AppWidgetBase {
final CharSequence trackName = service.getTrackName(); final CharSequence trackName = service.getTrackName();
final CharSequence artistName = service.getArtistName(); final CharSequence artistName = service.getArtistName();
final CharSequence albumName = service.getAlbumName(); final CharSequence albumName = service.getAlbumName();
final Bitmap bitmap = service.getAlbumArt(true); final Bitmap bitmap = service.getAlbumArt(true).getBitmap();
// Set the titles and artwork // Set the titles and artwork
appWidgetView.setTextViewText(R.id.app_widget_large_alternate_line_one, trackName); appWidgetView.setTextViewText(R.id.app_widget_large_alternate_line_one, trackName);
......
...@@ -116,7 +116,7 @@ public class AppWidgetSmall extends AppWidgetBase { ...@@ -116,7 +116,7 @@ public class AppWidgetSmall extends AppWidgetBase {
final CharSequence trackName = service.getTrackName(); final CharSequence trackName = service.getTrackName();
final CharSequence artistName = service.getArtistName(); final CharSequence artistName = service.getArtistName();
final Bitmap bitmap = service.getAlbumArt(true); final Bitmap bitmap = service.getAlbumArt(true).getBitmap();
// Set the titles and artwork // Set the titles and artwork
if (TextUtils.isEmpty(trackName) && TextUtils.isEmpty(artistName)) { if (TextUtils.isEmpty(trackName) && TextUtils.isEmpty(artistName)) {
......
...@@ -22,6 +22,7 @@ import android.widget.ImageView; ...@@ -22,6 +22,7 @@ import android.widget.ImageView;
import com.cyanogenmod.eleven.Config; import com.cyanogenmod.eleven.Config;
import com.cyanogenmod.eleven.MusicPlaybackService; import com.cyanogenmod.eleven.MusicPlaybackService;
import com.cyanogenmod.eleven.cache.PlaylistWorkerTask.PlaylistWorkerType; import com.cyanogenmod.eleven.cache.PlaylistWorkerTask.PlaylistWorkerType;
import com.cyanogenmod.eleven.utils.BitmapWithColors;
import com.cyanogenmod.eleven.utils.MusicUtils; import com.cyanogenmod.eleven.utils.MusicUtils;
import com.cyanogenmod.eleven.widgets.BlurScrimImage; import com.cyanogenmod.eleven.widgets.BlurScrimImage;
import com.cyanogenmod.eleven.widgets.LetterTileDrawable; import com.cyanogenmod.eleven.widgets.LetterTileDrawable;
...@@ -187,8 +188,8 @@ public class ImageFetcher extends ImageWorker { ...@@ -187,8 +188,8 @@ public class ImageFetcher extends ImageWorker {
* @param smallArtwork Get the small version of the default artwork if no artwork exists * @param smallArtwork Get the small version of the default artwork if no artwork exists
* @return The album art as an {@link Bitmap} * @return The album art as an {@link Bitmap}
*/ */
public Bitmap getArtwork(final String albumName, final long albumId, final String artistName, public BitmapWithColors getArtwork(final String albumName, final long albumId,
boolean smallArtwork) { final String artistName, boolean smallArtwork) {
// Check the disk cache // Check the disk cache
Bitmap artwork = null; Bitmap artwork = null;
String key = String.valueOf(albumId); String key = String.valueOf(albumId);
...@@ -201,7 +202,7 @@ public class ImageFetcher extends ImageWorker { ...@@ -201,7 +202,7 @@ public class ImageFetcher extends ImageWorker {
artwork = mImageCache.getArtworkFromFile(mContext, albumId); artwork = mImageCache.getArtworkFromFile(mContext, albumId);
} }
if (artwork != null) { if (artwork != null) {
return artwork; return new BitmapWithColors(artwork);
} }
return LetterTileDrawable.createDefaultBitmap(mContext, key, ImageType.ALBUM, false, return LetterTileDrawable.createDefaultBitmap(mContext, key, ImageType.ALBUM, false,
......
/*
* Copyright (C) 2014 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package com.cyanogenmod.eleven.utils;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.support.v7.graphics.Palette;
public class BitmapWithColors {
private Bitmap mBitmap;
private int mVibrantColor;
private int mVibrantDarkColor;
private boolean mColorsLoaded = false;
public BitmapWithColors(Bitmap bitmap) {
mBitmap = bitmap;
mVibrantColor = Color.TRANSPARENT;
mVibrantDarkColor = Color.TRANSPARENT;
mColorsLoaded = false;
}
public BitmapWithColors(Bitmap bitmap, int vibrantColor, int vibrantDarkColor) {
mBitmap = bitmap;
mVibrantColor = vibrantColor;
mVibrantDarkColor = vibrantDarkColor;
mColorsLoaded = true;
}
public Bitmap getBitmap() {
return mBitmap;
}
public int getVibrantColor() {
loadColorsIfNeeded();
return mVibrantColor;
}
public int getVibrantDarkColor() {
loadColorsIfNeeded();
return mVibrantDarkColor;
}
private void loadColorsIfNeeded() {
synchronized (this) {
if (mColorsLoaded) {
return;
}
}
final Palette p = Palette.generate(mBitmap);
int vibrantColor = Color.TRANSPARENT;
int vibrantDarkColor = Color.TRANSPARENT;
if (p != null) {
Palette.Swatch swatch = p.getDarkVibrantSwatch();
if (swatch != null) {
vibrantDarkColor = swatch.getRgb();
}
swatch = p.getVibrantSwatch();
if (swatch != null) {
vibrantColor = swatch.getRgb();
}
}
if (vibrantColor == Color.TRANSPARENT && vibrantDarkColor != Color.TRANSPARENT) {
vibrantColor = vibrantDarkColor;
}
if (vibrantColor != Color.TRANSPARENT && vibrantDarkColor == Color.TRANSPARENT) {
vibrantDarkColor = vibrantColor;
}
synchronized (this) {
mColorsLoaded = true;
mVibrantColor = vibrantColor;
mVibrantDarkColor = vibrantDarkColor;
}
}
}
...@@ -34,6 +34,7 @@ import junit.framework.Assert; ...@@ -34,6 +34,7 @@ import junit.framework.Assert;
import com.cyanogenmod.eleven.R; import com.cyanogenmod.eleven.R;
import com.cyanogenmod.eleven.cache.ImageWorker.ImageType; import com.cyanogenmod.eleven.cache.ImageWorker.ImageType;
import com.cyanogenmod.eleven.utils.BitmapWithColors;
import com.cyanogenmod.eleven.utils.MusicUtils; import com.cyanogenmod.eleven.utils.MusicUtils;
/** /**
...@@ -48,6 +49,7 @@ public class LetterTileDrawable extends Drawable { ...@@ -48,6 +49,7 @@ public class LetterTileDrawable extends Drawable {
/** Letter tile */ /** Letter tile */
private static TypedArray sColors; private static TypedArray sColors;
private static TypedArray sVibrantDarkColors;
private static int sDefaultColor; private static int sDefaultColor;
private static int sTileFontColor; private static int sTileFontColor;
private static float sLetterToTileRatio; private static float sLetterToTileRatio;
...@@ -75,6 +77,7 @@ public class LetterTileDrawable extends Drawable { ...@@ -75,6 +77,7 @@ public class LetterTileDrawable extends Drawable {
private static synchronized void initializeStaticVariables(final Resources res) { private static synchronized void initializeStaticVariables(final Resources res) {
if (sColors == null) { if (sColors == null) {
sColors = res.obtainTypedArray(R.array.letter_tile_colors); sColors = res.obtainTypedArray(R.array.letter_tile_colors);
sVibrantDarkColors = res.obtainTypedArray(R.array.letter_tile_vibrant_dark_colors);
sDefaultColor = res.getColor(R.color.letter_tile_default_color); sDefaultColor = res.getColor(R.color.letter_tile_default_color);
sTileFontColor = res.getColor(R.color.letter_tile_font_color); sTileFontColor = res.getColor(R.color.letter_tile_font_color);
sLetterToTileRatio = res.getFraction(R.dimen.letter_to_tile_ratio, 1, 1); sLetterToTileRatio = res.getFraction(R.dimen.letter_to_tile_ratio, 1, 1);
...@@ -172,18 +175,39 @@ public class LetterTileDrawable extends Drawable { ...@@ -172,18 +175,39 @@ public class LetterTileDrawable extends Drawable {
return pickColor(mIdentifier); return pickColor(mIdentifier);
} }
/**
* @return the corresponding index in the color palette based on the identifier
*/
private static int getColorIndex(final String identifier) {
if (TextUtils.isEmpty(identifier)) {
return -1;
}
return Math.abs(identifier.hashCode()) % sColors.length();
}
/** /**
* Returns a deterministic color based on the provided contact identifier string. * Returns a deterministic color based on the provided contact identifier string.
*/ */
private static int pickColor(final String identifier) { private static int pickColor(final String identifier) {
if (TextUtils.isEmpty(identifier)) { final int idx = getColorIndex(identifier);
if (idx == -1) {
return sDefaultColor; return sDefaultColor;
} }
// String.hashCode() implementation is not supposed to change across java versions, so
// this should guarantee the same email address always maps to the same color. return sColors.getColor(idx, sDefaultColor);
// The email should already have been normalized by the ContactRequest. }
final int color = Math.abs(identifier.hashCode()) % sColors.length();
return sColors.getColor(color, sDefaultColor); /**
* Returns the vibrant matching color based on the provided contact identifier string.
*/
private static int pickVibrantDarkColor(final String identifier) {
final int idx = getColorIndex(identifier);
if (idx == -1) {
return sDefaultColor;
}
return sVibrantDarkColors.getColor(idx, sDefaultColor);
} }
/** /**
...@@ -309,8 +333,8 @@ public class LetterTileDrawable extends Drawable { ...@@ -309,8 +333,8 @@ public class LetterTileDrawable extends Drawable {
* @param smallArtwork true if you want to draw a smaller version of the default bitmap for * @param smallArtwork true if you want to draw a smaller version of the default bitmap for
* perf/memory reasons * perf/memory reasons
*/ */
public static Bitmap createDefaultBitmap(Context context, String identifier, ImageType type, public static BitmapWithColors createDefaultBitmap(Context context, String identifier,
boolean isCircle, boolean smallArtwork) { ImageType type, boolean isCircle, boolean smallArtwork) {
initializeStaticVariables(context.getResources()); initializeStaticVariables(context.getResources());
identifier = MusicUtils.getTrimmedName(identifier); identifier = MusicUtils.getTrimmedName(identifier);
...@@ -324,8 +348,11 @@ public class LetterTileDrawable extends Drawable { ...@@ -324,8 +348,11 @@ public class LetterTileDrawable extends Drawable {
defaultBitmap.getHeight(), defaultBitmap.getConfig()); defaultBitmap.getHeight(), defaultBitmap.getConfig());
Canvas canvas = new Canvas(createdBitmap); Canvas canvas = new Canvas(createdBitmap);
int color = pickColor(identifier);
int vibrantDarkColor = pickVibrantDarkColor(identifier);
Paint paint = new Paint(); Paint paint = new Paint();
paint.setColor(pickColor(identifier)); paint.setColor(color);
final int minDimension = Math.min(bounds.width(), bounds.height()); final int minDimension = Math.min(bounds.width(), bounds.height());
...@@ -339,6 +366,6 @@ public class LetterTileDrawable extends Drawable { ...@@ -339,6 +366,6 @@ public class LetterTileDrawable extends Drawable {
drawBitmap(defaultBitmap, defaultBitmap.getWidth(), defaultBitmap.getHeight(), canvas, drawBitmap(defaultBitmap, defaultBitmap.getWidth(), defaultBitmap.getHeight(), canvas,
bounds, 1, 0, paint); bounds, 1, 0, paint);
return createdBitmap; return new BitmapWithColors(createdBitmap, color, vibrantDarkColor);
} }
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment