OSDN Git Service

48a792eb61c83e66df5e9fc4202e107ee692ed75
[android-x86/packages-apps-Eleven.git] / src / com / cyanogenmod / eleven / provider / PlaylistArtworkStore.java
1 /*
2 * Copyright (C) 2014 The CyanogenMod Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package com.cyanogenmod.eleven.provider;
17
18 import android.content.ContentValues;
19 import android.content.Context;
20 import android.database.Cursor;
21 import android.database.sqlite.SQLiteDatabase;
22
23 import com.cyanogenmod.eleven.utils.MusicUtils;
24
25 /**
26  * This db stores the details to generate the playlist artwork including when it was
27  * last updated and the # of songs in the playlist when it last updated
28  */
29 public class PlaylistArtworkStore {
30     private static final long ONE_DAY_IN_MS = 1000 * 60 * 60 * 24;
31
32     private static PlaylistArtworkStore sInstance = null;
33
34     private MusicDB mMusicDatabase = null;
35
36     /**
37      * @param context The {@link android.content.Context} to use
38      * @return A new instance of this class.
39      */
40     public static final synchronized PlaylistArtworkStore getInstance(final Context context) {
41         if (sInstance == null) {
42             sInstance = new PlaylistArtworkStore(context.getApplicationContext());
43         }
44         return sInstance;
45     }
46
47     /**
48      * @param playlistId playlist identifier
49      * @return the key used for the imagae cache for the cover art
50      */
51     public static final String getCoverCacheKey(final long playlistId) {
52         return "playlist_cover_" + playlistId;
53     }
54
55     /**
56      * @param playlistId playlist identifier
57      * @return the key used for the imagae cache for the top artist image
58      */
59     public static final String getArtistCacheKey(final long playlistId) {
60         return "playlist_artist_" + playlistId;
61     }
62
63     private final Context mContext;
64
65     /**
66      * Constructor of <code>RecentStore</code>
67      *
68      * @param context The {@link android.content.Context} to use
69      */
70     public PlaylistArtworkStore(final Context context) {
71         mMusicDatabase = MusicDB.getInstance(context);
72
73         mContext = context;
74     }
75
76     public void onCreate(final SQLiteDatabase db) {
77         // create the table
78         String builder = "CREATE TABLE IF NOT EXISTS " +
79                 PlaylistArtworkStoreColumns.NAME +
80                 "(" +
81                 PlaylistArtworkStoreColumns.ID +
82                 " INT UNIQUE," +
83                 PlaylistArtworkStoreColumns.LAST_UPDATE_ARTIST +
84                 " LONG DEFAULT 0," +
85                 PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_ARTIST +
86                 " INT DEFAULT 0," +
87                 PlaylistArtworkStoreColumns.LAST_UPDATE_COVER +
88                 " LONG DEFAULT 0," +
89                 PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_COVER +
90                 " INT DEFAULT 0);";
91
92         db.execSQL(builder);
93     }
94
95     public void onUpgrade(final SQLiteDatabase db, final int oldVersion, final int newVersion) {
96         // No upgrade path needed yet
97     }
98
99     public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
100         // If we ever have downgrade, drop the table to be safe
101         db.execSQL("DROP TABLE IF EXISTS " + PlaylistArtworkStoreColumns.NAME);
102         onCreate(db);
103     }
104
105     /**
106      * @param playlistId playlist identifier
107      * @return true if the artist artwork should be updated based on time since last update and
108      * whether the # of songs for the playlist has changed
109      */
110     public boolean needsArtistArtUpdate(final long playlistId) {
111         return needsUpdate(playlistId, PlaylistArtworkStoreColumns.LAST_UPDATE_ARTIST,
112                 PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_ARTIST);
113     }
114
115     /**
116      * @param playlistId playlist identifier
117      * @return true if the cover artwork should be updated based on time since last update and
118      * whether the # of songs for the playlist has changed
119      */
120     public boolean needsCoverArtUpdate(final long playlistId) {
121         return needsUpdate(playlistId, PlaylistArtworkStoreColumns.LAST_UPDATE_COVER,
122                 PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_COVER);
123     }
124
125     /**
126      * Updates the time and the # of songs in the db for the artist section of the table
127      * @param playlistId playlist identifier
128      */
129     public void updateArtistArt(final long playlistId) {
130         updateOrInsertTime(playlistId, PlaylistArtworkStoreColumns.LAST_UPDATE_ARTIST,
131                 PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_ARTIST);
132     }
133
134     /**
135      * Updates the time and the # of songs in the db for the cover art of the table
136      * @param playlistId playlist identifier
137      */
138     public void updateCoverArt(final long playlistId) {
139         updateOrInsertTime(playlistId, PlaylistArtworkStoreColumns.LAST_UPDATE_COVER,
140                 PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_COVER);
141     }
142
143     /**
144      * Internal function to update the entry for the columns passed in
145      * @param playlistId playlist identifier
146      * @param columnName the column to update to the current time
147      * @param countColumnName the column to set the # of songs to based on the playlist
148      */
149     private void updateOrInsertTime(final long playlistId, final String columnName, final String countColumnName) {
150         SQLiteDatabase database = mMusicDatabase.getWritableDatabase();
151
152         database.beginTransaction();
153
154         // gets the existing values for the entry if it exists
155         ContentValues values = getExistingContentValues(playlistId);
156         boolean existingEntry = values.size() > 0;
157         // update the values
158         values.put(PlaylistArtworkStoreColumns.ID, playlistId);
159         values.put(columnName, System.currentTimeMillis());
160         values.put(countColumnName, MusicUtils.getSongCountForPlaylist(mContext, playlistId));
161
162         // if it is an existing entry, update, otherwise insert
163         if (existingEntry) {
164             database.update(PlaylistArtworkStoreColumns.NAME, values,
165                     PlaylistArtworkStoreColumns.ID + "=" + playlistId, null);
166         } else {
167             database.insert(PlaylistArtworkStoreColumns.NAME, null, values);
168         }
169
170         database.setTransactionSuccessful();
171         database.endTransaction();
172     }
173
174     /**
175      * Internal function to get the existing values for a playlist entry
176      * @param playlistId playlist identifier
177      * @return the content values
178      */
179     private ContentValues getExistingContentValues(final long playlistId) {
180         ContentValues values = new ContentValues(4);
181         Cursor c = getEntry(playlistId);
182         if (c != null && c.moveToFirst()) {
183             values.put(PlaylistArtworkStoreColumns.ID, c.getLong(0));
184             values.put(PlaylistArtworkStoreColumns.LAST_UPDATE_ARTIST, c.getLong(1));
185             values.put(PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_ARTIST, c.getInt(2));
186             values.put(PlaylistArtworkStoreColumns.LAST_UPDATE_COVER, c.getLong(3));
187             values.put(PlaylistArtworkStoreColumns.NUM_SONGS_LAST_UPDATE_COVER, c.getInt(4));
188             c.close();
189             c = null;
190         }
191
192         return values;
193     }
194
195     /**
196      * Internal function to return whether the columns show that this needs an update
197      * @param playlistId playlist identifier
198      * @param columnName the column to inspect
199      * @param countColumnName the column count to inspect
200      * @return
201      */
202     private boolean needsUpdate(final long playlistId, final String columnName, final String countColumnName) {
203         // get the entry
204         Cursor c = getEntry(playlistId);
205
206         if (c != null && c.moveToFirst()) {
207             final long lastUpdate = c.getLong(c.getColumnIndex(columnName));
208             final long msSinceEpoch = System.currentTimeMillis();
209             final int songCount = MusicUtils.getSongCountForPlaylist(mContext, playlistId);
210             final int lastUpdatedSongCount = c.getInt(c.getColumnIndex(countColumnName));
211
212             c.close();
213             c = null;
214
215             // if the elapsed time since our last update is less than a day and the
216             // number of songs in the playlist hasn't changed, then don't update
217             if (msSinceEpoch - lastUpdate < ONE_DAY_IN_MS &&
218                     songCount == lastUpdatedSongCount) {
219                 return false;
220             }
221         }
222
223         return true;
224     }
225
226     /**
227      * Internal function to get the cursor entry for the playlist
228      * @param playlistId playlist identifier
229      * @return cursor
230      */
231     private Cursor getEntry(final long playlistId) {
232         SQLiteDatabase db = mMusicDatabase.getReadableDatabase();
233         return db.query(PlaylistArtworkStoreColumns.NAME, null,
234                 PlaylistArtworkStoreColumns.ID + "=" + playlistId, null, null, null, null);
235     }
236
237     public interface PlaylistArtworkStoreColumns {
238         /* Table name */
239         public static final String NAME = "playlist_details";
240
241         /* Playlist ID column */
242         public static final String ID = "playlistid";
243
244         /* When the top artist was last updated */
245         public static final String LAST_UPDATE_ARTIST = "last_updated_artist";
246
247         /* The number of songs when we last updated the artist */
248         public static final String NUM_SONGS_LAST_UPDATE_ARTIST = "num_songs_last_updated_artist";
249
250         /* When the cover art was last updated */
251         public static final String LAST_UPDATE_COVER = "last_updated_cover";
252
253         /* The number of songs when we last updated the cover */
254         public static final String NUM_SONGS_LAST_UPDATE_COVER = "num_songs_last_updated_cover";
255     }
256 }