diff options
Diffstat (limited to 'app/src/main/java/github')
5 files changed, 98 insertions, 54 deletions
diff --git a/app/src/main/java/github/daneren2005/dsub/service/ChromeCastController.java b/app/src/main/java/github/daneren2005/dsub/service/ChromeCastController.java index 7d2b0a07..670ea7d2 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/ChromeCastController.java +++ b/app/src/main/java/github/daneren2005/dsub/service/ChromeCastController.java @@ -483,8 +483,6 @@ public class ChromeCastController extends RemoteController { break; case MediaStatus.PLAYER_STATE_IDLE: if (mediaStatus.getIdleReason() == MediaStatus.IDLE_REASON_FINISHED) { - downloadService.setPlayerState(PlayerState.COMPLETED); - downloadService.postPlayCleanup(); downloadService.onSongCompleted(); } else if (mediaStatus.getIdleReason() == MediaStatus.IDLE_REASON_INTERRUPTED) { if (downloadService.getPlayerState() != PlayerState.PREPARING) { @@ -492,8 +490,7 @@ public class ChromeCastController extends RemoteController { } } else if (mediaStatus.getIdleReason() == MediaStatus.IDLE_REASON_ERROR) { Log.e(TAG, "Idle due to unknown error"); - downloadService.setPlayerState(PlayerState.COMPLETED); - downloadService.next(); + downloadService.onSongCompleted(); } else { Log.w(TAG, "Idle reason: " + mediaStatus.getIdleReason()); downloadService.setPlayerState(PlayerState.IDLE); diff --git a/app/src/main/java/github/daneren2005/dsub/service/DLNAController.java b/app/src/main/java/github/daneren2005/dsub/service/DLNAController.java index 64abce8a..0673cdeb 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/DLNAController.java +++ b/app/src/main/java/github/daneren2005/dsub/service/DLNAController.java @@ -171,11 +171,6 @@ public class DLNAController extends RemoteController { switch (lastChange.getEventedValue(0, AVTransportVariable.TransportState.class).getValue()) { case PLAYING: downloadService.setPlayerState(PlayerState.STARTED); - - // Try to setup next playing after playback start has been registered - if(supportsSetupNext && downloadService.getNextPlayerState() == PlayerState.IDLE) { - downloadService.setNextPlaying(); - } break; case PAUSED_PLAYBACK: downloadService.setPlayerState(PlayerState.PAUSED); @@ -193,8 +188,6 @@ public class DLNAController extends RemoteController { failedLoad(); } else if(downloadService.getPlayerState() == PlayerState.STARTED) { // Played until the end - downloadService.setPlayerState(PlayerState.COMPLETED); - downloadService.postPlayCleanup(); downloadService.onSongCompleted(); } else { downloadService.setPlayerState(PlayerState.STOPPED); @@ -211,7 +204,6 @@ public class DLNAController extends RemoteController { } catch (Exception e) { Log.w(TAG, "Failed to parse UPNP event", e); - failedLoad(); } } @@ -408,7 +400,6 @@ public class DLNAController extends RemoteController { Pair<String, String> songInfo = getSongInfo(currentPlaying); currentPlayingURI = songInfo.getFirst(); - downloadService.setNextPlayerState(PlayerState.IDLE); controlPoint.execute(new SetAVTransportURI(getTransportService(), songInfo.getFirst(), songInfo.getSecond()) { @Override public void success(ActionInvocation invocation) { @@ -637,9 +628,8 @@ public class DLNAController extends RemoteController { currentPosition = (int) positionInfo.getTrackElapsedSeconds(); if(positionInfo.getTrackURI() != null && positionInfo.getTrackURI().equals(nextPlayingURI) && downloadService.getNextPlayerState() == PlayerState.PREPARED) { - downloadService.setCurrentPlaying(nextPlaying, true); - downloadService.setPlayerState(PlayerState.STARTED); - downloadService.setNextPlaying(); + downloadService.onNextStarted(nextPlaying); + nextPlayingURI = null; } downloadService.postDelayed(new Runnable() { diff --git a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java index baff1a72..7c80ca56 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java +++ b/app/src/main/java/github/daneren2005/dsub/service/DownloadService.java @@ -77,6 +77,7 @@ import android.content.SharedPreferences; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.audiofx.AudioEffect; +import android.net.wifi.WifiManager; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -154,6 +155,7 @@ public class DownloadService extends Service { private String suggestedPlaylistName; private String suggestedPlaylistId; private PowerManager.WakeLock wakeLock; + private WifiManager.WifiLock wifiLock; private boolean keepScreenOn; private int cachedPosition = 0; private boolean downloadOngoing = false; @@ -257,6 +259,9 @@ public class DownloadService extends Service { wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName()); wakeLock.setReferenceCounted(false); + WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); + wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "downloadServiceLock"); + try { timerDuration = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_SLEEP_TIMER_DURATION, "5")); } catch(Throwable e) { @@ -401,7 +406,10 @@ public class DownloadService extends Service { offset++; } } - setNextPlaying(); + + if(remoteState == LOCAL || (remoteController != null && remoteController.isNextSupported())) { + setNextPlaying(); + } } else { int size = size(); int index = getCurrentPlayingIndex(); @@ -881,13 +889,13 @@ public class DownloadService extends Service { if(remoteState == LOCAL) { nextPlayingTask = new CheckCompletionTask(nextPlaying); nextPlayingTask.execute(); - } else if(remoteController != null) { + } else if(remoteController != null && remoteController.isNextSupported()) { remoteController.changeNextTrack(nextPlaying); } } else { if(remoteState == LOCAL) { // resetNext(); - } else if(remoteController != null) { + } else if(remoteController != null && remoteController.isNextSupported()) { remoteController.changeNextTrack(nextPlaying); } nextPlaying = null; @@ -1100,11 +1108,14 @@ public class DownloadService extends Service { } mediaPlayer.seekTo(position); - cachedPosition = position; subtractPosition = 0; } + cachedPosition = position; onSongProgress(); + if(playerState == PAUSED) { + lifecycleSupport.serializeDownloadQueue(); + } } catch (Exception x) { handleError(x); } @@ -1183,8 +1194,17 @@ public class DownloadService extends Service { } public void onSongCompleted() { + setPlayerStateCompleted(); + postPlayCleanup(); play(getNextPlayingIndex()); } + public void onNextStarted(DownloadFile nextPlaying) { + setPlayerStateCompleted(); + postPlayCleanup(); + setCurrentPlaying(nextPlaying, true); + setPlayerState(STARTED); + setNextPlayerState(IDLE); + } public synchronized void pause() { pause(false); @@ -1387,15 +1407,6 @@ public class DownloadService extends Service { scrobbler.scrobble(this, currentPlaying, true); } - if(playerState == STARTED && positionCache == null && remoteState == LOCAL) { - positionCache = new LocalPositionCache(); - Thread thread = new Thread(positionCache, "PositionCache"); - thread.start(); - } else if(playerState != STARTED && positionCache != null) { - positionCache.stop(); - positionCache = null; - } - if(playerState == STARTED && positionCache == null) { if(remoteState == LOCAL) { positionCache = new LocalPositionCache(); @@ -1408,6 +1419,39 @@ public class DownloadService extends Service { positionCache.stop(); positionCache = null; } + + + if(remoteState != LOCAL) { + if(playerState == STARTED) { + if (!wifiLock.isHeld()) { + wifiLock.acquire(); + } + } else if(playerState == PAUSED && wifiLock.isHeld()) { + wifiLock.release(); + } + } + + if(remoteController != null && remoteController.isNextSupported()) { + if(playerState == PREPARING || playerState == IDLE) { + nextPlayerState = IDLE; + } + } + + onStateUpdate(); + } + + public void setPlayerStateCompleted() { + // Acquire a temporary wakelock + acquireWakelock(); + + Log.i(TAG, this.playerState.name() + " -> " + PlayerState.COMPLETED + " (" + currentPlaying + ")"); + this.playerState = PlayerState.COMPLETED; + if(positionCache != null) { + positionCache.stop(); + positionCache = null; + } + scrobbler.scrobble(this, currentPlaying, true); + onStateUpdate(); } @@ -1477,16 +1521,6 @@ public class DownloadService extends Service { } } - private void setPlayerStateCompleted() { - Log.i(TAG, this.playerState.name() + " -> " + PlayerState.COMPLETED + " (" + currentPlaying + ")"); - this.playerState = PlayerState.COMPLETED; - if(positionCache != null) { - positionCache.stop(); - positionCache = null; - } - scrobbler.scrobble(this, currentPlaying, true); - } - public synchronized void setNextPlayerState(PlayerState playerState) { Log.i(TAG, "Next: " + this.nextPlayerState.name() + " -> " + playerState.name() + " (" + nextPlaying + ")"); this.nextPlayerState = playerState; @@ -1628,9 +1662,20 @@ public class DownloadService extends Service { remoteController = (RemoteController) ref; break; case LOCAL: default: + if(wifiLock.isHeld()) { + wifiLock.release(); + } break; } + if(remoteState != LOCAL) { + if(!wifiLock.isHeld()) { + wifiLock.acquire(); + } + } else if(wifiLock.isHeld()) { + wifiLock.release(); + } + if(remoteController != null) { remoteController.create(isPlaying, position / 1000); } else { @@ -1906,11 +1951,6 @@ public class DownloadService extends Service { mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { - // Acquire a temporary wakelock, since when we return from - // this callback the MediaPlayer will release its wakelock - // and allow the device to go to sleep. - wakeLock.acquire(30000); - setPlayerStateCompleted(); int pos = getPlayerPosition(); @@ -2566,6 +2606,12 @@ public class DownloadService extends Service { } }); } + public void acquireWakelock() { + acquireWakelock(30000); + } + public void acquireWakelock(int ms) { + wakeLock.acquire(ms); + } public void addOnSongChangedListener(OnSongChangedListener listener) { addOnSongChangedListener(listener, false); @@ -2664,6 +2710,13 @@ public class DownloadService extends Service { } }); } + + // Setup next playing at least a couple of seconds into the song since both Chromecast and some DLNA clients report PLAYING when still PREPARING + if(position > 2000 && remoteController != null && remoteController.isNextSupported()) { + if(playerState == STARTED && nextPlayerState == IDLE) { + setNextPlaying(); + } + } } private void onStateUpdate() { final long atRevision = revision; diff --git a/app/src/main/java/github/daneren2005/dsub/service/RemoteController.java b/app/src/main/java/github/daneren2005/dsub/service/RemoteController.java index cac28c09..99502f5e 100644 --- a/app/src/main/java/github/daneren2005/dsub/service/RemoteController.java +++ b/app/src/main/java/github/daneren2005/dsub/service/RemoteController.java @@ -19,18 +19,11 @@ 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; import github.daneren2005.serverproxy.WebProxy; @@ -48,9 +41,7 @@ public abstract class RemoteController { public abstract void changePosition(int seconds); public abstract void changeTrack(int index, DownloadFile song); // Really is abstract, just don't want to require RemoteController's support it - public void changeNextTrack(DownloadFile song) { - - }; + public void changeNextTrack(DownloadFile song) {} public boolean isNextSupported() { return this.nextSupported; } diff --git a/app/src/main/java/github/daneren2005/dsub/util/SettingsBackupAgent.java b/app/src/main/java/github/daneren2005/dsub/util/SettingsBackupAgent.java index 7eb6d137..def97cac 100644 --- a/app/src/main/java/github/daneren2005/dsub/util/SettingsBackupAgent.java +++ b/app/src/main/java/github/daneren2005/dsub/util/SettingsBackupAgent.java @@ -19,13 +19,26 @@ package github.daneren2005.dsub.util; import android.app.backup.BackupAgentHelper; +import android.app.backup.BackupDataInput; import android.app.backup.SharedPreferencesBackupHelper; +import android.os.ParcelFileDescriptor; + +import java.io.IOError; +import java.io.IOException; + import github.daneren2005.dsub.util.Constants; public class SettingsBackupAgent extends BackupAgentHelper { + @Override public void onCreate() { super.onCreate(); SharedPreferencesBackupHelper helper = new SharedPreferencesBackupHelper(this, Constants.PREFERENCES_FILE_NAME); addHelper("mypreferences", helper); } + + @Override + public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException{ + super.onRestore(data, appVersionCode, newState); + Util.getPreferences(this).edit().remove(Constants.PREFERENCES_KEY_CACHE_LOCATION).apply(); + } } |