summaryrefslogtreecommitdiffstats
path: root/src/com/cyngn/eleven/provider/PlaylistArtworkStore.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/cyngn/eleven/provider/PlaylistArtworkStore.java')
-rw-r--r--src/com/cyngn/eleven/provider/PlaylistArtworkStore.java258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/com/cyngn/eleven/provider/PlaylistArtworkStore.java b/src/com/cyngn/eleven/provider/PlaylistArtworkStore.java
new file mode 100644
index 0000000..2751a1e
--- /dev/null
+++ b/src/com/cyngn/eleven/provider/PlaylistArtworkStore.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2014 Cyanogen, Inc.
+ */
+package com.cyngn.eleven.provider;
+
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+
+import com.cyngn.eleven.utils.MusicUtils;
+
+/**
+ * This db stores the details to generate the playlist artwork including when it was
+ * last updated and the # of songs in the playlist when it last updated
+ */
+public class PlaylistArtworkStore extends SQLiteOpenHelper {
+ /* Version constant to increment when the database should be rebuilt */
+ private static final int VERSION = 1;
+
+ private static final long ONE_DAY_IN_MS = 1000 * 60 * 60 * 24;
+
+ /* Name of database file */
+ public static final String DATABASENAME = "playlistdetail.db";
+
+ private static PlaylistArtworkStore sInstance = null;
+
+ /**
+ * @param context The {@link android.content.Context} to use
+ * @return A new instance of this class.
+ */
+ public static final synchronized PlaylistArtworkStore getInstance(final Context context) {
+ if (sInstance == null) {
+ sInstance = new PlaylistArtworkStore(context.getApplicationContext());
+ }
+ return sInstance;
+ }
+
+ /**
+ * @param playlistId playlist identifier
+ * @return the key used for the imagae cache for the cover art
+ */
+ public static final String getCoverCacheKey(final long playlistId) {
+ return "playlist_cover_" + playlistId;
+ }
+
+ /**
+ * @param playlistId playlist identifier
+ * @return the key used for the imagae cache for the top artist image
+ */
+ public static final String getArtistCacheKey(final long playlistId) {
+ return "playlist_artist_" + playlistId;
+ }
+
+ private final Context mContext;
+
+ /**
+ * Constructor of <code>RecentStore</code>
+ *
+ * @param context The {@link android.content.Context} to use
+ */
+ public PlaylistArtworkStore(final Context context) {
+ super(context, DATABASENAME, null, VERSION);
+
+ mContext = context;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onCreate(final SQLiteDatabase db) {
+ // create the table
+ StringBuilder builder = new StringBuilder();
+ builder.append("CREATE TABLE IF NOT EXISTS ");
+ builder.append(PlaylistArtworkStoreColumns.NAME);
+ builder.append("(");
+ builder.append(PlaylistArtworkStoreColumns.ID);
+ builder.append(" INT UNIQUE,");
+
+ builder.append(PlaylistArtworkStoreColumns.LAST_UPDATE_ARTIST);
+ builder.append(" LONG DEFAULT 0,");
+
+ builder.append(PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_ARTIST);
+ builder.append(" INT DEFAULT 0,");
+
+ builder.append(PlaylistArtworkStoreColumns.LAST_UPDATE_COVER);
+ builder.append(" LONG DEFAULT 0,");
+
+ builder.append(PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_COVER);
+ builder.append(" INT DEFAULT 0);");
+
+ db.execSQL(builder.toString());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
+ // If we ever have upgrade, this code should be changed to handle this more gracefully
+ db.execSQL("DROP TABLE IF EXISTS " + PlaylistArtworkStoreColumns.NAME);
+ onCreate(db);
+ }
+
+ /**
+ * @param playlistId playlist identifier
+ * @return true if the artist artwork should be updated based on time since last update and
+ * whether the # of songs for the playlist has changed
+ */
+ public boolean needsArtistArtUpdate(final long playlistId) {
+ return needsUpdate(playlistId, PlaylistArtworkStoreColumns.LAST_UPDATE_ARTIST,
+ PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_ARTIST);
+ }
+
+ /**
+ * @param playlistId playlist identifier
+ * @return true if the cover artwork should be updated based on time since last update and
+ * whether the # of songs for the playlist has changed
+ */
+ public boolean needsCoverArtUpdate(final long playlistId) {
+ return needsUpdate(playlistId, PlaylistArtworkStoreColumns.LAST_UPDATE_COVER,
+ PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_COVER);
+ }
+
+ /**
+ * Updates the time and the # of songs in the db for the artist section of the table
+ * @param playlistId playlist identifier
+ */
+ public void updateArtistArt(final long playlistId) {
+ updateOrInsertTime(playlistId, PlaylistArtworkStoreColumns.LAST_UPDATE_ARTIST,
+ PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_ARTIST);
+ }
+
+ /**
+ * Updates the time and the # of songs in the db for the cover art of the table
+ * @param playlistId playlist identifier
+ */
+ public void updateCoverArt(final long playlistId) {
+ updateOrInsertTime(playlistId, PlaylistArtworkStoreColumns.LAST_UPDATE_COVER,
+ PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_COVER);
+ }
+
+ /**
+ * Internal function to update the entry for the columns passed in
+ * @param playlistId playlist identifier
+ * @param columnName the column to update to the current time
+ * @param countColumnName the column to set the # of songs to based on the playlist
+ */
+ private void updateOrInsertTime(final long playlistId, final String columnName, final String countColumnName) {
+ SQLiteDatabase database = getWritableDatabase();
+
+ database.beginTransaction();
+
+ // gets the existing values for the entry if it exists
+ ContentValues values = getExistingContentValues(playlistId);
+ boolean existingEntry = values.size() > 0;
+ // update the values
+ values.put(PlaylistArtworkStoreColumns.ID, playlistId);
+ values.put(columnName, System.currentTimeMillis());
+ values.put(countColumnName, MusicUtils.getSongCountForPlaylist(mContext, playlistId));
+
+ // if it is an existing entry, update, otherwise insert
+ if (existingEntry) {
+ database.update(PlaylistArtworkStoreColumns.NAME, values,
+ PlaylistArtworkStoreColumns.ID + "=" + playlistId, null);
+ } else {
+ database.insert(PlaylistArtworkStoreColumns.NAME, null, values);
+ }
+
+ database.setTransactionSuccessful();
+ database.endTransaction();
+ }
+
+ /**
+ * Internal function to get the existing values for a playlist entry
+ * @param playlistId playlist identifier
+ * @return the content values
+ */
+ private ContentValues getExistingContentValues(final long playlistId) {
+ ContentValues values = new ContentValues(4);
+ Cursor c = getEntry(playlistId);
+ if (c != null && c.moveToFirst()) {
+ values.put(PlaylistArtworkStoreColumns.ID, c.getLong(0));
+ values.put(PlaylistArtworkStoreColumns.LAST_UPDATE_ARTIST, c.getLong(1));
+ values.put(PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_ARTIST, c.getInt(2));
+ values.put(PlaylistArtworkStoreColumns.LAST_UPDATE_COVER, c.getLong(3));
+ values.put(PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_COVER, c.getInt(4));
+ c.close();
+ c = null;
+ }
+
+ return values;
+ }
+
+ /**
+ * Internal function to return whether the columns show that this needs an update
+ * @param playlistId playlist identifier
+ * @param columnName the column to inspect
+ * @param countColumnName the column count to inspect
+ * @return
+ */
+ private boolean needsUpdate(final long playlistId, final String columnName, final String countColumnName) {
+ // get the entry
+ Cursor c = getEntry(playlistId);
+
+ if (c != null && c.moveToFirst()) {
+ final long lastUpdate = c.getLong(c.getColumnIndex(columnName));
+ final long msSinceEpoch = System.currentTimeMillis();
+ final int songCount = MusicUtils.getSongCountForPlaylist(mContext, playlistId);
+ final int lastUpdatedSongCount = c.getInt(c.getColumnIndex(countColumnName));
+
+ c.close();
+ c = null;
+
+ // if the elapsed time since our last update is less than a day and the
+ // number of songs in the playlist hasn't changed, then don't update
+ if (msSinceEpoch - lastUpdate < ONE_DAY_IN_MS &&
+ songCount == lastUpdatedSongCount) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Internal function to get the cursor entry for the playlist
+ * @param playlistId playlist identifier
+ * @return cursor
+ */
+ private Cursor getEntry(final long playlistId) {
+ SQLiteDatabase db = getReadableDatabase();
+ return db.query(PlaylistArtworkStoreColumns.NAME, null,
+ PlaylistArtworkStoreColumns.ID + "=" + playlistId, null, null, null, null);
+ }
+
+ public interface PlaylistArtworkStoreColumns {
+ /* Table name */
+ public static final String NAME = "playlist_details";
+
+ /* Playlist ID column */
+ public static final String ID = "playlistid";
+
+ /* When the top artist was last updated */
+ public static final String LAST_UPDATE_ARTIST = "last_updated_artist";
+
+ /* The number of songs when we last updated the artist */
+ public static final String NUM_SONGS_LAST_UPDATE_ARTIST = "num_songs_last_updated_artist";
+
+ /* When the cover art was last updated */
+ public static final String LAST_UPDATE_COVER = "last_updated_cover";
+
+ /* The number of songs when we last updated the cover */
+ public static final String NUM_SONGS_LAST_UPDATE_COVER = "num_songs_last_updated_cover";
+ }
+}