aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Jackson <daneren2005@gmail.com>2013-08-11 08:58:30 -0700
committerScott Jackson <daneren2005@gmail.com>2013-08-11 08:58:30 -0700
commit3cc5dfa96f67899ada68a69b3e21816c3431b438 (patch)
tree198df287345814e434fb4611127ad6d2c1b80814
parentd5286a60e905f64bb62f8e95633f5aaef8c13105 (diff)
downloaddsub-3cc5dfa96f67899ada68a69b3e21816c3431b438.tar.gz
dsub-3cc5dfa96f67899ada68a69b3e21816c3431b438.tar.bz2
dsub-3cc5dfa96f67899ada68a69b3e21816c3431b438.zip
Use JukeboxController instead of JukeboxService
-rw-r--r--src/github/daneren2005/dsub/domain/RemoteStatus.java (renamed from src/github/daneren2005/dsub/domain/JukeboxStatus.java)2
-rw-r--r--src/github/daneren2005/dsub/service/CachedMusicService.java14
-rw-r--r--src/github/daneren2005/dsub/service/DownloadServiceImpl.java59
-rw-r--r--src/github/daneren2005/dsub/service/JukeboxController.java111
-rw-r--r--src/github/daneren2005/dsub/service/JukeboxService.java359
-rw-r--r--src/github/daneren2005/dsub/service/MusicService.java15
-rw-r--r--src/github/daneren2005/dsub/service/OfflineMusicService.java15
-rw-r--r--src/github/daneren2005/dsub/service/RESTMusicService.java21
-rw-r--r--src/github/daneren2005/dsub/service/RemoteController.java51
-rw-r--r--src/github/daneren2005/dsub/service/parser/JukeboxStatusParser.java6
10 files changed, 163 insertions, 490 deletions
diff --git a/src/github/daneren2005/dsub/domain/JukeboxStatus.java b/src/github/daneren2005/dsub/domain/RemoteStatus.java
index 7b229f49..e9749120 100644
--- a/src/github/daneren2005/dsub/domain/JukeboxStatus.java
+++ b/src/github/daneren2005/dsub/domain/RemoteStatus.java
@@ -22,7 +22,7 @@ package github.daneren2005.dsub.domain;
* @author Sindre Mehus
* @version $Id$
*/
-public class JukeboxStatus {
+public class RemoteStatus {
private Integer positionSeconds;
private Integer currentPlayingIndex;
diff --git a/src/github/daneren2005/dsub/service/CachedMusicService.java b/src/github/daneren2005/dsub/service/CachedMusicService.java
index 943b5eb2..cc8d2dbd 100644
--- a/src/github/daneren2005/dsub/service/CachedMusicService.java
+++ b/src/github/daneren2005/dsub/service/CachedMusicService.java
@@ -29,7 +29,7 @@ import android.support.v4.util.LruCache;
import github.daneren2005.dsub.domain.ChatMessage;
import github.daneren2005.dsub.domain.Genre;
import github.daneren2005.dsub.domain.Indexes;
-import github.daneren2005.dsub.domain.JukeboxStatus;
+import github.daneren2005.dsub.domain.RemoteStatus;
import github.daneren2005.dsub.domain.Lyrics;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.MusicFolder;
@@ -241,32 +241,32 @@ public class CachedMusicService implements MusicService {
}
@Override
- public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception {
return musicService.updateJukeboxPlaylist(ids, context, progressListener);
}
@Override
- public JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception {
return musicService.skipJukebox(index, offsetSeconds, context, progressListener);
}
@Override
- public JukeboxStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception {
return musicService.stopJukebox(context, progressListener);
}
@Override
- public JukeboxStatus startJukebox(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus startJukebox(Context context, ProgressListener progressListener) throws Exception {
return musicService.startJukebox(context, progressListener);
}
@Override
- public JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception {
return musicService.getJukeboxStatus(context, progressListener);
}
@Override
- public JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception {
return musicService.setJukeboxGain(gain, context, progressListener);
}
diff --git a/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
index 85991abb..9568c0af 100644
--- a/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
+++ b/src/github/daneren2005/dsub/service/DownloadServiceImpl.java
@@ -99,7 +99,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
private final LruCache<MusicDirectory.Entry, DownloadFile> downloadFileCache = new LruCache<MusicDirectory.Entry, DownloadFile>(100);
private final List<DownloadFile> cleanupCandidates = new ArrayList<DownloadFile>();
private final Scrobbler scrobbler = new Scrobbler();
- private final JukeboxService jukeboxService = new JukeboxService(this);
+ private RemoteController remoteController;
private DownloadFile currentPlaying;
private DownloadFile nextPlaying;
private DownloadFile currentDownloading;
@@ -324,15 +324,15 @@ public class DownloadServiceImpl extends Service implements DownloadService {
private void updateJukeboxPlaylist() {
if (remoteState != RemoteControlState.LOCAL) {
- jukeboxService.updatePlaylist();
+ remoteController.updatePlaylist();
}
}
public void restore(List<MusicDirectory.Entry> songs, int currentPlayingIndex, int currentPlayingPosition) {
SharedPreferences prefs = Util.getPreferences(this);
remoteState = RemoteControlState.values()[prefs.getInt(Constants.PREFERENCES_KEY_CONTROL_MODE, 0)];
- if(remoteState == RemoteControlState.JUKEBOX_SERVER) {
- jukeboxService.setEnabled(true);
+ if(remoteState != RemoteControlState.LOCAL) {
+ setRemoteState(remoteState);
}
boolean startShufflePlay = prefs.getBoolean(Constants.PREFERENCES_KEY_SHUFFLE_MODE, false);
download(songs, false, false, false, false);
@@ -667,7 +667,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
setCurrentPlaying(index, start);
if (start) {
if (remoteState != RemoteControlState.LOCAL) {
- jukeboxService.skip(getCurrentPlayingIndex(), 0);
+ remoteController.changeTrack(getCurrentPlayingIndex(), currentPlaying);
setPlayerState(STARTED);
} else {
bufferAndPlay();
@@ -727,7 +727,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
public synchronized void seekTo(int position) {
try {
if (remoteState != RemoteControlState.LOCAL) {
- jukeboxService.skip(getCurrentPlayingIndex(), position / 1000);
+ remoteController.changePosition(position / 1000);
} else {
mediaPlayer.seekTo(position);
cachedPosition = position;
@@ -784,7 +784,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
try {
if (playerState == STARTED) {
if (remoteState != RemoteControlState.LOCAL) {
- jukeboxService.stop();
+ remoteController.stop();
} else {
mediaPlayer.pause();
}
@@ -800,7 +800,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
try {
if (playerState == STARTED) {
if (remoteState != RemoteControlState.LOCAL) {
- jukeboxService.stop();
+ remoteController.stop();
} else {
mediaPlayer.pause();
}
@@ -817,7 +817,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
public synchronized void start() {
try {
if (remoteState != RemoteControlState.LOCAL) {
- jukeboxService.start();
+ remoteController.start();
} else {
mediaPlayer.start();
}
@@ -849,7 +849,7 @@ public class DownloadServiceImpl extends Service implements DownloadService {
return 0;
}
if (remoteState != RemoteControlState.LOCAL) {
- return jukeboxService.getPositionSeconds() * 1000;
+ return remoteController.getRemotePosition() * 1000;
} else {
return cachedPosition;
}
@@ -1028,25 +1028,42 @@ public class DownloadServiceImpl extends Service implements DownloadService {
@Override
public void setRemoteEnabled(RemoteControlState newState) {
- remoteState = newState;
- jukeboxService.setEnabled(remoteState == RemoteControlState.JUKEBOX_SERVER);
- if (remoteState != RemoteControlState.LOCAL) {
- reset();
-
- // Cancel current download, if necessary.
- if (currentDownloading != null) {
- currentDownloading.cancelDownload();
- }
- }
+ setRemoteState(newState);
SharedPreferences.Editor editor = Util.getPreferences(this).edit();
editor.putInt(Constants.PREFERENCES_KEY_CONTROL_MODE, newState.getValue());
editor.commit();
}
+ private void setRemoteState(RemoteControlState newState) {
+ if(remoteController != null) {
+ remoteController.stop();
+ setPlayerState(PlayerState.IDLE);
+ remoteController.shutdown();
+ remoteController = null;
+ }
+
+ remoteState = newState;
+ switch(newState) {
+ case JUKEBOX_SERVER:
+ remoteController = new JukeboxController(this);
+ break;
+ case LOCAL: default:
+ break;
+ }
+
+ if (remoteState != RemoteControlState.LOCAL) {
+ reset();
+
+ // Cancel current download, if necessary.
+ if (currentDownloading != null) {
+ currentDownloading.cancelDownload();
+ }
+ }
+ }
@Override
public void setRemoteVolume(boolean up) {
- jukeboxService.adjustVolume(up);
+ remoteController.setVolume(up);
}
private synchronized void bufferAndPlay() {
diff --git a/src/github/daneren2005/dsub/service/JukeboxController.java b/src/github/daneren2005/dsub/service/JukeboxController.java
index 4a3d4d40..f27a147f 100644
--- a/src/github/daneren2005/dsub/service/JukeboxController.java
+++ b/src/github/daneren2005/dsub/service/JukeboxController.java
@@ -15,16 +15,11 @@
package github.daneren2005.dsub.service;
-import android.content.Context;
import android.os.Handler;
import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ProgressBar;
-import android.widget.Toast;
+
import github.daneren2005.dsub.R;
-import github.daneren2005.dsub.domain.JukeboxStatus;
+import github.daneren2005.dsub.domain.RemoteStatus;
import github.daneren2005.dsub.domain.PlayerState;
import github.daneren2005.dsub.domain.RemoteControlState;
import github.daneren2005.dsub.service.parser.SubsonicRESTException;
@@ -41,15 +36,16 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
public class JukeboxController extends RemoteController {
- private static final String TAG = JukeboxService.class.getSimpleName();
+ private static final String TAG = JukeboxController.class.getSimpleName();
private static final long STATUS_UPDATE_INTERVAL_SECONDS = 5L;
private final Handler handler = new Handler();
+ private boolean running = false;
private final TaskQueue tasks = new TaskQueue();
private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
private ScheduledFuture<?> statusUpdateFuture;
private final AtomicLong timeOfLastUpdate = new AtomicLong();
- private JukeboxStatus jukeboxStatus;
+ private RemoteStatus jukeboxStatus;
private float gain = 0.5f;
public JukeboxController(DownloadServiceImpl downloadService) {
@@ -57,10 +53,10 @@ public class JukeboxController extends RemoteController {
new Thread() {
@Override
public void run() {
+ running = true;
processTasks();
}
}.start();
- downloadService.setPlayerState(PlayerState.IDLE);
updatePlaylist();
}
@@ -80,6 +76,10 @@ public class JukeboxController extends RemoteController {
stopStatusUpdate();
tasks.add(new Stop());
}
+ @Override
+ public void shutdown() {
+ running = false;
+ }
@Override
public void updatePlaylist() {
@@ -95,8 +95,7 @@ public class JukeboxController extends RemoteController {
}
@Override
public void changePosition(int seconds) {
- // TODO: Break down into changePosition/changeTrack
- /*tasks.remove(Skip.class);
+ tasks.remove(Skip.class);
tasks.remove(Stop.class);
tasks.remove(Start.class);
@@ -104,8 +103,8 @@ public class JukeboxController extends RemoteController {
if (jukeboxStatus != null) {
jukeboxStatus.setPositionSeconds(seconds);
}
- tasks.add(new Skip(index, seconds));
- downloadService.setPlayerState(PlayerState.STARTED);*/
+ tasks.add(new Skip(-1, seconds));
+ downloadService.setPlayerState(PlayerState.STARTED);
}
@Override
public void changeTrack(int index, DownloadFile song) {
@@ -144,12 +143,14 @@ public class JukeboxController extends RemoteController {
}
private void processTasks() {
- while (true) {
- JukeboxTask task = null;
+ while (running) {
+ RemoteTask task = null;
try {
task = tasks.take();
- JukeboxStatus status = task.execute();
- onStatusUpdate(status);
+ RemoteStatus status = task.execute();
+ if(status != null) {
+ onStatusUpdate(status);
+ }
} catch (Throwable x) {
onError(task, x);
}
@@ -176,7 +177,7 @@ public class JukeboxController extends RemoteController {
}
}
- private void onStatusUpdate(JukeboxStatus jukeboxStatus) {
+ private void onStatusUpdate(RemoteStatus jukeboxStatus) {
timeOfLastUpdate.set(System.currentTimeMillis());
this.jukeboxStatus = jukeboxStatus;
@@ -189,7 +190,7 @@ public class JukeboxController extends RemoteController {
}
}
- private void onError(JukeboxTask task, Throwable x) {
+ private void onError(RemoteTask task, Throwable x) {
if (x instanceof ServerTooOldException && !(task instanceof Stop)) {
disableJukeboxOnError(x, R.string.download_jukebox_server_too_old);
} else if (x instanceof OfflineException && !(task instanceof Stop)) {
@@ -215,54 +216,15 @@ public class JukeboxController extends RemoteController {
private MusicService getMusicService() {
return MusicServiceFactory.getMusicService(downloadService);
}
-
- private static class TaskQueue {
- private final LinkedBlockingQueue<JukeboxTask> queue = new LinkedBlockingQueue<JukeboxTask>();
-
- void add(JukeboxTask jukeboxTask) {
- queue.add(jukeboxTask);
- }
-
- JukeboxTask take() throws InterruptedException {
- return queue.take();
- }
-
- void remove(Class<? extends JukeboxTask> clazz) {
- try {
- Iterator<JukeboxTask> iterator = queue.iterator();
- while (iterator.hasNext()) {
- JukeboxTask task = iterator.next();
- if (clazz.equals(task.getClass())) {
- iterator.remove();
- }
- }
- } catch (Throwable x) {
- Log.w(TAG, "Failed to clean-up task queue.", x);
- }
- }
-
- void clear() {
- queue.clear();
- }
- }
-
- private abstract class JukeboxTask {
- abstract JukeboxStatus execute() throws Exception;
-
- @Override
- public String toString() {
- return getClass().getSimpleName();
- }
- }
- private class GetStatus extends JukeboxTask {
+ private class GetStatus extends RemoteTask {
@Override
- JukeboxStatus execute() throws Exception {
+ RemoteStatus execute() throws Exception {
return getMusicService().getJukeboxStatus(downloadService, null);
}
}
- private class SetPlaylist extends JukeboxTask {
+ private class SetPlaylist extends RemoteTask {
private final List<String> ids;
SetPlaylist(List<String> ids) {
@@ -270,12 +232,12 @@ public class JukeboxController extends RemoteController {
}
@Override
- JukeboxStatus execute() throws Exception {
+ RemoteStatus execute() throws Exception {
return getMusicService().updateJukeboxPlaylist(ids, downloadService, null);
}
}
- private class Skip extends JukeboxTask {
+ private class Skip extends RemoteTask {
private final int index;
private final int offsetSeconds;
@@ -285,26 +247,26 @@ public class JukeboxController extends RemoteController {
}
@Override
- JukeboxStatus execute() throws Exception {
+ RemoteStatus execute() throws Exception {
return getMusicService().skipJukebox(index, offsetSeconds, downloadService, null);
}
}
- private class Stop extends JukeboxTask {
+ private class Stop extends RemoteTask {
@Override
- JukeboxStatus execute() throws Exception {
+ RemoteStatus execute() throws Exception {
return getMusicService().stopJukebox(downloadService, null);
}
}
- private class Start extends JukeboxTask {
+ private class Start extends RemoteTask {
@Override
- JukeboxStatus execute() throws Exception {
+ RemoteStatus execute() throws Exception {
return getMusicService().startJukebox(downloadService, null);
}
}
- private class SetGain extends JukeboxTask {
+ private class SetGain extends RemoteTask {
private final float gain;
private SetGain(float gain) {
@@ -312,8 +274,15 @@ public class JukeboxController extends RemoteController {
}
@Override
- JukeboxStatus execute() throws Exception {
+ RemoteStatus execute() throws Exception {
return getMusicService().setJukeboxGain(gain, downloadService, null);
}
}
+
+ private class ShutdownTask extends RemoteTask {
+ @Override
+ RemoteStatus execute() throws Exception {
+ return null;
+ }
+ }
}
diff --git a/src/github/daneren2005/dsub/service/JukeboxService.java b/src/github/daneren2005/dsub/service/JukeboxService.java
deleted file mode 100644
index c44b98c4..00000000
--- a/src/github/daneren2005/dsub/service/JukeboxService.java
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- This file is part of Subsonic.
-
- Subsonic is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- Subsonic is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
-
- Copyright 2009 (C) Sindre Mehus
- */
-package github.daneren2005.dsub.service;
-
-import android.content.Context;
-import android.os.Handler;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.widget.ProgressBar;
-import android.widget.Toast;
-import github.daneren2005.dsub.R;
-import github.daneren2005.dsub.domain.JukeboxStatus;
-import github.daneren2005.dsub.domain.PlayerState;
-import github.daneren2005.dsub.domain.RemoteControlState;
-import github.daneren2005.dsub.service.parser.SubsonicRESTException;
-import github.daneren2005.dsub.util.Util;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-
-/**
- * Provides an asynchronous interface to the remote jukebox on the Subsonic server.
- *
- * @author Sindre Mehus
- * @version $Id$
- */
-public class JukeboxService {
-
- private static final String TAG = JukeboxService.class.getSimpleName();
- private static final long STATUS_UPDATE_INTERVAL_SECONDS = 5L;
-
- private final Handler handler = new Handler();
- private final TaskQueue tasks = new TaskQueue();
- private final DownloadServiceImpl downloadService;
- private final ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
- private ScheduledFuture<?> statusUpdateFuture;
- private final AtomicLong timeOfLastUpdate = new AtomicLong();
- private JukeboxStatus jukeboxStatus;
- private float gain = 0.5f;
- private VolumeToast volumeToast;
-
- // TODO: Report warning if queue fills up.
- // TODO: Create shutdown method?
- // TODO: Disable repeat.
- // TODO: Persist RC state?
- // TODO: Minimize status updates.
-
- public JukeboxService(DownloadServiceImpl downloadService) {
- this.downloadService = downloadService;
- new Thread() {
- @Override
- public void run() {
- processTasks();
- }
- }.start();
- }
-
- private synchronized void startStatusUpdate() {
- stopStatusUpdate();
- Runnable updateTask = new Runnable() {
- @Override
- public void run() {
- tasks.remove(GetStatus.class);
- tasks.add(new GetStatus());
- }
- };
- statusUpdateFuture = executorService.scheduleWithFixedDelay(updateTask, STATUS_UPDATE_INTERVAL_SECONDS,
- STATUS_UPDATE_INTERVAL_SECONDS, TimeUnit.SECONDS);
- }
-
- private synchronized void stopStatusUpdate() {
- if (statusUpdateFuture != null) {
- statusUpdateFuture.cancel(false);
- statusUpdateFuture = null;
- }
- }
-
- private void processTasks() {
- while (true) {
- JukeboxTask task = null;
- try {
- task = tasks.take();
- JukeboxStatus status = task.execute();
- onStatusUpdate(status);
- } catch (Throwable x) {
- onError(task, x);
- }
- }
- }
-
- private void onStatusUpdate(JukeboxStatus jukeboxStatus) {
- timeOfLastUpdate.set(System.currentTimeMillis());
- this.jukeboxStatus = jukeboxStatus;
-
- // Track change?
- Integer index = jukeboxStatus.getCurrentPlayingIndex();
- if (index != null && index != -1 && index != downloadService.getCurrentPlayingIndex()) {
- downloadService.setPlayerState(PlayerState.COMPLETED);
- downloadService.setCurrentPlaying(index, true);
- downloadService.setPlayerState(PlayerState.STARTED);
- }
- }
-
- private void onError(JukeboxTask task, Throwable x) {
- if (x instanceof ServerTooOldException && !(task instanceof Stop)) {
- disableJukeboxOnError(x, R.string.download_jukebox_server_too_old);
- } else if (x instanceof OfflineException && !(task instanceof Stop)) {
- disableJukeboxOnError(x, R.string.download_jukebox_offline);
- } else if (x instanceof SubsonicRESTException && ((SubsonicRESTException) x).getCode() == 50 && !(task instanceof Stop)) {
- disableJukeboxOnError(x, R.string.download_jukebox_not_authorized);
- } else {
- Log.e(TAG, "Failed to process jukebox task: " + x, x);
- }
- }
-
- private void disableJukeboxOnError(Throwable x, final int resourceId) {
- Log.w(TAG, x.toString());
- handler.post(new Runnable() {
- @Override
- public void run() {
- Util.toast(downloadService, resourceId, false);
- }
- });
- downloadService.setRemoteEnabled(RemoteControlState.LOCAL);
- }
-
- public void updatePlaylist() {
- tasks.remove(Skip.class);
- tasks.remove(Stop.class);
- tasks.remove(Start.class);
-
- List<String> ids = new ArrayList<String>();
- for (DownloadFile file : downloadService.getDownloads()) {
- ids.add(file.getSong().getId());
- }
- tasks.add(new SetPlaylist(ids));
- }
-
- public void skip(final int index, final int offsetSeconds) {
- tasks.remove(Skip.class);
- tasks.remove(Stop.class);
- tasks.remove(Start.class);
-
- startStatusUpdate();
- if (jukeboxStatus != null) {
- jukeboxStatus.setPositionSeconds(offsetSeconds);
- }
- tasks.add(new Skip(index, offsetSeconds));
- downloadService.setPlayerState(PlayerState.STARTED);
- }
-
- public void stop() {
- tasks.remove(Stop.class);
- tasks.remove(Start.class);
-
- stopStatusUpdate();
- tasks.add(new Stop());
- }
-
- public void start() {
- tasks.remove(Stop.class);
- tasks.remove(Start.class);
-
- startStatusUpdate();
- tasks.add(new Start());
- }
-
- public synchronized void adjustVolume(boolean up) {
- float delta = up ? 0.1f : -0.1f;
- gain += delta;
- gain = Math.max(gain, 0.0f);
- gain = Math.min(gain, 1.0f);
-
- tasks.remove(SetGain.class);
- tasks.add(new SetGain(gain));
-
- if (volumeToast == null) {
- volumeToast = new VolumeToast(downloadService);
- }
- volumeToast.setVolume(gain);
- }
-
- private MusicService getMusicService() {
- return MusicServiceFactory.getMusicService(downloadService);
- }
-
- public int getPositionSeconds() {
- if (jukeboxStatus == null || jukeboxStatus.getPositionSeconds() == null || timeOfLastUpdate.get() == 0) {
- return 0;
- }
-
- if (jukeboxStatus.isPlaying()) {
- int secondsSinceLastUpdate = (int) ((System.currentTimeMillis() - timeOfLastUpdate.get()) / 1000L);
- return jukeboxStatus.getPositionSeconds() + secondsSinceLastUpdate;
- }
-
- return jukeboxStatus.getPositionSeconds();
- }
-
- public void setEnabled(boolean enabled) {
- tasks.clear();
- if (enabled) {
- updatePlaylist();
- }
- stop();
- downloadService.setPlayerState(PlayerState.IDLE);
- }
-
- private static class TaskQueue {
-
- private final LinkedBlockingQueue<JukeboxTask> queue = new LinkedBlockingQueue<JukeboxTask>();
-
- void add(JukeboxTask jukeboxTask) {
- queue.add(jukeboxTask);
- }
-
- JukeboxTask take() throws InterruptedException {
- return queue.take();
- }
-
- void remove(Class<? extends JukeboxTask> clazz) {
- try {
- Iterator<JukeboxTask> iterator = queue.iterator();
- while (iterator.hasNext()) {
- JukeboxTask task = iterator.next();
- if (clazz.equals(task.getClass())) {
- iterator.remove();
- }
- }
- } catch (Throwable x) {
- Log.w(TAG, "Failed to clean-up task queue.", x);
- }
- }
-
- void clear() {
- queue.clear();
- }
- }
-
- private abstract class JukeboxTask {
-
- abstract JukeboxStatus execute() throws Exception;
-
- @Override
- public String toString() {
- return getClass().getSimpleName();
- }
- }
-
- private class GetStatus extends JukeboxTask {
- @Override
- JukeboxStatus execute() throws Exception {
- return getMusicService().getJukeboxStatus(downloadService, null);
- }
- }
-
- private class SetPlaylist extends JukeboxTask {
-
- private final List<String> ids;
-
- SetPlaylist(List<String> ids) {
- this.ids = ids;
- }
-
- @Override
- JukeboxStatus execute() throws Exception {
- return getMusicService().updateJukeboxPlaylist(ids, downloadService, null);
- }
- }
-
- private class Skip extends JukeboxTask {
- private final int index;
- private final int offsetSeconds;
-
- Skip(int index, int offsetSeconds) {
- this.index = index;
- this.offsetSeconds = offsetSeconds;
- }
-
- @Override
- JukeboxStatus execute() throws Exception {
- return getMusicService().skipJukebox(index, offsetSeconds, downloadService, null);
- }
- }
-
- private class Stop extends JukeboxTask {
- @Override
- JukeboxStatus execute() throws Exception {
- return getMusicService().stopJukebox(downloadService, null);
- }
- }
-
- private class Start extends JukeboxTask {
- @Override
- JukeboxStatus execute() throws Exception {
- return getMusicService().startJukebox(downloadService, null);
- }
- }
-
- private class SetGain extends JukeboxTask {
-
- private final float gain;
-
- private SetGain(float gain) {
- this.gain = gain;
- }
-
- @Override
- JukeboxStatus execute() throws Exception {
- return getMusicService().setJukeboxGain(gain, downloadService, null);
- }
- }
-
- private static class VolumeToast extends Toast {
-
- private final ProgressBar progressBar;
-
- public VolumeToast(Context context) {
- super(context);
- setDuration(Toast.LENGTH_SHORT);
- LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- View view = inflater.inflate(R.layout.jukebox_volume, null);
- progressBar = (ProgressBar) view.findViewById(R.id.jukebox_volume_progress_bar);
-
- setView(view);
- setGravity(Gravity.TOP, 0, 0);
- }
-
- public void setVolume(float volume) {
- progressBar.setProgress(Math.round(100 * volume));
- show();
- }
- }
-}
diff --git a/src/github/daneren2005/dsub/service/MusicService.java b/src/github/daneren2005/dsub/service/MusicService.java
index 7aa878ab..cae307cb 100644
--- a/src/github/daneren2005/dsub/service/MusicService.java
+++ b/src/github/daneren2005/dsub/service/MusicService.java
@@ -27,13 +27,12 @@ import android.graphics.Bitmap;
import github.daneren2005.dsub.domain.ChatMessage;
import github.daneren2005.dsub.domain.Genre;
import github.daneren2005.dsub.domain.Indexes;
-import github.daneren2005.dsub.domain.JukeboxStatus;
+import github.daneren2005.dsub.domain.RemoteStatus;
import github.daneren2005.dsub.domain.Lyrics;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.MusicFolder;
import github.daneren2005.dsub.domain.Playlist;
import github.daneren2005.dsub.domain.PodcastChannel;
-import github.daneren2005.dsub.domain.PodcastEpisode;
import github.daneren2005.dsub.domain.SearchCritera;
import github.daneren2005.dsub.domain.SearchResult;
import github.daneren2005.dsub.domain.Share;
@@ -98,17 +97,17 @@ public interface MusicService {
String getHlsUrl(String id, int bitRate, Context context) throws Exception;
- JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception;
+ RemoteStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception;
- JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception;
+ RemoteStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception;
- JukeboxStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception;
+ RemoteStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception;
- JukeboxStatus startJukebox(Context context, ProgressListener progressListener) throws Exception;
+ RemoteStatus startJukebox(Context context, ProgressListener progressListener) throws Exception;
- JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception;
+ RemoteStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception;
- JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception;
+ RemoteStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception;
void setStarred(String id, boolean starred, Context context, ProgressListener progressListener) throws Exception;
diff --git a/src/github/daneren2005/dsub/service/OfflineMusicService.java b/src/github/daneren2005/dsub/service/OfflineMusicService.java
index 22fdcd9b..1221df5c 100644
--- a/src/github/daneren2005/dsub/service/OfflineMusicService.java
+++ b/src/github/daneren2005/dsub/service/OfflineMusicService.java
@@ -37,13 +37,12 @@ import android.util.Log;
import github.daneren2005.dsub.domain.Artist;
import github.daneren2005.dsub.domain.Genre;
import github.daneren2005.dsub.domain.Indexes;
-import github.daneren2005.dsub.domain.JukeboxStatus;
+import github.daneren2005.dsub.domain.RemoteStatus;
import github.daneren2005.dsub.domain.Lyrics;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.MusicFolder;
import github.daneren2005.dsub.domain.Playlist;
import github.daneren2005.dsub.domain.PodcastChannel;
-import github.daneren2005.dsub.domain.PodcastEpisode;
import github.daneren2005.dsub.domain.SearchCritera;
import github.daneren2005.dsub.domain.SearchResult;
import github.daneren2005.dsub.util.Constants;
@@ -523,32 +522,32 @@ public class OfflineMusicService extends RESTMusicService {
}
@Override
- public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception {
throw new OfflineException("Jukebox not available in offline mode");
}
@Override
- public JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception {
throw new OfflineException("Jukebox not available in offline mode");
}
@Override
- public JukeboxStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception {
throw new OfflineException("Jukebox not available in offline mode");
}
@Override
- public JukeboxStatus startJukebox(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus startJukebox(Context context, ProgressListener progressListener) throws Exception {
throw new OfflineException("Jukebox not available in offline mode");
}
@Override
- public JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception {
throw new OfflineException("Jukebox not available in offline mode");
}
@Override
- public JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception {
throw new OfflineException("Jukebox not available in offline mode");
}
diff --git a/src/github/daneren2005/dsub/service/RESTMusicService.java b/src/github/daneren2005/dsub/service/RESTMusicService.java
index 17f26ea1..82148dc0 100644
--- a/src/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/src/github/daneren2005/dsub/service/RESTMusicService.java
@@ -22,9 +22,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
-import java.io.FileReader;
import java.io.OutputStream;
-import java.io.OutputStreamWriter;
import java.io.Reader;
import java.net.URLEncoder;
import java.util.ArrayList;
@@ -71,7 +69,6 @@ import android.net.NetworkInfo;
import android.util.Log;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.*;
-import github.daneren2005.dsub.domain.MusicDirectory.Entry;
import github.daneren2005.dsub.service.parser.AlbumListParser;
import github.daneren2005.dsub.service.parser.ChatMessageParser;
import github.daneren2005.dsub.service.parser.ErrorParser;
@@ -740,7 +737,7 @@ public class RESTMusicService implements MusicService {
}
@Override
- public JukeboxStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus updateJukeboxPlaylist(List<String> ids, Context context, ProgressListener progressListener) throws Exception {
int n = ids.size();
List<String> parameterNames = new ArrayList<String>(n + 1);
parameterNames.add("action");
@@ -755,36 +752,40 @@ public class RESTMusicService implements MusicService {
}
@Override
- public JukeboxStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus skipJukebox(int index, int offsetSeconds, Context context, ProgressListener progressListener) throws Exception {
List<String> parameterNames = Arrays.asList("action", "index", "offset");
List<Object> parameterValues = Arrays.<Object>asList("skip", index, offsetSeconds);
+ if(index < 0) {
+ parameterNames.remove(1);
+ parameterValues.remove(1);
+ }
return executeJukeboxCommand(context, progressListener, parameterNames, parameterValues);
}
@Override
- public JukeboxStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus stopJukebox(Context context, ProgressListener progressListener) throws Exception {
return executeJukeboxCommand(context, progressListener, Arrays.asList("action"), Arrays.<Object>asList("stop"));
}
@Override
- public JukeboxStatus startJukebox(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus startJukebox(Context context, ProgressListener progressListener) throws Exception {
return executeJukeboxCommand(context, progressListener, Arrays.asList("action"), Arrays.<Object>asList("start"));
}
@Override
- public JukeboxStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus getJukeboxStatus(Context context, ProgressListener progressListener) throws Exception {
return executeJukeboxCommand(context, progressListener, Arrays.asList("action"), Arrays.<Object>asList("status"));
}
@Override
- public JukeboxStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception {
+ public RemoteStatus setJukeboxGain(float gain, Context context, ProgressListener progressListener) throws Exception {
List<String> parameterNames = Arrays.asList("action", "gain");
List<Object> parameterValues = Arrays.<Object>asList("setGain", gain);
return executeJukeboxCommand(context, progressListener, parameterNames, parameterValues);
}
- private JukeboxStatus executeJukeboxCommand(Context context, ProgressListener progressListener, List<String> parameterNames, List<Object> parameterValues) throws Exception {
+ private RemoteStatus executeJukeboxCommand(Context context, ProgressListener progressListener, List<String> parameterNames, List<Object> parameterValues) throws Exception {
checkServerVersion(context, "1.7", "Jukebox not supported.");
Reader reader = getReader(context, progressListener, "jukeboxControl", null, parameterNames, parameterValues);
try {
diff --git a/src/github/daneren2005/dsub/service/RemoteController.java b/src/github/daneren2005/dsub/service/RemoteController.java
index 717c2c72..f2b8f20d 100644
--- a/src/github/daneren2005/dsub/service/RemoteController.java
+++ b/src/github/daneren2005/dsub/service/RemoteController.java
@@ -20,19 +20,27 @@
package github.daneren2005.dsub.service;
import android.content.Context;
+import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.Toast;
+
+import java.util.Iterator;
+import java.util.concurrent.LinkedBlockingQueue;
+
import github.daneren2005.dsub.R;
+import github.daneren2005.dsub.domain.RemoteStatus;
public abstract class RemoteController {
+ private static final String TAG = RemoteController.class.getSimpleName();
protected DownloadServiceImpl downloadService;
private VolumeToast volumeToast;
-
+
public abstract void start();
public abstract void stop();
+ public abstract void shutdown();
public abstract void updatePlaylist();
public abstract void changePosition(int seconds);
@@ -40,6 +48,45 @@ public abstract class RemoteController {
public abstract void setVolume(boolean up);
public abstract int getRemotePosition();
+
+ protected abstract class RemoteTask {
+ abstract RemoteStatus execute() throws Exception;
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName();
+ }
+ }
+
+ protected static class TaskQueue {
+ private final LinkedBlockingQueue<RemoteTask> queue = new LinkedBlockingQueue<RemoteTask>();
+
+ void add(RemoteTask jukeboxTask) {
+ queue.add(jukeboxTask);
+ }
+
+ RemoteTask take() throws InterruptedException {
+ return queue.take();
+ }
+
+ void remove(Class<? extends RemoteTask> clazz) {
+ try {
+ Iterator<RemoteTask> iterator = queue.iterator();
+ while (iterator.hasNext()) {
+ RemoteTask task = iterator.next();
+ if (clazz.equals(task.getClass())) {
+ iterator.remove();
+ }
+ }
+ } catch (Throwable x) {
+ Log.w(TAG, "Failed to clean-up task queue.", x);
+ }
+ }
+
+ void clear() {
+ queue.clear();
+ }
+ }
protected VolumeToast getVolumeToast() {
if(volumeToast == null) {
@@ -48,7 +95,7 @@ public abstract class RemoteController {
return volumeToast;
}
- public static class VolumeToast extends Toast {
+ protected static class VolumeToast extends Toast {
private final ProgressBar progressBar;
public VolumeToast(Context context) {
diff --git a/src/github/daneren2005/dsub/service/parser/JukeboxStatusParser.java b/src/github/daneren2005/dsub/service/parser/JukeboxStatusParser.java
index 8526e635..b7fc2f3f 100644
--- a/src/github/daneren2005/dsub/service/parser/JukeboxStatusParser.java
+++ b/src/github/daneren2005/dsub/service/parser/JukeboxStatusParser.java
@@ -23,7 +23,7 @@ import java.io.Reader;
import org.xmlpull.v1.XmlPullParser;
import android.content.Context;
-import github.daneren2005.dsub.domain.JukeboxStatus;
+import github.daneren2005.dsub.domain.RemoteStatus;
/**
* @author Sindre Mehus
@@ -34,11 +34,11 @@ public class JukeboxStatusParser extends AbstractParser {
super(context);
}
- public JukeboxStatus parse(Reader reader) throws Exception {
+ public RemoteStatus parse(Reader reader) throws Exception {
init(reader);
- JukeboxStatus jukeboxStatus = new JukeboxStatus();
+ RemoteStatus jukeboxStatus = new RemoteStatus();
int eventType;
do {
eventType = nextParseEvent();