2 package org.lineageos.eleven.loaders;
4 import static org.lineageos.eleven.utils.MusicUtils.mService;
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;
15 import org.lineageos.eleven.utils.MusicUtils;
17 import java.util.Arrays;
20 * A custom {@link Cursor} used to return the queue and allow for easy dragging
21 * and dropping of the items in it.
23 @SuppressLint("NewApi")
24 public class NowPlayingCursor extends AbstractCursor {
26 private static final String[] PROJECTION = new String[] {
34 AudioColumns.ALBUM_ID,
38 AudioColumns.DURATION,
43 private final Context mContext;
45 private long[] mNowPlaying;
47 private long[] mCursorIndexes;
53 private Cursor mQueueCursor;
56 * Constructor of <code>NowPlayingCursor</code>
58 * @param context The {@link Context} to use
60 public NowPlayingCursor(final Context context) {
62 makeNowPlayingCursor();
69 public int getCount() {
77 public boolean onMove(final int oldPosition, final int newPosition) {
78 if (oldPosition == newPosition) {
82 if (mNowPlaying == null || mCursorIndexes == null || newPosition >= mNowPlaying.length) {
86 final long id = mNowPlaying[newPosition];
87 final int cursorIndex = Arrays.binarySearch(mCursorIndexes, id);
88 mQueueCursor.moveToPosition(cursorIndex);
89 mCurPos = newPosition;
97 public String getString(final int column) {
99 return mQueueCursor.getString(column);
100 } catch (final Exception ignored) {
110 public short getShort(final int column) {
111 return mQueueCursor.getShort(column);
118 public int getInt(final int column) {
120 return mQueueCursor.getInt(column);
121 } catch (final Exception ignored) {
131 public long getLong(final int column) {
133 return mQueueCursor.getLong(column);
134 } catch (final Exception ignored) {
144 public float getFloat(final int column) {
145 return mQueueCursor.getFloat(column);
152 public double getDouble(final int column) {
153 return mQueueCursor.getDouble(column);
160 public int getType(final int column) {
161 return mQueueCursor.getType(column);
168 public boolean isNull(final int column) {
169 return mQueueCursor.isNull(column);
176 public String[] getColumnNames() {
183 @SuppressWarnings("deprecation")
185 public void deactivate() {
186 if (mQueueCursor != null) {
187 mQueueCursor.deactivate();
195 public boolean requery() {
196 makeNowPlayingCursor();
204 public void close() {
206 if (mQueueCursor != null) {
207 mQueueCursor.close();
210 } catch (final Exception close) {
216 * Actually makes the queue
218 private void makeNowPlayingCursor() {
220 mNowPlaying = MusicUtils.getQueue();
221 mSize = mNowPlaying.length;
226 final StringBuilder selection = new StringBuilder();
227 selection.append(MediaStore.Audio.Media._ID + " IN (");
228 for (int i = 0; i < mSize; i++) {
229 selection.append(mNowPlaying[i]);
231 selection.append(",");
234 selection.append(")");
236 mQueueCursor = mContext.getContentResolver().query(
237 MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, PROJECTION, selection.toString(),
238 null, MediaStore.Audio.Media._ID);
240 if (mQueueCursor == null) {
245 final int playlistSize = mQueueCursor.getCount();
246 mCursorIndexes = new long[playlistSize];
247 mQueueCursor.moveToFirst();
248 final int columnIndex = mQueueCursor.getColumnIndexOrThrow(MediaStore.Audio.Media._ID);
249 for (int i = 0; i < playlistSize; i++) {
250 mCursorIndexes[i] = mQueueCursor.getLong(columnIndex);
251 mQueueCursor.moveToNext();
253 mQueueCursor.moveToFirst();
257 for (int i = mNowPlaying.length - 1; i >= 0; i--) {
258 final long trackId = mNowPlaying[i];
259 final int cursorIndex = Arrays.binarySearch(mCursorIndexes, trackId);
260 if (cursorIndex < 0) {
261 removed += MusicUtils.removeTrack(trackId);
265 mNowPlaying = MusicUtils.getQueue();
266 mSize = mNowPlaying.length;
268 mCursorIndexes = null;
275 * @param which The position to remove
276 * @return True if sucessfull, false othersise
278 public boolean removeItem(final int which) {
280 if (mService.removeTracks(which, which) == 0) {
286 mNowPlaying[i] = mNowPlaying[i + 1];
290 } catch (final RemoteException ignored) {