aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorScott Jackson <daneren2005@gmail.com>2015-03-14 21:13:17 -0700
committerScott Jackson <daneren2005@gmail.com>2015-03-14 21:13:17 -0700
commit85456d948366fcf564499c88a0d83291cde23a34 (patch)
treeb0c886f1a242b09e6cdd67bb9aeea6656edab337 /src
parent07cdb62bb7cddcf9cbe499cf3d05e29b4be34644 (diff)
downloaddsub-85456d948366fcf564499c88a0d83291cde23a34.tar.gz
dsub-85456d948366fcf564499c88a0d83291cde23a34.tar.bz2
dsub-85456d948366fcf564499c88a0d83291cde23a34.zip
#428 Start of handoff logic. For now just saves current playing queue
Diffstat (limited to 'src')
-rw-r--r--src/github/daneren2005/dsub/domain/PlayerQueue.java30
-rw-r--r--src/github/daneren2005/dsub/provider/DSubWidgetProvider.java3
-rw-r--r--src/github/daneren2005/dsub/service/CachedMusicService.java11
-rw-r--r--src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java52
-rw-r--r--src/github/daneren2005/dsub/service/MusicService.java5
-rw-r--r--src/github/daneren2005/dsub/service/OfflineMusicService.java11
-rw-r--r--src/github/daneren2005/dsub/service/RESTMusicService.java35
-rw-r--r--src/github/daneren2005/dsub/service/parser/PlayQueueParser.java81
8 files changed, 215 insertions, 13 deletions
diff --git a/src/github/daneren2005/dsub/domain/PlayerQueue.java b/src/github/daneren2005/dsub/domain/PlayerQueue.java
new file mode 100644
index 00000000..32f29725
--- /dev/null
+++ b/src/github/daneren2005/dsub/domain/PlayerQueue.java
@@ -0,0 +1,30 @@
+/*
+ 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 2015 (C) Scott Jackson
+*/
+
+package github.daneren2005.dsub.domain;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+public class PlayerQueue implements Serializable {
+ public List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>();
+ public List<MusicDirectory.Entry> toDelete = new ArrayList<MusicDirectory.Entry>();
+ public int currentPlayingIndex;
+ public int currentPlayingPosition;
+ public boolean renameCurrent = false;
+ public Date changed = null;
+}
diff --git a/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java b/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java
index 0bf0fe9d..444b6cff 100644
--- a/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java
+++ b/src/github/daneren2005/dsub/provider/DSubWidgetProvider.java
@@ -43,6 +43,7 @@ import github.daneren2005.dsub.activity.DownloadActivity;
import github.daneren2005.dsub.activity.SubsonicActivity;
import github.daneren2005.dsub.activity.SubsonicFragmentActivity;
import github.daneren2005.dsub.domain.MusicDirectory;
+import github.daneren2005.dsub.domain.PlayerQueue;
import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.service.DownloadServiceLifecycleSupport;
import github.daneren2005.dsub.util.Constants;
@@ -165,7 +166,7 @@ public class DSubWidgetProvider extends AppWidgetProvider {
MusicDirectory.Entry currentPlaying = null;
if(service == null) {
// Deserialize from playling list to setup
- DownloadServiceLifecycleSupport.State state = FileUtil.deserialize(context, DownloadServiceLifecycleSupport.FILENAME_DOWNLOADS_SER, DownloadServiceLifecycleSupport.State.class);
+ PlayerQueue state = FileUtil.deserialize(context, DownloadServiceLifecycleSupport.FILENAME_DOWNLOADS_SER, PlayerQueue.class);
if(state != null && state.currentPlayingIndex != -1) {
currentPlaying = state.songs.get(state.currentPlayingIndex);
}
diff --git a/src/github/daneren2005/dsub/service/CachedMusicService.java b/src/github/daneren2005/dsub/service/CachedMusicService.java
index 79399483..9d3444cb 100644
--- a/src/github/daneren2005/dsub/service/CachedMusicService.java
+++ b/src/github/daneren2005/dsub/service/CachedMusicService.java
@@ -37,6 +37,7 @@ import github.daneren2005.dsub.domain.Bookmark;
import github.daneren2005.dsub.domain.ChatMessage;
import github.daneren2005.dsub.domain.Genre;
import github.daneren2005.dsub.domain.Indexes;
+import github.daneren2005.dsub.domain.PlayerQueue;
import github.daneren2005.dsub.domain.PodcastEpisode;
import github.daneren2005.dsub.domain.RemoteStatus;
import github.daneren2005.dsub.domain.Lyrics;
@@ -924,6 +925,16 @@ public class CachedMusicService implements MusicService {
}
@Override
+ public void savePlayQueue(List<Entry> songs, Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception {
+ musicService.savePlayQueue(songs, currentPlaying, position, context, progressListener);
+ }
+
+ @Override
+ public PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception {
+ return musicService.getPlayQueue(context, progressListener);
+ }
+
+ @Override
public int processOfflineSyncs(final Context context, final ProgressListener progressListener) throws Exception{
return musicService.processOfflineSyncs(context, progressListener);
}
diff --git a/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java b/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java
index afcea3e5..8af16a76 100644
--- a/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java
+++ b/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java
@@ -20,6 +20,7 @@ package github.daneren2005.dsub.service;
import java.io.Serializable;
import java.util.ArrayList;
+import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -37,10 +38,14 @@ import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.KeyEvent;
import github.daneren2005.dsub.domain.MusicDirectory;
+import github.daneren2005.dsub.domain.PlayerQueue;
import github.daneren2005.dsub.domain.PlayerState;
+import github.daneren2005.dsub.domain.ServerInfo;
+import github.daneren2005.dsub.util.BackgroundTask;
import github.daneren2005.dsub.util.CacheCleaner;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.FileUtil;
+import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.Util;
import static github.daneren2005.dsub.domain.PlayerState.PREPARING;
@@ -61,6 +66,7 @@ public class DownloadServiceLifecycleSupport {
private ReentrantLock lock = new ReentrantLock();
private final AtomicBoolean setup = new AtomicBoolean(false);
private long lastPressTime = 0;
+ private SilentBackgroundTask<Void> currentSavePlayQueueTask = null;
/**
* This receiver manages the intent that could come from other applications.
@@ -272,7 +278,7 @@ public class DownloadServiceLifecycleSupport {
}
public void serializeDownloadQueueNow(List<DownloadFile> songs) {
- State state = new State();
+ final PlayerQueue state = new PlayerQueue();
for (DownloadFile downloadFile : songs) {
state.songs.add(downloadFile.getSong());
}
@@ -286,9 +292,41 @@ public class DownloadServiceLifecycleSupport {
if(currentPlaying != null) {
state.renameCurrent = currentPlaying.isWorkDone() && !currentPlaying.isCompleteFileAvailable();
}
+ state.changed = new Date();
Log.i(TAG, "Serialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition);
FileUtil.serialize(downloadService, state, FILENAME_DOWNLOADS_SER);
+
+ // If we are on Subsonic 5.2+, save play queue
+ if(ServerInfo.checkServerVersion(downloadService, "1.12") && !ServerInfo.isMadsonic(downloadService) && !Util.isOffline(downloadService) && state.songs.size() > 0) {
+ // Cancel any currently running tasks
+ if(currentSavePlayQueueTask != null) {
+ currentSavePlayQueueTask.cancel();
+ }
+
+ currentSavePlayQueueTask = new SilentBackgroundTask<Void>(downloadService) {
+ @Override
+ protected Void doInBackground() throws Throwable {
+ try {
+ MusicService musicService = MusicServiceFactory.getMusicService(downloadService);
+ musicService.savePlayQueue(state.songs, state.songs.get(state.currentPlayingIndex), state.currentPlayingPosition, downloadService, null);
+ currentSavePlayQueueTask = null;
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to save playing queue to server", e);
+ currentSavePlayQueueTask = null;
+ }
+
+ return null;
+ }
+
+ @Override
+ protected void error(Throwable error) {
+ currentSavePlayQueueTask = null;
+ super.error(error);
+ }
+ };
+ currentSavePlayQueueTask.execute();
+ }
}
public void post(Runnable runnable) {
@@ -296,7 +334,7 @@ public class DownloadServiceLifecycleSupport {
}
private void deserializeDownloadQueueNow() {
- State state = FileUtil.deserialize(downloadService, FILENAME_DOWNLOADS_SER, State.class);
+ PlayerQueue state = FileUtil.deserialize(downloadService, FILENAME_DOWNLOADS_SER, PlayerQueue.class);
if (state == null) {
return;
}
@@ -399,14 +437,4 @@ public class DownloadServiceLifecycleSupport {
});
}
}
-
- public static class State implements Serializable {
- private static final long serialVersionUID = -6346438781062572271L;
-
- public List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>();
- public List<MusicDirectory.Entry> toDelete = new ArrayList<MusicDirectory.Entry>();
- public int currentPlayingIndex;
- public int currentPlayingPosition;
- public boolean renameCurrent = false;
- }
}
diff --git a/src/github/daneren2005/dsub/service/MusicService.java b/src/github/daneren2005/dsub/service/MusicService.java
index b4b99911..95b1bde6 100644
--- a/src/github/daneren2005/dsub/service/MusicService.java
+++ b/src/github/daneren2005/dsub/service/MusicService.java
@@ -30,6 +30,7 @@ import github.daneren2005.dsub.domain.Bookmark;
import github.daneren2005.dsub.domain.ChatMessage;
import github.daneren2005.dsub.domain.Genre;
import github.daneren2005.dsub.domain.Indexes;
+import github.daneren2005.dsub.domain.PlayerQueue;
import github.daneren2005.dsub.domain.RemoteStatus;
import github.daneren2005.dsub.domain.Lyrics;
import github.daneren2005.dsub.domain.MusicDirectory;
@@ -185,6 +186,10 @@ public interface MusicService {
Bitmap getBitmap(String url, int size, Context context, ProgressListener progressListener, SilentBackgroundTask task) throws Exception;
MusicDirectory getVideos(boolean refresh, Context context, ProgressListener progressListener) throws Exception;
+
+ void savePlayQueue(List<MusicDirectory.Entry> songs, MusicDirectory.Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception;
+
+ PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception;
int processOfflineSyncs(final Context context, final ProgressListener progressListener) throws Exception;
diff --git a/src/github/daneren2005/dsub/service/OfflineMusicService.java b/src/github/daneren2005/dsub/service/OfflineMusicService.java
index c66ba598..8b38d061 100644
--- a/src/github/daneren2005/dsub/service/OfflineMusicService.java
+++ b/src/github/daneren2005/dsub/service/OfflineMusicService.java
@@ -41,6 +41,7 @@ import github.daneren2005.dsub.domain.ArtistInfo;
import github.daneren2005.dsub.domain.ChatMessage;
import github.daneren2005.dsub.domain.Genre;
import github.daneren2005.dsub.domain.Indexes;
+import github.daneren2005.dsub.domain.PlayerQueue;
import github.daneren2005.dsub.domain.PodcastEpisode;
import github.daneren2005.dsub.domain.RemoteStatus;
import github.daneren2005.dsub.domain.Lyrics;
@@ -804,6 +805,16 @@ public class OfflineMusicService implements MusicService {
}
@Override
+ public void savePlayQueue(List<MusicDirectory.Entry> songs, MusicDirectory.Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception {
+ throw new OfflineException(ERRORMSG);
+ }
+
+ @Override
+ public PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception {
+ throw new OfflineException(ERRORMSG);
+ }
+
+ @Override
public int processOfflineSyncs(final Context context, final ProgressListener progressListener) throws Exception{
throw new OfflineException(ERRORMSG);
}
diff --git a/src/github/daneren2005/dsub/service/RESTMusicService.java b/src/github/daneren2005/dsub/service/RESTMusicService.java
index 6caf2ade..de60ae12 100644
--- a/src/github/daneren2005/dsub/service/RESTMusicService.java
+++ b/src/github/daneren2005/dsub/service/RESTMusicService.java
@@ -81,6 +81,7 @@ import github.daneren2005.dsub.service.parser.LicenseParser;
import github.daneren2005.dsub.service.parser.LyricsParser;
import github.daneren2005.dsub.service.parser.MusicDirectoryParser;
import github.daneren2005.dsub.service.parser.MusicFoldersParser;
+import github.daneren2005.dsub.service.parser.PlayQueueParser;
import github.daneren2005.dsub.service.parser.PlaylistParser;
import github.daneren2005.dsub.service.parser.PlaylistsParser;
import github.daneren2005.dsub.service.parser.PodcastChannelParser;
@@ -1549,6 +1550,40 @@ public class RESTMusicService implements MusicService {
}
@Override
+ public void savePlayQueue(List<MusicDirectory.Entry> songs, MusicDirectory.Entry currentPlaying, int position, Context context, ProgressListener progressListener) throws Exception {
+ List<String> parameterNames = new LinkedList<String>();
+ List<Object> parameterValues = new LinkedList<Object>();
+
+ for(MusicDirectory.Entry song: songs) {
+ parameterNames.add("id");
+ parameterValues.add(song.getId());
+ }
+
+ parameterNames.add("current");
+ parameterValues.add(currentPlaying.getId());
+
+ parameterNames.add("position");
+ parameterValues.add(position);
+
+ Reader reader = getReader(context, progressListener, "savePlayQueue", null, parameterNames, parameterValues);
+ try {
+ new ErrorParser(context, getInstance(context)).parse(reader);
+ } finally {
+ Util.close(reader);
+ }
+ }
+
+ @Override
+ public PlayerQueue getPlayQueue(Context context, ProgressListener progressListener) throws Exception {
+ Reader reader = getReader(context, progressListener, "getPlayQueue", null);
+ try {
+ return new PlayQueueParser(context, getInstance(context)).parse(reader, progressListener);
+ } finally {
+ Util.close(reader);
+ }
+ }
+
+ @Override
public int processOfflineSyncs(final Context context, final ProgressListener progressListener) throws Exception{
return processOfflineScrobbles(context, progressListener) + processOfflineStars(context, progressListener);
}
diff --git a/src/github/daneren2005/dsub/service/parser/PlayQueueParser.java b/src/github/daneren2005/dsub/service/parser/PlayQueueParser.java
new file mode 100644
index 00000000..7dc62105
--- /dev/null
+++ b/src/github/daneren2005/dsub/service/parser/PlayQueueParser.java
@@ -0,0 +1,81 @@
+/*
+ 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 2015 (C) Scott Jackson
+*/
+
+package github.daneren2005.dsub.service.parser;
+
+import android.content.Context;
+
+import org.xmlpull.v1.XmlPullParser;
+
+import java.io.Reader;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Locale;
+
+import github.daneren2005.dsub.domain.MusicDirectory;
+import github.daneren2005.dsub.domain.PlayerQueue;
+import github.daneren2005.dsub.util.ProgressListener;
+
+public class PlayQueueParser extends MusicDirectoryEntryParser {
+ public PlayQueueParser(Context context, int instance) {
+ super(context, instance);
+ }
+
+ public PlayerQueue parse(Reader reader, ProgressListener progressListener) throws Exception {
+ init(reader);
+
+ PlayerQueue state = new PlayerQueue();
+ String currentId = null;
+ String changed = null;
+ int eventType;
+ do {
+ eventType = nextParseEvent();
+ if (eventType == XmlPullParser.START_TAG) {
+ String name = getElementName();
+ if("playQueue".equals(name)) {
+ currentId = get("current");
+ state.currentPlayingPosition = getInteger("position");
+ try {
+ state.changed = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss", Locale.ENGLISH).parse(get("changed"));
+ } catch (ParseException e) {
+ state.changed = null;
+ }
+ } else if ("entry".equals(name)) {
+ MusicDirectory.Entry entry = parseEntry("");
+ // Only add songs
+ if(!entry.isVideo()) {
+ state.songs.add(entry);
+ }
+ } else if ("error".equals(name)) {
+ handleError();
+ }
+ }
+ } while (eventType != XmlPullParser.END_DOCUMENT);
+
+ if(currentId != null) {
+ for (MusicDirectory.Entry entry : state.songs) {
+ if (entry.getId().equals(currentId)) {
+ state.currentPlayingIndex = state.songs.indexOf(entry);
+ }
+ }
+ } else {
+ state.currentPlayingIndex = 0;
+ state.currentPlayingPosition = 0;
+ }
+
+ validate();
+ return state;
+ }
+}