Merge pull request #210 from jakobkukla/new-refactor-musicservice
Refactor: MusicService
This commit is contained in:
commit
0233e1264e
3 changed files with 68 additions and 121 deletions
|
|
@ -103,12 +103,6 @@ public class MusicPlayerRemote {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setPosition(final int position) {
|
|
||||||
if (musicService != null) {
|
|
||||||
musicService.setPosition(position);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void pauseSong() {
|
public static void pauseSong() {
|
||||||
if (musicService != null) {
|
if (musicService != null) {
|
||||||
musicService.pause();
|
musicService.pause();
|
||||||
|
|
@ -148,7 +142,7 @@ public class MusicPlayerRemote {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void openQueue(final List<Song> queue, final int startPosition, final boolean startPlaying) {
|
public static void openQueue(final List<Song> queue, final int startPosition, final boolean startPlaying) {
|
||||||
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
|
if (!tryToHandleOpenPlayingQueue(queue, startPosition) && musicService != null) {
|
||||||
musicService.openQueue(queue, startPosition, startPlaying);
|
musicService.openQueue(queue, startPosition, startPlaying);
|
||||||
if (!PreferenceUtil.getInstance(musicService).getRememberShuffle()){
|
if (!PreferenceUtil.getInstance(musicService).getRememberShuffle()){
|
||||||
setShuffleMode(QueueManager.SHUFFLE_MODE_NONE);
|
setShuffleMode(QueueManager.SHUFFLE_MODE_NONE);
|
||||||
|
|
@ -162,19 +156,15 @@ public class MusicPlayerRemote {
|
||||||
startPosition = new Random().nextInt(queue.size());
|
startPosition = new Random().nextInt(queue.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tryToHandleOpenPlayingQueue(queue, startPosition, startPlaying) && musicService != null) {
|
if (!tryToHandleOpenPlayingQueue(queue, startPosition) && musicService != null) {
|
||||||
openQueue(queue, startPosition, startPlaying);
|
openQueue(queue, startPosition, startPlaying);
|
||||||
setShuffleMode(QueueManager.SHUFFLE_MODE_SHUFFLE);
|
setShuffleMode(QueueManager.SHUFFLE_MODE_SHUFFLE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean tryToHandleOpenPlayingQueue(final List<Song> queue, final int startPosition, final boolean startPlaying) {
|
private static boolean tryToHandleOpenPlayingQueue(final List<Song> queue, final int startPosition) {
|
||||||
if (getPlayingQueue() == queue) {
|
if (getPlayingQueue() == queue) {
|
||||||
if (startPlaying) {
|
playSongAt(startPosition);
|
||||||
playSongAt(startPosition);
|
|
||||||
} else {
|
|
||||||
setPosition(startPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_
|
||||||
import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED;
|
import static com.google.android.exoplayer2.Player.MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED;
|
||||||
import static com.google.android.exoplayer2.Player.PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM;
|
import static com.google.android.exoplayer2.Player.PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM;
|
||||||
|
|
||||||
public class MusicService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener, Playback.PlaybackCallbacks {
|
public class MusicService extends Service implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
|
public static final String PACKAGE_NAME = BuildConfig.APPLICATION_ID;
|
||||||
|
|
||||||
public static final String ACTION_TOGGLE = PACKAGE_NAME + ".toggle";
|
public static final String ACTION_TOGGLE = PACKAGE_NAME + ".toggle";
|
||||||
|
|
@ -103,10 +103,8 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
public static final int TRACK_CHANGED = 1;
|
public static final int TRACK_CHANGED = 1;
|
||||||
public static final int TRACK_ENDED = 2;
|
public static final int TRACK_ENDED = 2;
|
||||||
|
|
||||||
public static final int RELEASE_WAKELOCK = 0;
|
|
||||||
public static final int PLAY_SONG = 3;
|
public static final int PLAY_SONG = 3;
|
||||||
public static final int PREPARE_NEXT = 4;
|
public static final int PREPARE_NEXT = 4;
|
||||||
public static final int SET_POSITION = 5;
|
|
||||||
|
|
||||||
public static final int SAVE_QUEUE = 0;
|
public static final int SAVE_QUEUE = 0;
|
||||||
public static final int LOAD_QUEUE = 9;
|
public static final int LOAD_QUEUE = 9;
|
||||||
|
|
@ -123,7 +121,6 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
|
|
||||||
public QueueManager queueManager;
|
public QueueManager queueManager;
|
||||||
|
|
||||||
private boolean notHandledMetaChangedForCurrentTrack;
|
|
||||||
private boolean queuesRestored;
|
private boolean queuesRestored;
|
||||||
|
|
||||||
private PlayingNotification playingNotification;
|
private PlayingNotification playingNotification;
|
||||||
|
|
@ -159,6 +156,41 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private final Playback.PlaybackCallbacks playbackCallbacks = new Playback.PlaybackCallbacks() {
|
||||||
|
@Override
|
||||||
|
public void onStateChanged(int state) {
|
||||||
|
notifyChange(STATE_CHANGED);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onReadyChanged(boolean ready, int reason) {
|
||||||
|
notifyChange(STATE_CHANGED);
|
||||||
|
|
||||||
|
if (ready) {
|
||||||
|
progressHandler.sendEmptyMessage(TRACK_STARTED);
|
||||||
|
prepareNext();
|
||||||
|
} else if (reason == PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM) {
|
||||||
|
progressHandler.sendEmptyMessage(TRACK_ENDED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTrackChanged(int reason) {
|
||||||
|
acquireWakeLock(30000);
|
||||||
|
|
||||||
|
if (reason == MEDIA_ITEM_TRANSITION_REASON_AUTO) {
|
||||||
|
playerHandler.sendEmptyMessage(TRACK_CHANGED);
|
||||||
|
progressHandler.sendEmptyMessage(TRACK_CHANGED);
|
||||||
|
} else if (reason == MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED) {
|
||||||
|
progressHandler.sendEmptyMessage(TRACK_CHANGED);
|
||||||
|
prepareNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyChange(STATE_CHANGED);
|
||||||
|
notifyChange(META_CHANGED);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private final BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver becomingNoisyReceiver = new BroadcastReceiver() {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, @NonNull Intent intent) {
|
public void onReceive(Context context, @NonNull Intent intent) {
|
||||||
|
|
@ -205,7 +237,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
wakeLock.setReferenceCounted(false);
|
wakeLock.setReferenceCounted(false);
|
||||||
|
|
||||||
playback = new LocalPlayer(this);
|
playback = new LocalPlayer(this);
|
||||||
playback.setCallbacks(this);
|
playback.setCallbacks(playbackCallbacks);
|
||||||
|
|
||||||
queueManager = new QueueManager(this, queueCallbacks);
|
queueManager = new QueueManager(this, queueCallbacks);
|
||||||
|
|
||||||
|
|
@ -221,7 +253,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
queueHandlerThread.start();
|
queueHandlerThread.start();
|
||||||
queueHandler = new QueueHandler(this, queueHandlerThread.getLooper());
|
queueHandler = new QueueHandler(this, queueHandlerThread.getLooper());
|
||||||
|
|
||||||
throttledSeekHandler = new ThrottledSeekHandler(playerHandler);
|
throttledSeekHandler = new ThrottledSeekHandler(new Handler());
|
||||||
uiThreadHandler = new Handler();
|
uiThreadHandler = new Handler();
|
||||||
|
|
||||||
registerReceiver(widgetIntentReceiver, new IntentFilter(INTENT_EXTRA_WIDGET_UPDATE));
|
registerReceiver(widgetIntentReceiver, new IntentFilter(INTENT_EXTRA_WIDGET_UPDATE));
|
||||||
|
|
@ -423,7 +455,6 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
|
|
||||||
if (restoredProgress > 0) seek(restoredProgress);
|
if (restoredProgress > 0) seek(restoredProgress);
|
||||||
|
|
||||||
notHandledMetaChangedForCurrentTrack = true;
|
|
||||||
handleChangeInternal(META_CHANGED);
|
handleChangeInternal(META_CHANGED);
|
||||||
handleChangeInternal(QUEUE_CHANGED);
|
handleChangeInternal(QUEUE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
@ -466,24 +497,17 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
playSongAt(queueManager.getNextPosition(force));
|
playSongAt(queueManager.getNextPosition(force));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openTrackAndPrepareNextAt(int position) {
|
private synchronized void openTrackAndPrepareNextAt(int position) {
|
||||||
synchronized (this) {
|
queueManager.position = position;
|
||||||
queueManager.position = position;
|
|
||||||
|
|
||||||
openCurrent();
|
openCurrent();
|
||||||
playback.start();
|
playback.start();
|
||||||
|
|
||||||
notifyChange(META_CHANGED);
|
|
||||||
notHandledMetaChangedForCurrentTrack = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void openCurrent() {
|
private synchronized void openCurrent() {
|
||||||
synchronized (this) {
|
if (queueManager.getCurrentSong() == null) return;
|
||||||
if (queueManager.getCurrentSong() == null) return;
|
|
||||||
|
|
||||||
playback.setDataSource(queueManager.getCurrentSong());
|
playback.setDataSource(queueManager.getCurrentSong());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareNext() {
|
private void prepareNext() {
|
||||||
|
|
@ -491,13 +515,11 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
playerHandler.obtainMessage(PREPARE_NEXT).sendToTarget();
|
playerHandler.obtainMessage(PREPARE_NEXT).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareNextImpl() {
|
private synchronized void prepareNextImpl() {
|
||||||
synchronized (this) {
|
if (queueManager.getCurrentSong() == null) return;
|
||||||
if (queueManager.getCurrentSong() == null) return;
|
|
||||||
|
|
||||||
queueManager.nextPosition = queueManager.getNextPosition(false);
|
queueManager.nextPosition = queueManager.getNextPosition(false);
|
||||||
playback.queueDataSource(queueManager.getSongAt(queueManager.nextPosition));
|
playback.queueDataSource(queueManager.getSongAt(queueManager.nextPosition));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initNotification() {
|
public void initNotification() {
|
||||||
|
|
@ -606,11 +628,7 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
position = 0;
|
position = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startPlaying) {
|
playSongAt(position);
|
||||||
playSongAt(position);
|
|
||||||
} else {
|
|
||||||
setPosition(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyChange(QUEUE_CHANGED);
|
notifyChange(QUEUE_CHANGED);
|
||||||
}
|
}
|
||||||
|
|
@ -622,37 +640,18 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
playerHandler.obtainMessage(PLAY_SONG, position, 0).sendToTarget();
|
playerHandler.obtainMessage(PLAY_SONG, position, 0).sendToTarget();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPosition(final int position) {
|
|
||||||
// handle this on the handlers thread to avoid blocking the ui thread
|
|
||||||
playerHandler.removeMessages(SET_POSITION);
|
|
||||||
playerHandler.obtainMessage(SET_POSITION, position, 0).sendToTarget();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void playSongAtImpl(int position) {
|
|
||||||
openTrackAndPrepareNextAt(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void pause() {
|
public void pause() {
|
||||||
if (playback.isPlaying()) {
|
if (playback.isPlaying()) {
|
||||||
playback.pause();
|
playback.pause();
|
||||||
notifyChange(STATE_CHANGED);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void play() {
|
public synchronized void play() {
|
||||||
synchronized (this) {
|
if (!playback.isPlaying()) {
|
||||||
if (!playback.isPlaying()) {
|
if (!playback.isReady()) {
|
||||||
if (!playback.isReady()) {
|
playSongAt(queueManager.position);
|
||||||
playSongAt(queueManager.position);
|
} else {
|
||||||
} else {
|
playback.start();
|
||||||
playback.start();
|
|
||||||
if (notHandledMetaChangedForCurrentTrack) {
|
|
||||||
handleChangeInternal(META_CHANGED);
|
|
||||||
notHandledMetaChangedForCurrentTrack = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
notifyChange(STATE_CHANGED);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -677,12 +676,10 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
return playback.getDuration();
|
return playback.getDuration();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int seek(int millis) {
|
public synchronized int seek(int millis) {
|
||||||
synchronized (this) {
|
playback.setProgress(millis);
|
||||||
playback.setProgress(millis);
|
throttledSeekHandler.notifySeek();
|
||||||
throttledSeekHandler.notifySeek();
|
return millis;
|
||||||
return millis;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyChange(@NonNull final String what) {
|
private void notifyChange(@NonNull final String what) {
|
||||||
|
|
@ -760,36 +757,6 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStateChanged(int state) {
|
|
||||||
notifyChange(STATE_CHANGED);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onReadyChanged(boolean ready, int reason) {
|
|
||||||
notifyChange(STATE_CHANGED);
|
|
||||||
|
|
||||||
if (ready) {
|
|
||||||
progressHandler.sendEmptyMessage(TRACK_STARTED);
|
|
||||||
prepareNext();
|
|
||||||
} else if (reason == PLAY_WHEN_READY_CHANGE_REASON_END_OF_MEDIA_ITEM) {
|
|
||||||
progressHandler.sendEmptyMessage(TRACK_ENDED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTrackChanged(int reason) {
|
|
||||||
acquireWakeLock(30000);
|
|
||||||
|
|
||||||
if (reason == MEDIA_ITEM_TRANSITION_REASON_AUTO) {
|
|
||||||
playerHandler.sendEmptyMessage(TRACK_CHANGED);
|
|
||||||
progressHandler.sendEmptyMessage(TRACK_CHANGED);
|
|
||||||
} else if (reason == MEDIA_ITEM_TRANSITION_REASON_PLAYLIST_CHANGED) {
|
|
||||||
progressHandler.sendEmptyMessage(TRACK_CHANGED);
|
|
||||||
prepareNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static final class PlaybackHandler extends Handler {
|
private static final class PlaybackHandler extends Handler {
|
||||||
private final WeakReference<MusicService> mService;
|
private final WeakReference<MusicService> mService;
|
||||||
|
|
||||||
|
|
@ -810,16 +777,16 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
if (service.queueManager.getRepeatMode() == QueueManager.REPEAT_MODE_NONE && service.queueManager.isLastTrack()) {
|
if (service.queueManager.getRepeatMode() == QueueManager.REPEAT_MODE_NONE && service.queueManager.isLastTrack()) {
|
||||||
service.pause();
|
service.pause();
|
||||||
service.seek(0);
|
service.seek(0);
|
||||||
service.notifyChange(STATE_CHANGED);
|
|
||||||
} else {
|
} else {
|
||||||
service.queueManager.position = service.queueManager.nextPosition;
|
service.queueManager.position = service.queueManager.nextPosition;
|
||||||
service.prepareNextImpl();
|
service.prepareNextImpl();
|
||||||
service.notifyChange(META_CHANGED);
|
|
||||||
service.notifyChange(QUEUE_CHANGED);
|
service.notifyChange(QUEUE_CHANGED);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TRACK_ENDED:
|
case TRACK_ENDED:
|
||||||
|
// FIXME This isn't used anywhere. This means releaseWakeLock() is never called
|
||||||
|
|
||||||
// if there is a timer finished, don't continue
|
// if there is a timer finished, don't continue
|
||||||
if (service.pendingQuit || service.queueManager.getRepeatMode() == QueueManager.REPEAT_MODE_NONE && service.queueManager.isLastTrack()) {
|
if (service.pendingQuit || service.queueManager.getRepeatMode() == QueueManager.REPEAT_MODE_NONE && service.queueManager.isLastTrack()) {
|
||||||
service.notifyChange(STATE_CHANGED);
|
service.notifyChange(STATE_CHANGED);
|
||||||
|
|
@ -833,21 +800,11 @@ public class MusicService extends Service implements SharedPreferences.OnSharedP
|
||||||
service.playNextSong(false);
|
service.playNextSong(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEmptyMessage(RELEASE_WAKELOCK);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RELEASE_WAKELOCK:
|
|
||||||
service.releaseWakeLock();
|
service.releaseWakeLock();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAY_SONG:
|
case PLAY_SONG:
|
||||||
service.playSongAtImpl(msg.arg1);
|
|
||||||
service.notifyChange(STATE_CHANGED);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SET_POSITION:
|
|
||||||
service.openTrackAndPrepareNextAt(msg.arg1);
|
service.openTrackAndPrepareNextAt(msg.arg1);
|
||||||
service.notifyChange(STATE_CHANGED);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PREPARE_NEXT:
|
case PREPARE_NEXT:
|
||||||
|
|
|
||||||
|
|
@ -215,9 +215,9 @@ public class QueueManager {
|
||||||
position = currentPosition - 1;
|
position = currentPosition - 1;
|
||||||
} else if (deletedPosition == currentPosition) {
|
} else if (deletedPosition == currentPosition) {
|
||||||
if (playingQueue.size() > deletedPosition) {
|
if (playingQueue.size() > deletedPosition) {
|
||||||
MusicPlayerRemote.setPosition(position);
|
MusicPlayerRemote.playSongAt(position);
|
||||||
} else {
|
} else {
|
||||||
MusicPlayerRemote.setPosition(position - 1);
|
MusicPlayerRemote.playSongAt(position - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue