Refactor SongTimeline.addSongs() so it receives arguments from QueryTask
This commit is contained in:
parent
3774d386e3
commit
64d716571f
@ -435,10 +435,10 @@ public class LibraryActivity
|
||||
all = true;
|
||||
}
|
||||
}
|
||||
mode = modeForAction[mode];
|
||||
|
||||
QueryTask query = buildQueryFromIntent(intent, false, all);
|
||||
PlaybackService.get(this).addSongs(mode, query, intent.getIntExtra("type", MediaUtils.TYPE_INVALID));
|
||||
query.mode = modeForAction[mode];
|
||||
PlaybackService.get(this).addSongs(query);
|
||||
|
||||
mLastActedId = id;
|
||||
|
||||
@ -650,7 +650,7 @@ public class LibraryActivity
|
||||
query = MediaUtils.buildFileQuery(intent.getStringExtra("file"), projection);
|
||||
} else if (all || id == LibraryAdapter.HEADER_ID) {
|
||||
query = ((MediaAdapter)mPagerAdapter.mAdapters[type]).buildSongQuery(projection);
|
||||
query.setExtra(id);
|
||||
query.data = id;
|
||||
} else {
|
||||
query = MediaUtils.buildQuery(type, id, projection, null);
|
||||
}
|
||||
|
@ -333,11 +333,12 @@ public class MediaAdapter
|
||||
public QueryTask buildSongQuery(String[] projection)
|
||||
{
|
||||
QueryTask query = buildQuery(projection, true);
|
||||
query.type = mType;
|
||||
if (mType != MediaUtils.TYPE_SONG) {
|
||||
query.setUri(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
|
||||
query.uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
// Would be better to match the sort order in the adapter. This
|
||||
// is likely to require significantly more work though.
|
||||
query.setSortOrder(mSongSort);
|
||||
query.sortOrder = mSongSort;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
@ -151,7 +151,9 @@ public class MediaUtils {
|
||||
selection.append(select);
|
||||
}
|
||||
|
||||
return new QueryTask(media, projection, selection.toString(), null, DEFAULT_SORT);
|
||||
QueryTask result = new QueryTask(media, projection, selection.toString(), null, DEFAULT_SORT);
|
||||
result.type = type;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,7 +169,10 @@ public class MediaUtils {
|
||||
{
|
||||
Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", id);
|
||||
String sort = MediaStore.Audio.Playlists.Members.PLAY_ORDER;
|
||||
return new QueryTask(uri, projection, selection, null, sort);
|
||||
QueryTask result = new QueryTask(uri, projection, selection, null, sort);
|
||||
result.type = TYPE_PLAYLIST;
|
||||
result.id = id;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -183,7 +188,9 @@ public class MediaUtils {
|
||||
public static QueryTask buildGenreQuery(long id, String[] projection, String selection, String[] selectionArgs, String sort)
|
||||
{
|
||||
Uri uri = MediaStore.Audio.Genres.Members.getContentUri("external", id);
|
||||
return new QueryTask(uri, projection, selection, selectionArgs, sort);
|
||||
QueryTask result = new QueryTask(uri, projection, selection, selectionArgs, sort);
|
||||
result.type = TYPE_GENRE;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -544,6 +551,8 @@ public class MediaUtils {
|
||||
selection.append("*' AND is_music!=0");
|
||||
|
||||
Uri media = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
return new QueryTask(media, projection, selection.toString(), null, DEFAULT_SORT);
|
||||
QueryTask result = new QueryTask(media, projection, selection.toString(), null, DEFAULT_SORT);
|
||||
result.type = TYPE_FILE;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -89,7 +89,7 @@ public final class PlaybackService extends Service
|
||||
/**
|
||||
* State file version that indicates data order.
|
||||
*/
|
||||
private static final int STATE_VERSION = 5;
|
||||
private static final int STATE_VERSION = 6;
|
||||
|
||||
private static final int NOTIFICATION_ID = 2;
|
||||
|
||||
@ -1199,7 +1199,7 @@ public final class PlaybackService extends Service
|
||||
processSong((Song)message.obj);
|
||||
break;
|
||||
case QUERY:
|
||||
runQuery(message.arg1, (QueryTask)message.obj, message.arg2);
|
||||
runQuery((QueryTask)message.obj);
|
||||
break;
|
||||
case IDLE_TIMEOUT:
|
||||
if ((mState & FLAG_PLAYING) != 0) {
|
||||
@ -1365,25 +1365,15 @@ public final class PlaybackService extends Service
|
||||
* Run the query and add the results to the timeline. Should be called in the
|
||||
* worker thread.
|
||||
*
|
||||
* @param mode How to add songs. Passed to
|
||||
* {@link SongTimeline#addSongs(int, android.database.Cursor, int, long)}
|
||||
* @param query The query to run.
|
||||
* @param jumpTo Passed to
|
||||
* {@link SongTimeline#addSongs(int, android.database.Cursor, int, long)}
|
||||
*/
|
||||
public void runQuery(int mode, QueryTask query, int jumpTo)
|
||||
public void runQuery(QueryTask query)
|
||||
{
|
||||
Cursor cursor = query.runQuery(getContentResolver());
|
||||
if (cursor == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
int count = mTimeline.addSongs(mode, cursor, jumpTo, query.getExtra());
|
||||
cursor.close();
|
||||
int count = mTimeline.addSongs(this, query);
|
||||
|
||||
int text;
|
||||
|
||||
switch (mode) {
|
||||
switch (query.mode) {
|
||||
case SongTimeline.MODE_PLAY:
|
||||
case SongTimeline.MODE_PLAY_POS_FIRST:
|
||||
case SongTimeline.MODE_PLAY_ID_FIRST:
|
||||
@ -1398,7 +1388,7 @@ public final class PlaybackService extends Service
|
||||
text = R.plurals.enqueued;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid add mode: " + mode);
|
||||
throw new IllegalArgumentException("Invalid add mode: " + query.mode);
|
||||
}
|
||||
|
||||
Toast.makeText(this, getResources().getQuantityString(text, count, count), Toast.LENGTH_SHORT).show();
|
||||
@ -1407,15 +1397,11 @@ public final class PlaybackService extends Service
|
||||
/**
|
||||
* Run the query in the background and add the results to the timeline.
|
||||
*
|
||||
* @param mode One of SongTimeline.MODE_*. Tells whether to play the songs
|
||||
* immediately or enqueue them for later.
|
||||
* @param query The query.
|
||||
* @param jumpTo Passed to
|
||||
* {@link SongTimeline#addSongs(int, android.database.Cursor, int, long)}
|
||||
*/
|
||||
public void addSongs(int mode, QueryTask query, int jumpTo)
|
||||
public void addSongs(QueryTask query)
|
||||
{
|
||||
mHandler.sendMessage(mHandler.obtainMessage(QUERY, mode, jumpTo, query));
|
||||
mHandler.sendMessage(mHandler.obtainMessage(QUERY, query));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1450,7 +1436,9 @@ public final class PlaybackService extends Service
|
||||
}
|
||||
|
||||
String selection = "_id!=" + current.id;
|
||||
addSongs(SongTimeline.MODE_PLAY_NEXT, MediaUtils.buildQuery(type, id, Song.FILLED_PROJECTION, selection), 0);
|
||||
QueryTask query = MediaUtils.buildQuery(type, id, Song.FILLED_PROJECTION, selection);
|
||||
query.mode = SongTimeline.MODE_PLAY_NEXT;
|
||||
addSongs(query);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -232,13 +232,16 @@ public class PlaylistActivity extends Activity
|
||||
case LibraryActivity.ACTION_PLAY:
|
||||
case LibraryActivity.ACTION_ENQUEUE: {
|
||||
QueryTask query = MediaUtils.buildMediaQuery(MediaUtils.TYPE_SONG, audioId, Song.FILLED_PROJECTION, null);
|
||||
PlaybackService.get(this).addSongs(MODE_FOR_ACTION[action], query, 0);
|
||||
query.mode = MODE_FOR_ACTION[action];
|
||||
PlaybackService.get(this).addSongs(query);
|
||||
break;
|
||||
}
|
||||
case LibraryActivity.ACTION_PLAY_ALL:
|
||||
case LibraryActivity.ACTION_ENQUEUE_ALL: {
|
||||
QueryTask query = MediaUtils.buildPlaylistQuery(mPlaylistId, Song.FILLED_PLAYLIST_PROJECTION, null);
|
||||
PlaybackService.get(this).addSongs(MODE_FOR_ACTION[action], query, position - mListView.getHeaderViewsCount());
|
||||
query.mode = MODE_FOR_ACTION[action];
|
||||
query.data = position - mListView.getHeaderViewsCount();
|
||||
PlaybackService.get(this).addSongs(query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -30,12 +30,33 @@ import android.net.Uri;
|
||||
* Represents a pending query.
|
||||
*/
|
||||
public class QueryTask {
|
||||
private Uri mUri;
|
||||
private final String[] mProjection;
|
||||
private final String mSelection;
|
||||
private final String[] mSelectionArgs;
|
||||
private String mSortOrder;
|
||||
private long mExtra;
|
||||
public Uri uri;
|
||||
public final String[] projection;
|
||||
public final String selection;
|
||||
public final String[] selectionArgs;
|
||||
public String sortOrder;
|
||||
|
||||
/**
|
||||
* Used for {@link SongTimeline#addSongs(android.content.Context, QueryTask)}.
|
||||
* One of SongTimeline.MODE_*.
|
||||
*/
|
||||
public int mode;
|
||||
|
||||
/**
|
||||
* Id of the group being queried.
|
||||
*/
|
||||
public long id;
|
||||
|
||||
/**
|
||||
* Type of the group being query. One of MediaUtils.TYPE_*.
|
||||
*/
|
||||
public int type;
|
||||
|
||||
/**
|
||||
* Data. Required value depends on value of mode. See individual mode
|
||||
* documentation for details.
|
||||
*/
|
||||
public long data;
|
||||
|
||||
/**
|
||||
* Create the tasks. All arguments are passed directly to
|
||||
@ -43,52 +64,11 @@ public class QueryTask {
|
||||
*/
|
||||
public QueryTask(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
|
||||
{
|
||||
mUri = uri;
|
||||
mProjection = projection;
|
||||
mSelection = selection;
|
||||
mSelectionArgs = selectionArgs;
|
||||
mSortOrder = sortOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the uri of the pending query.
|
||||
*
|
||||
* @param uri The new uri.
|
||||
*/
|
||||
public void setUri(Uri uri)
|
||||
{
|
||||
mUri = uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modify the sort order of the pending query.
|
||||
*
|
||||
* @param sortOrder The new sort order.
|
||||
*/
|
||||
public void setSortOrder(String sortOrder)
|
||||
{
|
||||
mSortOrder = sortOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Store some extra data with this query. This data is not used at all by
|
||||
* when running the query.
|
||||
*
|
||||
* @param extra The extra data
|
||||
*/
|
||||
public void setExtra(long extra)
|
||||
{
|
||||
mExtra = extra;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the extra data stored by {@link QueryTask#setExtra(long)}
|
||||
*
|
||||
* @return The extra data
|
||||
*/
|
||||
public long getExtra()
|
||||
{
|
||||
return mExtra;
|
||||
this.uri = uri;
|
||||
this.projection = projection;
|
||||
this.selection = selection;
|
||||
this.selectionArgs = selectionArgs;
|
||||
this.sortOrder = sortOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,6 +78,6 @@ public class QueryTask {
|
||||
*/
|
||||
public Cursor runQuery(ContentResolver resolver)
|
||||
{
|
||||
return resolver.query(mUri, mProjection, mSelection, mSelectionArgs, mSortOrder);
|
||||
return resolver.query(uri, projection, selection, selectionArgs, sortOrder);
|
||||
}
|
||||
}
|
||||
|
@ -88,19 +88,19 @@ public final class SongTimeline {
|
||||
/**
|
||||
* Clear the timeline and use only the provided songs.
|
||||
*
|
||||
* @see SongTimeline#addSongs(int, android.database.Cursor, int, long)
|
||||
* @see SongTimeline#addSongs(Context, QueryTask)
|
||||
*/
|
||||
public static final int MODE_PLAY = 0;
|
||||
/**
|
||||
* Clear the queue and add the songs after the current song.
|
||||
*
|
||||
* @see SongTimeline#addSongs(int, android.database.Cursor, int, long)
|
||||
* @see SongTimeline#addSongs(Context, QueryTask)
|
||||
*/
|
||||
public static final int MODE_PLAY_NEXT = 1;
|
||||
/**
|
||||
* Add the songs at the end of the timeline, clearing random songs.
|
||||
*
|
||||
* @see SongTimeline#addSongs(int, android.database.Cursor, int, long)
|
||||
* @see SongTimeline#addSongs(Context, QueryTask)
|
||||
*/
|
||||
public static final int MODE_ENQUEUE = 2;
|
||||
/**
|
||||
@ -108,9 +108,9 @@ public final class SongTimeline {
|
||||
* removing the songs before the given position in the query and appending
|
||||
* them to the end of the queue.
|
||||
*
|
||||
* Pass the position in the integer argument.
|
||||
* Pass the position in QueryTask.data.
|
||||
*
|
||||
* @see SongTimeline#addSongs(int, android.database.Cursor, int, long)
|
||||
* @see SongTimeline#addSongs(Context, QueryTask)
|
||||
*/
|
||||
public static final int MODE_PLAY_POS_FIRST = 3;
|
||||
/**
|
||||
@ -119,11 +119,9 @@ public final class SongTimeline {
|
||||
* them to the end of the queue. If there are multiple songs with
|
||||
* the given id, picks the first song with that id.
|
||||
*
|
||||
* Pass the id in the long argument and the type of the id (one of
|
||||
* MediaUtils.TYPE_ARTIST, TYPE_ALBUM or TYPE_SONG) in the integer
|
||||
* argument.
|
||||
* Pass the id in QueryTask.data.
|
||||
*
|
||||
* @see SongTimeline#addSongs(int, android.database.Cursor, int, long)
|
||||
* @see SongTimeline#addSongs(Context, QueryTask)
|
||||
*/
|
||||
public static final int MODE_PLAY_ID_FIRST = 4;
|
||||
/**
|
||||
@ -132,11 +130,9 @@ public final class SongTimeline {
|
||||
* them to the end of the queue. If there are multiple songs with
|
||||
* the given id, picks the first song with that id.
|
||||
*
|
||||
* Pass the id in the long argument and the type of the id (one of
|
||||
* MediaUtils.TYPE_ARTIST, TYPE_ALBUM or TYPE_SONG) in the integer
|
||||
* argument.
|
||||
* Pass the id in QueryTask.data.
|
||||
*
|
||||
* @see SongTimeline#addSongs(int, android.database.Cursor, int, long)
|
||||
* @see SongTimeline#addSongs(Context, QueryTask)
|
||||
*/
|
||||
public static final int MODE_ENQUEUE_ID_FIRST = 5;
|
||||
/**
|
||||
@ -144,9 +140,9 @@ public final class SongTimeline {
|
||||
* removing the songs before the given position in the query and appending
|
||||
* them to the end of the queue.
|
||||
*
|
||||
* Pass the position in the integer argument.
|
||||
* Pass the position in QueryTask.data.
|
||||
*
|
||||
* @see SongTimeline#addSongs(int, android.database.Cursor, int, long)
|
||||
* @see SongTimeline#addSongs(Context, QueryTask)
|
||||
*/
|
||||
public static final int MODE_ENQUEUE_POS_FIRST = 6;
|
||||
|
||||
@ -303,8 +299,11 @@ public final class SongTimeline {
|
||||
StringBuilder selection = new StringBuilder("_ID IN (");
|
||||
for (int i = 0; i != n; ++i) {
|
||||
long id = in.readLong();
|
||||
if (id == -1)
|
||||
continue;
|
||||
|
||||
// Add the index to the flags so we can sort
|
||||
int flags = (in.readInt() & ~(~0 << Song.FLAG_COUNT)) | (i << Song.FLAG_COUNT);
|
||||
int flags = in.readInt() & ~(~0 << Song.FLAG_COUNT) | i << Song.FLAG_COUNT;
|
||||
songs.add(new Song(id, flags));
|
||||
|
||||
if (i != 0)
|
||||
@ -375,7 +374,6 @@ public final class SongTimeline {
|
||||
Song song = songs.get(i);
|
||||
if (song == null) {
|
||||
out.writeLong(-1);
|
||||
out.writeInt(0);
|
||||
} else {
|
||||
out.writeLong(song.id);
|
||||
out.writeInt(song.flags);
|
||||
@ -580,23 +578,29 @@ public final class SongTimeline {
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the songs from the given cursor to the song timeline.
|
||||
* Run the given query and add the results to the song timeline.
|
||||
*
|
||||
* @param mode How to add the songs. One of SongTimeline.MODE_*.
|
||||
* @param cursor The cursor to fill from.
|
||||
* @param i The integer argument. See individual mode documentation for
|
||||
* usage.
|
||||
* @param l The long argument. See individual mode documentation for
|
||||
* usage.
|
||||
* @param context A context to use.
|
||||
* @param query The query to be run. The mode variable must be initialized
|
||||
* to one of SongTimeline.MODE_*. The type and data variables may also need
|
||||
* to be initialized depending on the given mode.
|
||||
* @return The number of songs that were added.
|
||||
*/
|
||||
public int addSongs(int mode, Cursor cursor, int i, long l)
|
||||
public int addSongs(Context context, QueryTask query)
|
||||
{
|
||||
if (cursor == null)
|
||||
Cursor cursor = query.runQuery(context.getContentResolver());
|
||||
if (cursor == null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int count = cursor.getCount();
|
||||
if (count == 0)
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mode = query.mode;
|
||||
int type = query.type;
|
||||
long data = query.data;
|
||||
|
||||
ArrayList<Song> timeline = mSongs;
|
||||
synchronized (this) {
|
||||
@ -636,11 +640,11 @@ public final class SongTimeline {
|
||||
timeline.add(song);
|
||||
|
||||
if (jumpSong == null) {
|
||||
if ((mode == MODE_PLAY_POS_FIRST || mode == MODE_ENQUEUE_POS_FIRST) && j == i) {
|
||||
if ((mode == MODE_PLAY_POS_FIRST || mode == MODE_ENQUEUE_POS_FIRST) && j == data) {
|
||||
jumpSong = song;
|
||||
} else if (mode == MODE_PLAY_ID_FIRST || mode == MODE_ENQUEUE_ID_FIRST) {
|
||||
long id;
|
||||
switch (i) {
|
||||
switch (type) {
|
||||
case MediaUtils.TYPE_ARTIST:
|
||||
id = song.artistId;
|
||||
break;
|
||||
@ -651,9 +655,9 @@ public final class SongTimeline {
|
||||
id = song.id;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Unsupported id type: " + i);
|
||||
throw new IllegalArgumentException("Unsupported id type: " + type);
|
||||
}
|
||||
if (id == l)
|
||||
if (id == data)
|
||||
jumpSong = song;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user