OSDN Git Service

Eleven: lots of ui tweaks (fonts, padding, grid layout) and cancel tasks smarter
[android-x86/packages-apps-Eleven.git] / src / com / cyngn / eleven / loaders / NowPlayingCursor.java
1
2 package com.cyngn.eleven.loaders;
3
4 import static com.cyngn.eleven.utils.MusicUtils.mService;
5
6 import android.annotation.SuppressLint;
7 import android.content.Context;
8 import android.database.AbstractCursor;
9 import android.database.Cursor;
10 import android.os.RemoteException;
11 import android.provider.BaseColumns;
12 import android.provider.MediaStore;
13 import android.provider.MediaStore.Audio.AudioColumns;
14
15 import com.cyngn.eleven.utils.ApolloUtils;
16 import com.cyngn.eleven.utils.MusicUtils;
17
18 import java.util.Arrays;
19
20 /**
21  * A custom {@link Cursor} used to return the queue and allow for easy dragging
22  * and dropping of the items in it.
23  */
24 @SuppressLint("NewApi")
25 public class NowPlayingCursor extends AbstractCursor {
26
27     private static final String[] PROJECTION = new String[] {
28             /* 0 */
29             BaseColumns._ID,
30             /* 1 */
31             AudioColumns.TITLE,
32             /* 2 */
33             AudioColumns.ARTIST,
34             /* 3 */
35             AudioColumns.ALBUM_ID,
36             /* 4 */
37             AudioColumns.ALBUM,
38             /* 5 */
39             AudioColumns.DURATION,
40             /* 6 */
41             AudioColumns.YEAR,
42     };
43
44     private final Context mContext;
45
46     private long[] mNowPlaying;
47
48     private long[] mCursorIndexes;
49
50     private int mSize;
51
52     private int mCurPos;
53
54     private Cursor mQueueCursor;
55
56     /**
57      * Constructor of <code>NowPlayingCursor</code>
58      * 
59      * @param context The {@link Context} to use
60      */
61     public NowPlayingCursor(final Context context) {
62         mContext = context;
63         makeNowPlayingCursor();
64     }
65
66     /**
67      * {@inheritDoc}
68      */
69     @Override
70     public int getCount() {
71         return mSize;
72     }
73
74     /**
75      * {@inheritDoc}
76      */
77     @Override
78     public boolean onMove(final int oldPosition, final int newPosition) {
79         if (oldPosition == newPosition) {
80             return true;
81         }
82
83         if (mNowPlaying == null || mCursorIndexes == null || newPosition >= mNowPlaying.length) {
84             return false;
85         }
86
87         final long id = mNowPlaying[newPosition];
88         final int cursorIndex = Arrays.binarySearch(mCursorIndexes, id);
89         mQueueCursor.moveToPosition(cursorIndex);
90         mCurPos = newPosition;
91         return true;
92     }
93
94     /**
95      * {@inheritDoc}
96      */
97     @Override
98     public String getString(final int column) {
99         try {
100             return mQueueCursor.getString(column);
101         } catch (final Exception ignored) {
102             onChange(true);
103             return "";
104         }
105     }
106
107     /**
108      * {@inheritDoc}
109      */
110     @Override
111     public short getShort(final int column) {
112         return mQueueCursor.getShort(column);
113     }
114
115     /**
116      * {@inheritDoc}
117      */
118     @Override
119     public int getInt(final int column) {
120         try {
121             return mQueueCursor.getInt(column);
122         } catch (final Exception ignored) {
123             onChange(true);
124             return 0;
125         }
126     }
127
128     /**
129      * {@inheritDoc}
130      */
131     @Override
132     public long getLong(final int column) {
133         try {
134             return mQueueCursor.getLong(column);
135         } catch (final Exception ignored) {
136             onChange(true);
137             return 0;
138         }
139     }
140
141     /**
142      * {@inheritDoc}
143      */
144     @Override
145     public float getFloat(final int column) {
146         return mQueueCursor.getFloat(column);
147     }
148
149     /**
150      * {@inheritDoc}
151      */
152     @Override
153     public double getDouble(final int column) {
154         return mQueueCursor.getDouble(column);
155     }
156
157     /**
158      * {@inheritDoc}
159      */
160     @Override
161     public int getType(final int column) {
162         return mQueueCursor.getType(column);
163     }
164
165     /**
166      * {@inheritDoc}
167      */
168     @Override
169     public boolean isNull(final int column) {
170         return mQueueCursor.isNull(column);
171     }
172
173     /**
174      * {@inheritDoc}
175      */
176     @Override
177     public String[] getColumnNames() {
178         return PROJECTION;
179     }
180
181     /**
182      * {@inheritDoc}
183      */
184     @SuppressWarnings("deprecation")
185     @Override
186     public void deactivate() {
187         if (mQueueCursor != null) {
188             mQueueCursor.deactivate();
189         }
190     }
191
192     /**
193      * {@inheritDoc}
194      */
195     @Override
196     public boolean requery() {
197         makeNowPlayingCursor();
198         return true;
199     }
200
201     /**
202      * {@inheritDoc}
203      */
204     @Override
205     public void close() {
206         try {
207             if (mQueueCursor != null) {
208                 mQueueCursor.close();
209                 mQueueCursor = null;
210             }
211         } catch (final Exception close) {
212         }
213         super.close();
214     };
215
216     /**
217      * Actually makes the queue
218      */
219     private void makeNowPlayingCursor() {
220         mQueueCursor = null;
221         mNowPlaying = MusicUtils.getQueue();
222         mSize = mNowPlaying.length;
223         if (mSize == 0) {
224             return;
225         }
226
227         final StringBuilder selection = new StringBuilder();
228         selection.append(MediaStore.Audio.Media._ID + " IN (");
229         for (int i = 0; i < mSize; i++) {
230             selection.append(mNowPlaying[i]);
231             if (i < mSize - 1) {
232                 selection.append(",");
233             }
234         }
235         selection.append(")");
236
237         mQueueCursor = mContext.getContentResolver().query(
238                 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, PROJECTION, selection.toString(),
239                 null, MediaStore.Audio.Media._ID);
240
241         if (mQueueCursor == null) {
242             mSize = 0;
243             return;
244         }
245
246         final int playlistSize = mQueueCursor.getCount();
247         mCursorIndexes = new long[playlistSize];
248         mQueueCursor.moveToFirst();
249         final int columnIndex = mQueueCursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID);
250         for (int i = 0; i < playlistSize; i++) {
251             mCursorIndexes[i] = mQueueCursor.getLong(columnIndex);
252             mQueueCursor.moveToNext();
253         }
254         mQueueCursor.moveToFirst();
255         mCurPos = -1;
256
257         int removed = 0;
258         for (int i = mNowPlaying.length - 1; i >= 0; i--) {
259             final long trackId = mNowPlaying[i];
260             final int cursorIndex = Arrays.binarySearch(mCursorIndexes, trackId);
261             if (cursorIndex < 0) {
262                 removed += MusicUtils.removeTrack(trackId);
263             }
264         }
265         if (removed > 0) {
266             mNowPlaying = MusicUtils.getQueue();
267             mSize = mNowPlaying.length;
268             if (mSize == 0) {
269                 mCursorIndexes = null;
270                 return;
271             }
272         }
273     }
274
275     /**
276      * @param which The position to remove
277      * @return True if sucessfull, false othersise
278      */
279     public boolean removeItem(final int which) {
280         try {
281             if (mService.removeTracks(which, which) == 0) {
282                 return false;
283             }
284             int i = which;
285             mSize--;
286             while (i < mSize) {
287                 mNowPlaying[i] = mNowPlaying[i + 1];
288                 i++;
289             }
290             onMove(-1, mCurPos);
291         } catch (final RemoteException ignored) {
292         }
293         return true;
294     }
295 }