diff options
Diffstat (limited to 'src')
3 files changed, 1038 insertions, 1038 deletions
diff --git a/src/github/daneren2005/dsub/service/DownloadServiceImpl.java b/src/github/daneren2005/dsub/service/DownloadServiceImpl.java index 79ce52d7..4df94be3 100644 --- a/src/github/daneren2005/dsub/service/DownloadServiceImpl.java +++ b/src/github/daneren2005/dsub/service/DownloadServiceImpl.java @@ -73,83 +73,83 @@ import java.net.URLEncoder; */ public class DownloadServiceImpl extends Service implements DownloadService { - private static final String TAG = DownloadServiceImpl.class.getSimpleName(); - - public static final String CMD_PLAY = "github.daneren2005.dsub.CMD_PLAY"; - public static final String CMD_TOGGLEPAUSE = "github.daneren2005.dsub.CMD_TOGGLEPAUSE"; - public static final String CMD_PAUSE = "github.daneren2005.dsub.CMD_PAUSE"; - public static final String CMD_STOP = "github.daneren2005.dsub.CMD_STOP"; - public static final String CMD_PREVIOUS = "github.daneren2005.dsub.CMD_PREVIOUS"; - public static final String CMD_NEXT = "github.daneren2005.dsub.CMD_NEXT"; - - - private RemoteControlClientHelper mRemoteControl; - - private final IBinder binder = new SimpleServiceBinder<DownloadService>(this); + private static final String TAG = DownloadServiceImpl.class.getSimpleName(); + + public static final String CMD_PLAY = "github.daneren2005.dsub.CMD_PLAY"; + public static final String CMD_TOGGLEPAUSE = "github.daneren2005.dsub.CMD_TOGGLEPAUSE"; + public static final String CMD_PAUSE = "github.daneren2005.dsub.CMD_PAUSE"; + public static final String CMD_STOP = "github.daneren2005.dsub.CMD_STOP"; + public static final String CMD_PREVIOUS = "github.daneren2005.dsub.CMD_PREVIOUS"; + public static final String CMD_NEXT = "github.daneren2005.dsub.CMD_NEXT"; + + + private RemoteControlClientHelper mRemoteControl; + + private final IBinder binder = new SimpleServiceBinder<DownloadService>(this); private Looper mediaPlayerLooper; - private MediaPlayer mediaPlayer; + private MediaPlayer mediaPlayer; private MediaPlayer nextMediaPlayer; private boolean nextSetup = false; private boolean isPartial = true; - private final List<DownloadFile> downloadList = new ArrayList<DownloadFile>(); + private final List<DownloadFile> downloadList = new ArrayList<DownloadFile>(); private final List<DownloadFile> backgroundDownloadList = new ArrayList<DownloadFile>(); private final List<DownloadFile> toDelete = new ArrayList<DownloadFile>(); private final Handler handler = new Handler(); private Handler mediaPlayerHandler; - private final DownloadServiceLifecycleSupport lifecycleSupport = new DownloadServiceLifecycleSupport(this); - private final ShufflePlayBuffer shufflePlayBuffer = new ShufflePlayBuffer(this); + private final DownloadServiceLifecycleSupport lifecycleSupport = new DownloadServiceLifecycleSupport(this); + private final ShufflePlayBuffer shufflePlayBuffer = new ShufflePlayBuffer(this); - 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 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 RemoteController remoteController; - private DownloadFile currentPlaying; + private DownloadFile currentPlaying; private int currentPlayingIndex = -1; private DownloadFile nextPlaying; - private DownloadFile currentDownloading; - private CancellableTask bufferTask; + private DownloadFile currentDownloading; + private CancellableTask bufferTask; private CancellableTask nextPlayingTask; - private PlayerState playerState = IDLE; + private PlayerState playerState = IDLE; private PlayerState nextPlayerState = IDLE; - private boolean shufflePlay; - private long revision; - private static DownloadService instance; - private String suggestedPlaylistName; + private boolean shufflePlay; + private long revision; + private static DownloadService instance; + private String suggestedPlaylistName; private String suggestedPlaylistId; - private PowerManager.WakeLock wakeLock; - private boolean keepScreenOn; + private PowerManager.WakeLock wakeLock; + private boolean keepScreenOn; private int cachedPosition = 0; private long downloadRevision; private boolean downloadOngoing = false; - private static boolean equalizerAvailable; - private static boolean visualizerAvailable; - private EqualizerController equalizerController; - private VisualizerController visualizerController; - private boolean showVisualization; - private RemoteControlState remoteState = RemoteControlState.LOCAL; + private static boolean equalizerAvailable; + private static boolean visualizerAvailable; + private EqualizerController equalizerController; + private VisualizerController visualizerController; + private boolean showVisualization; + private RemoteControlState remoteState = RemoteControlState.LOCAL; private PositionCache positionCache; private StreamProxy proxy; - + private Timer sleepTimer; private int timerDuration; private boolean autoPlayStart = false; - static { + static { if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) { equalizerAvailable = true; visualizerAvailable = true; } - } + } @Override - public void onCreate() { - super.onCreate(); + public void onCreate() { + super.onCreate(); new Thread(new Runnable() { public void run() { Looper.prepare(); - + mediaPlayer = new MediaPlayer(); mediaPlayer.setWakeMode(DownloadServiceImpl.this, PowerManager.PARTIAL_WAKE_LOCK); @@ -160,7 +160,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { return false; } }); - + try { Intent i = new Intent(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION); i.putExtra(AudioEffect.EXTRA_AUDIO_SESSION, mediaPlayer.getAudioSessionId()); @@ -169,26 +169,26 @@ public class DownloadServiceImpl extends Service implements DownloadService { } catch(Throwable e) { // Froyo or lower } - + mediaPlayerLooper = Looper.myLooper(); mediaPlayerHandler = new Handler(mediaPlayerLooper); Looper.loop(); } }).start(); - Util.registerMediaButtonEventReceiver(this); + Util.registerMediaButtonEventReceiver(this); - if (mRemoteControl == null) { - // Use the remote control APIs (if available) to set the playback state - mRemoteControl = RemoteControlClientHelper.createInstance(); - ComponentName mediaButtonReceiverComponent = new ComponentName(getPackageName(), MediaButtonIntentReceiver.class.getName()); - mRemoteControl.register(this, mediaButtonReceiverComponent); - } + if (mRemoteControl == null) { + // Use the remote control APIs (if available) to set the playback state + mRemoteControl = RemoteControlClientHelper.createInstance(); + ComponentName mediaButtonReceiverComponent = new ComponentName(getPackageName(), MediaButtonIntentReceiver.class.getName()); + mRemoteControl.register(this, mediaButtonReceiverComponent); + } PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE); wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this.getClass().getName()); wakeLock.setReferenceCounted(false); - + SharedPreferences prefs = Util.getPreferences(this); try { timerDuration = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_SLEEP_TIMER_DURATION, "5")); @@ -196,7 +196,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { timerDuration = 5; } sleepTimer = null; - + keepScreenOn = prefs.getBoolean(Constants.PREFERENCES_KEY_KEEP_SCREEN_ON, false); instance = this; @@ -209,26 +209,26 @@ public class DownloadServiceImpl extends Service implements DownloadService { getVisualizerController(); showVisualization = true; } - } + } - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - super.onStartCommand(intent, flags, startId); - lifecycleSupport.onStart(intent); - return START_NOT_STICKY; - } + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + super.onStartCommand(intent, flags, startId); + lifecycleSupport.onStart(intent); + return START_NOT_STICKY; + } @Override - public void onDestroy() { - super.onDestroy(); + public void onDestroy() { + super.onDestroy(); instance = null; - + if(currentPlaying != null) currentPlaying.setPlaying(false); if(sleepTimer != null){ sleepTimer.cancel(); sleepTimer.purge(); } - lifecycleSupport.onDestroy(); + lifecycleSupport.onDestroy(); try { Intent i = new Intent(AudioEffect.ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION); @@ -238,24 +238,24 @@ public class DownloadServiceImpl extends Service implements DownloadService { } catch(Throwable e) { // Froyo or lower } - - mediaPlayer.release(); - if(nextMediaPlayer != null) { + + mediaPlayer.release(); + if(nextMediaPlayer != null) { nextMediaPlayer.release(); - } + } mediaPlayerLooper.quit(); - shufflePlayBuffer.shutdown(); - if (equalizerController != null) { - equalizerController.release(); - } - if (visualizerController != null) { - visualizerController.release(); - } - if (mRemoteControl != null) { - mRemoteControl.unregister(this); - mRemoteControl = null; - } - + shufflePlayBuffer.shutdown(); + if (equalizerController != null) { + equalizerController.release(); + } + if (visualizerController != null) { + visualizerController.release(); + } + if (mRemoteControl != null) { + mRemoteControl.unregister(this); + mRemoteControl = null; + } + if(bufferTask != null) { bufferTask.cancel(); } @@ -268,16 +268,16 @@ public class DownloadServiceImpl extends Service implements DownloadService { } Util.hidePlayingNotification(this, this, handler); Util.hideDownloadingNotification(this); - } + } - public static DownloadService getInstance() { - return instance; - } + public static DownloadService getInstance() { + return instance; + } - @Override - public IBinder onBind(Intent intent) { - return binder; - } + @Override + public IBinder onBind(Intent intent) { + return binder; + } @Override public synchronized void download(Bookmark bookmark) { @@ -290,57 +290,57 @@ public class DownloadServiceImpl extends Service implements DownloadService { lifecycleSupport.serializeDownloadQueue(); } - @Override - public synchronized void download(List<MusicDirectory.Entry> songs, boolean save, boolean autoplay, boolean playNext, boolean shuffle) { - setShufflePlayEnabled(false); - int offset = 1; + @Override + public synchronized void download(List<MusicDirectory.Entry> songs, boolean save, boolean autoplay, boolean playNext, boolean shuffle) { + setShufflePlayEnabled(false); + int offset = 1; - if (songs.isEmpty()) { - return; - } - if (playNext) { - if (autoplay && getCurrentPlayingIndex() >= 0) { - offset = 0; - } - for (MusicDirectory.Entry song : songs) { + if (songs.isEmpty()) { + return; + } + if (playNext) { + if (autoplay && getCurrentPlayingIndex() >= 0) { + offset = 0; + } + for (MusicDirectory.Entry song : songs) { if(song != null) { DownloadFile downloadFile = new DownloadFile(this, song, save); downloadList.add(getCurrentPlayingIndex() + offset, downloadFile); offset++; } - } + } setNextPlaying(); - revision++; - } else { + revision++; + } else { int size = size(); int index = getCurrentPlayingIndex(); - for (MusicDirectory.Entry song : songs) { - DownloadFile downloadFile = new DownloadFile(this, song, save); - downloadList.add(downloadFile); - } + for (MusicDirectory.Entry song : songs) { + DownloadFile downloadFile = new DownloadFile(this, song, save); + downloadList.add(downloadFile); + } if(!autoplay && (size - 1) == index) { setNextPlaying(); } - revision++; - } - updateJukeboxPlaylist(); - + revision++; + } + updateJukeboxPlaylist(); + if(shuffle) { shuffle(); } - if (autoplay) { - play(0); - } else { - if (currentPlaying == null) { - currentPlaying = downloadList.get(0); + if (autoplay) { + play(0); + } else { + if (currentPlaying == null) { + currentPlaying = downloadList.get(0); currentPlayingIndex = 0; currentPlaying.setPlaying(true); - } - checkDownloads(); - } - lifecycleSupport.serializeDownloadQueue(); - } + } + checkDownloads(); + } + lifecycleSupport.serializeDownloadQueue(); + } public synchronized void downloadBackground(List<MusicDirectory.Entry> songs, boolean save) { for (MusicDirectory.Entry song : songs) { DownloadFile downloadFile = new DownloadFile(this, song, save); @@ -350,158 +350,158 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } revision++; - + checkDownloads(); lifecycleSupport.serializeDownloadQueue(); } - private void updateJukeboxPlaylist() { - if (remoteState != RemoteControlState.LOCAL) { - remoteController.updatePlaylist(); - } - } + private void updateJukeboxPlaylist() { + if (remoteState != RemoteControlState.LOCAL) { + remoteController.updatePlaylist(); + } + } - public void restore(List<MusicDirectory.Entry> songs, List<MusicDirectory.Entry> toDelete, int currentPlayingIndex, int currentPlayingPosition) { + public void restore(List<MusicDirectory.Entry> songs, List<MusicDirectory.Entry> toDelete, int currentPlayingIndex, int currentPlayingPosition) { SharedPreferences prefs = Util.getPreferences(this); remoteState = RemoteControlState.values()[prefs.getInt(Constants.PREFERENCES_KEY_CONTROL_MODE, 0)]; if(remoteState != RemoteControlState.LOCAL) { setRemoteState(remoteState); } boolean startShufflePlay = prefs.getBoolean(Constants.PREFERENCES_KEY_SHUFFLE_MODE, false); - download(songs, false, false, false, false); + download(songs, false, false, false, false); if(startShufflePlay) { shufflePlay = true; SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean(Constants.PREFERENCES_KEY_SHUFFLE_MODE, true); editor.commit(); } - if (currentPlayingIndex != -1) { - while(mediaPlayer == null) { - Util.sleepQuietly(50L); - } - - play(currentPlayingIndex, false); - if (currentPlaying != null && currentPlaying.isCompleteFileAvailable() && remoteState == RemoteControlState.LOCAL) { - doPlay(currentPlaying, currentPlayingPosition, autoPlayStart); - } + if (currentPlayingIndex != -1) { + while(mediaPlayer == null) { + Util.sleepQuietly(50L); + } + + play(currentPlayingIndex, false); + if (currentPlaying != null && currentPlaying.isCompleteFileAvailable() && remoteState == RemoteControlState.LOCAL) { + doPlay(currentPlaying, currentPlayingPosition, autoPlayStart); + } autoPlayStart = false; - } + } if(toDelete != null) { for(MusicDirectory.Entry entry: toDelete) { this.toDelete.add(forSong(entry)); } } - } + } - @Override - public synchronized void setShufflePlayEnabled(boolean enabled) { - shufflePlay = enabled; - if (shufflePlay) { - clear(); - checkDownloads(); - } + @Override + public synchronized void setShufflePlayEnabled(boolean enabled) { + shufflePlay = enabled; + if (shufflePlay) { + clear(); + checkDownloads(); + } SharedPreferences.Editor editor = Util.getPreferences(this).edit(); editor.putBoolean(Constants.PREFERENCES_KEY_SHUFFLE_MODE, enabled); editor.commit(); - } + } - @Override - public boolean isShufflePlayEnabled() { - return shufflePlay; - } + @Override + public boolean isShufflePlayEnabled() { + return shufflePlay; + } - @Override - public synchronized void shuffle() { - Collections.shuffle(downloadList); + @Override + public synchronized void shuffle() { + Collections.shuffle(downloadList); currentPlayingIndex = downloadList.indexOf(currentPlaying); - if (currentPlaying != null) { - downloadList.remove(getCurrentPlayingIndex()); - downloadList.add(0, currentPlaying); + if (currentPlaying != null) { + downloadList.remove(getCurrentPlayingIndex()); + downloadList.add(0, currentPlaying); currentPlayingIndex = 0; - } - revision++; - lifecycleSupport.serializeDownloadQueue(); - updateJukeboxPlaylist(); + } + revision++; + lifecycleSupport.serializeDownloadQueue(); + updateJukeboxPlaylist(); setNextPlaying(); - } + } - @Override - public RepeatMode getRepeatMode() { - return Util.getRepeatMode(this); - } + @Override + public RepeatMode getRepeatMode() { + return Util.getRepeatMode(this); + } - @Override - public void setRepeatMode(RepeatMode repeatMode) { - Util.setRepeatMode(this, repeatMode); + @Override + public void setRepeatMode(RepeatMode repeatMode) { + Util.setRepeatMode(this, repeatMode); setNextPlaying(); - } + } + + @Override + public boolean getKeepScreenOn() { + return keepScreenOn; + } - @Override - public boolean getKeepScreenOn() { - return keepScreenOn; - } + @Override + public void setKeepScreenOn(boolean keepScreenOn) { + this.keepScreenOn = keepScreenOn; - @Override - public void setKeepScreenOn(boolean keepScreenOn) { - this.keepScreenOn = keepScreenOn; - SharedPreferences prefs = Util.getPreferences(this); SharedPreferences.Editor editor = prefs.edit(); editor.putBoolean(Constants.PREFERENCES_KEY_KEEP_SCREEN_ON, keepScreenOn); editor.commit(); - } + } - @Override - public boolean getShowVisualization() { - return showVisualization; - } + @Override + public boolean getShowVisualization() { + return showVisualization; + } - @Override - public void setShowVisualization(boolean showVisualization) { - this.showVisualization = showVisualization; + @Override + public void setShowVisualization(boolean showVisualization) { + this.showVisualization = showVisualization; SharedPreferences.Editor editor = Util.getPreferences(this).edit(); editor.putBoolean(Constants.PREFERENCES_VISUALIZER_ON, showVisualization); editor.commit(); } - @Override - public synchronized DownloadFile forSong(MusicDirectory.Entry song) { - DownloadFile returnFile = null; - for (DownloadFile downloadFile : downloadList) { - if (downloadFile.getSong().equals(song)) { - if(((downloadFile.isDownloading() && !downloadFile.isDownloadCancelled() && downloadFile.getPartialFile().exists()) || downloadFile.isWorkDone())) { - // If downloading, return immediately - return downloadFile; + @Override + public synchronized DownloadFile forSong(MusicDirectory.Entry song) { + DownloadFile returnFile = null; + for (DownloadFile downloadFile : downloadList) { + if (downloadFile.getSong().equals(song)) { + if(((downloadFile.isDownloading() && !downloadFile.isDownloadCancelled() && downloadFile.getPartialFile().exists()) || downloadFile.isWorkDone())) { + // If downloading, return immediately + return downloadFile; } else { // Otherwise, check to make sure there isn't a background download going on first returnFile = downloadFile; } - } - } + } + } for (DownloadFile downloadFile : backgroundDownloadList) { - if (downloadFile.getSong().equals(song)) { - return downloadFile; - } - } - - if(returnFile != null) { - return returnFile; - } - - DownloadFile downloadFile = downloadFileCache.get(song); - if (downloadFile == null) { - downloadFile = new DownloadFile(this, song, false); - downloadFileCache.put(song, downloadFile); - } - return downloadFile; - } - - @Override - public synchronized void clear() { - clear(true); - } - + if (downloadFile.getSong().equals(song)) { + return downloadFile; + } + } + + if(returnFile != null) { + return returnFile; + } + + DownloadFile downloadFile = downloadFileCache.get(song); + if (downloadFile == null) { + downloadFile = new DownloadFile(this, song, false); + downloadFileCache.put(song, downloadFile); + } + return downloadFile; + } + + @Override + public synchronized void clear() { + clear(true); + } + @Override public synchronized void clearBackground() { if(currentDownloading != null && backgroundDownloadList.contains(currentDownloading)) { @@ -512,126 +512,126 @@ public class DownloadServiceImpl extends Service implements DownloadService { Util.hideDownloadingNotification(this); } - @Override - public synchronized void clearIncomplete() { - reset(); - Iterator<DownloadFile> iterator = downloadList.iterator(); - while (iterator.hasNext()) { - DownloadFile downloadFile = iterator.next(); - if (!downloadFile.isCompleteFileAvailable()) { - iterator.remove(); - } - } - lifecycleSupport.serializeDownloadQueue(); - updateJukeboxPlaylist(); - } - - @Override - public synchronized int size() { - return downloadList.size(); - } - - public synchronized void clear(boolean serialize) { - // Delete podcast if fully listened to - if(currentPlaying != null && currentPlaying.getSong() instanceof PodcastEpisode) { + @Override + public synchronized void clearIncomplete() { + reset(); + Iterator<DownloadFile> iterator = downloadList.iterator(); + while (iterator.hasNext()) { + DownloadFile downloadFile = iterator.next(); + if (!downloadFile.isCompleteFileAvailable()) { + iterator.remove(); + } + } + lifecycleSupport.serializeDownloadQueue(); + updateJukeboxPlaylist(); + } + + @Override + public synchronized int size() { + return downloadList.size(); + } + + public synchronized void clear(boolean serialize) { + // Delete podcast if fully listened to + if(currentPlaying != null && currentPlaying.getSong() instanceof PodcastEpisode) { int duration = getPlayerDuration(); - // Make sure > 90% of the way through - int cutoffPoint = (int)(duration * 0.90); - if(duration > 0 && cachedPosition > cutoffPoint) { - currentPlaying.delete(); - } - } + // Make sure > 90% of the way through + int cutoffPoint = (int)(duration * 0.90); + if(duration > 0 && cachedPosition > cutoffPoint) { + currentPlaying.delete(); + } + } for(DownloadFile podcast: toDelete) { podcast.delete(); } toDelete.clear(); - reset(); - downloadList.clear(); - revision++; - if (currentDownloading != null) { - currentDownloading.cancelDownload(); - currentDownloading = null; - } - setCurrentPlaying(null, false); - - if (serialize) { - lifecycleSupport.serializeDownloadQueue(); - } - updateJukeboxPlaylist(); + reset(); + downloadList.clear(); + revision++; + if (currentDownloading != null) { + currentDownloading.cancelDownload(); + currentDownloading = null; + } + setCurrentPlaying(null, false); + + if (serialize) { + lifecycleSupport.serializeDownloadQueue(); + } + updateJukeboxPlaylist(); setNextPlaying(); - } - + } + @Override - public synchronized void remove(int which) { + public synchronized void remove(int which) { downloadList.remove(which); currentPlayingIndex = downloadList.indexOf(currentPlaying); } - @Override - public synchronized void remove(DownloadFile downloadFile) { - if (downloadFile == currentDownloading) { - currentDownloading.cancelDownload(); - currentDownloading = null; - } - if (downloadFile == currentPlaying) { - reset(); - setCurrentPlaying(null, false); - } - downloadList.remove(downloadFile); + @Override + public synchronized void remove(DownloadFile downloadFile) { + if (downloadFile == currentDownloading) { + currentDownloading.cancelDownload(); + currentDownloading = null; + } + if (downloadFile == currentPlaying) { + reset(); + setCurrentPlaying(null, false); + } + downloadList.remove(downloadFile); currentPlayingIndex = downloadList.indexOf(currentPlaying); backgroundDownloadList.remove(downloadFile); - revision++; - lifecycleSupport.serializeDownloadQueue(); - updateJukeboxPlaylist(); + revision++; + lifecycleSupport.serializeDownloadQueue(); + updateJukeboxPlaylist(); if(downloadFile == nextPlaying) { setNextPlaying(); } - } - - @Override - public synchronized void delete(List<MusicDirectory.Entry> songs) { - for (MusicDirectory.Entry song : songs) { - forSong(song).delete(); - } - } - - @Override - public synchronized void unpin(List<MusicDirectory.Entry> songs) { - for (MusicDirectory.Entry song : songs) { - forSong(song).unpin(); - } - } - - synchronized void setCurrentPlaying(int currentPlayingIndex, boolean showNotification) { - try { - setCurrentPlaying(downloadList.get(currentPlayingIndex), showNotification); - } catch (IndexOutOfBoundsException x) { - // Ignored - } - } + } + + @Override + public synchronized void delete(List<MusicDirectory.Entry> songs) { + for (MusicDirectory.Entry song : songs) { + forSong(song).delete(); + } + } + + @Override + public synchronized void unpin(List<MusicDirectory.Entry> songs) { + for (MusicDirectory.Entry song : songs) { + forSong(song).unpin(); + } + } + + synchronized void setCurrentPlaying(int currentPlayingIndex, boolean showNotification) { + try { + setCurrentPlaying(downloadList.get(currentPlayingIndex), showNotification); + } catch (IndexOutOfBoundsException x) { + // Ignored + } + } synchronized void setCurrentPlaying(DownloadFile currentPlaying, boolean showNotification) { if(this.currentPlaying != null) { this.currentPlaying.setPlaying(false); } - this.currentPlaying = currentPlaying; + this.currentPlaying = currentPlaying; if(currentPlaying == null) { currentPlayingIndex = -1; } else { currentPlayingIndex = downloadList.indexOf(currentPlaying); } - if (currentPlaying != null) { - Util.broadcastNewTrackInfo(this, currentPlaying.getSong()); + if (currentPlaying != null) { + Util.broadcastNewTrackInfo(this, currentPlaying.getSong()); mRemoteControl.updateMetadata(this, currentPlaying.getSong()); - } else { - Util.broadcastNewTrackInfo(this, null); + } else { + Util.broadcastNewTrackInfo(this, null); Util.hidePlayingNotification(this, this, handler); - } - } - + } + } + synchronized void setNextPlaying() { SharedPreferences prefs = Util.getPreferences(DownloadServiceImpl.this); boolean gaplessPlayback = prefs.getBoolean(Constants.PREFERENCES_KEY_GAPLESS_PLAYBACK, true); @@ -640,9 +640,9 @@ public class DownloadServiceImpl extends Service implements DownloadService { nextPlayerState = IDLE; return; } - + int index = getNextPlayingIndex(); - + nextSetup = false; if(nextPlayingTask != null) { nextPlayingTask.cancel(); @@ -658,39 +658,39 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } - @Override - public int getCurrentPlayingIndex() { - return currentPlayingIndex; - } - private int getNextPlayingIndex() { - int index = getCurrentPlayingIndex(); + @Override + public int getCurrentPlayingIndex() { + return currentPlayingIndex; + } + private int getNextPlayingIndex() { + int index = getCurrentPlayingIndex(); if (index != -1) { - switch (getRepeatMode()) { - case OFF: - index = index + 1; - break; - case ALL: + switch (getRepeatMode()) { + case OFF: + index = index + 1; + break; + case ALL: index = (index + 1) % size(); - break; - case SINGLE: - break; - default: - break; - } - } - return index; - } - - @Override - public DownloadFile getCurrentPlaying() { - return currentPlaying; - } - - @Override - public DownloadFile getCurrentDownloading() { - return currentDownloading; - } - + break; + case SINGLE: + break; + default: + break; + } + } + return index; + } + + @Override + public DownloadFile getCurrentPlaying() { + return currentPlaying; + } + + @Override + public DownloadFile getCurrentDownloading() { + return currentDownloading; + } + @Override public List<DownloadFile> getSongs() { return downloadList; @@ -698,62 +698,62 @@ public class DownloadServiceImpl extends Service implements DownloadService { public List<DownloadFile> getToDelete() { return toDelete; } - @Override - public synchronized List<DownloadFile> getDownloads() { + @Override + public synchronized List<DownloadFile> getDownloads() { List<DownloadFile> temp = new ArrayList<DownloadFile>(); temp.addAll(downloadList); temp.addAll(backgroundDownloadList); - return temp; - } - + return temp; + } + @Override public List<DownloadFile> getBackgroundDownloads() { return backgroundDownloadList; } - /** Plays either the current song (resume) or the first/next one in queue. */ - public synchronized void play() - { - int current = getCurrentPlayingIndex(); - if (current == -1) { - play(0); - } else { - play(current); - } - } - - @Override - public synchronized void play(int index) { - play(index, true); - } + /** Plays either the current song (resume) or the first/next one in queue. */ + public synchronized void play() + { + int current = getCurrentPlayingIndex(); + if (current == -1) { + play(0); + } else { + play(current); + } + } + + @Override + public synchronized void play(int index) { + play(index, true); + } private synchronized void play(int index, boolean start) { play(index, start, 0); } - private synchronized void play(int index, boolean start, int position) { - if (index < 0 || index >= size()) { - reset(); - setCurrentPlaying(null, false); + private synchronized void play(int index, boolean start, int position) { + if (index < 0 || index >= size()) { + reset(); + setCurrentPlaying(null, false); lifecycleSupport.serializeDownloadQueue(); - } else { + } else { if(nextPlayingTask != null) { nextPlayingTask.cancel(); nextPlayingTask = null; } - setCurrentPlaying(index, start); - if (start) { - if (remoteState != RemoteControlState.LOCAL) { + setCurrentPlaying(index, start); + if (start) { + if (remoteState != RemoteControlState.LOCAL) { remoteController.changeTrack(index, downloadList.get(index)); - setPlayerState(STARTED); - } else { - bufferAndPlay(position); - } - } + setPlayerState(STARTED); + } else { + bufferAndPlay(position); + } + } if (remoteState == RemoteControlState.LOCAL) { checkDownloads(); setNextPlaying(); } - } - } + } + } private synchronized void playNext() { if(nextPlaying != null && nextPlayerState == PlayerState.PREPARED) { if(!nextSetup) { @@ -783,7 +783,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { setPlayerState(PlayerState.STARTED); setupHandlers(currentPlaying, false); setNextPlaying(); - + // Proxy should not be being used here since the next player was already setup to play if(proxy != null) { proxy.stop(); @@ -791,53 +791,53 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } - /** Plays or resumes the playback, depending on the current player state. */ - public synchronized void togglePlayPause() { - if (playerState == PAUSED || playerState == COMPLETED || playerState == STOPPED) { - start(); - } else if (playerState == STOPPED || playerState == IDLE) { + /** Plays or resumes the playback, depending on the current player state. */ + public synchronized void togglePlayPause() { + if (playerState == PAUSED || playerState == COMPLETED || playerState == STOPPED) { + start(); + } else if (playerState == STOPPED || playerState == IDLE) { autoPlayStart = true; - play(); - } else if (playerState == STARTED) { - pause(); - } - } - - @Override - public synchronized void seekTo(int position) { - try { - if (remoteState != RemoteControlState.LOCAL) { + play(); + } else if (playerState == STARTED) { + pause(); + } + } + + @Override + public synchronized void seekTo(int position) { + try { + if (remoteState != RemoteControlState.LOCAL) { remoteController.changePosition(position / 1000); - } else { - mediaPlayer.seekTo(position); + } else { + mediaPlayer.seekTo(position); cachedPosition = position; - } - } catch (Exception x) { - handleError(x); - } - } - - @Override - public synchronized void previous() { - int index = getCurrentPlayingIndex(); - if (index == -1) { - return; - } - - // Restart song if played more than five seconds. - if (getPlayerPosition() > 5000 || (index == 0 && getRepeatMode() != RepeatMode.ALL)) { - play(index); - } else { + } + } catch (Exception x) { + handleError(x); + } + } + + @Override + public synchronized void previous() { + int index = getCurrentPlayingIndex(); + if (index == -1) { + return; + } + + // Restart song if played more than five seconds. + if (getPlayerPosition() > 5000 || (index == 0 && getRepeatMode() != RepeatMode.ALL)) { + play(index); + } else { if(index == 0) { index = size(); } - play(index - 1); - } - } + play(index - 1); + } + } - @Override - public synchronized void next() { + @Override + public synchronized void next() { // Delete podcast if fully listened to if(currentPlaying != null && currentPlaying.getSong() instanceof PodcastEpisode) { int duration = getPlayerDuration(); @@ -849,13 +849,13 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } - int index = getCurrentPlayingIndex(); + int index = getCurrentPlayingIndex(); int nextPlayingIndex = getNextPlayingIndex(); // Make sure to actually go to next when repeat song is on if(index == nextPlayingIndex) { nextPlayingIndex++; } - if (index != -1 && nextPlayingIndex < size()) { + if (index != -1 && nextPlayingIndex < size()) { if(nextPlaying != null && downloadList.get(nextPlayingIndex) == nextPlaying && nextPlayerState == PlayerState.PREPARED && remoteState == RemoteControlState.LOCAL) { if(mediaPlayer.isPlaying()) { mediaPlayer.stop(); @@ -865,42 +865,42 @@ public class DownloadServiceImpl extends Service implements DownloadService { mediaPlayer.reset(); playNext(true); } else { - play(nextPlayingIndex); + play(nextPlayingIndex); } - } - } - - private void onSongCompleted() { - play(getNextPlayingIndex()); - } - - @Override - public synchronized void pause() { - try { - if (playerState == STARTED) { - if (remoteState != RemoteControlState.LOCAL) { + } + } + + private void onSongCompleted() { + play(getNextPlayingIndex()); + } + + @Override + public synchronized void pause() { + try { + if (playerState == STARTED) { + if (remoteState != RemoteControlState.LOCAL) { remoteController.stop(); - } else { - mediaPlayer.pause(); - } - setPlayerState(PAUSED); - } - } catch (Exception x) { - handleError(x); - } - } - + } else { + mediaPlayer.pause(); + } + setPlayerState(PAUSED); + } + } catch (Exception x) { + handleError(x); + } + } + @Override public synchronized void stop() { try { if (playerState == STARTED) { - if (remoteState != RemoteControlState.LOCAL) { + if (remoteState != RemoteControlState.LOCAL) { remoteController.stop(); - } else { - mediaPlayer.pause(); - } - setPlayerState(STOPPED); - } else if(playerState == PAUSED) { + } else { + mediaPlayer.pause(); + } + setPlayerState(STOPPED); + } else if(playerState == PAUSED) { setPlayerState(STOPPED); } } catch(Exception x) { @@ -908,113 +908,113 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } - @Override - public synchronized void start() { - try { - if (remoteState != RemoteControlState.LOCAL) { + @Override + public synchronized void start() { + try { + if (remoteState != RemoteControlState.LOCAL) { remoteController.start(); - } else { - mediaPlayer.start(); + } else { + mediaPlayer.start(); } - setPlayerState(STARTED); - } catch (Exception x) { - handleError(x); - } - } - - @Override - public synchronized void reset() { - if (bufferTask != null) { - bufferTask.cancel(); - } - try { + setPlayerState(STARTED); + } catch (Exception x) { + handleError(x); + } + } + + @Override + public synchronized void reset() { + if (bufferTask != null) { + bufferTask.cancel(); + } + try { setPlayerState(IDLE); mediaPlayer.setOnErrorListener(null); mediaPlayer.setOnCompletionListener(null); - mediaPlayer.reset(); - } catch (Exception x) { - handleError(x); - } - } - - @Override - public int getPlayerPosition() { - try { - if (playerState == IDLE || playerState == DOWNLOADING || playerState == PREPARING) { - return 0; - } - if (remoteState != RemoteControlState.LOCAL) { + mediaPlayer.reset(); + } catch (Exception x) { + handleError(x); + } + } + + @Override + public int getPlayerPosition() { + try { + if (playerState == IDLE || playerState == DOWNLOADING || playerState == PREPARING) { + return 0; + } + if (remoteState != RemoteControlState.LOCAL) { return remoteController.getRemotePosition() * 1000; - } else { - return cachedPosition; - } - } catch (Exception x) { - handleError(x); - return 0; - } - } - - @Override - public synchronized int getPlayerDuration() { - if (currentPlaying != null) { - Integer duration = currentPlaying.getSong().getDuration(); - if (duration != null) { - return duration * 1000; - } - } - if (playerState != IDLE && playerState != DOWNLOADING && playerState != PlayerState.PREPARING) { - try { - return mediaPlayer.getDuration(); - } catch (Exception x) { - handleError(x); - } - } - return 0; - } - - @Override - public PlayerState getPlayerState() { - return playerState; - } + } else { + return cachedPosition; + } + } catch (Exception x) { + handleError(x); + return 0; + } + } + + @Override + public synchronized int getPlayerDuration() { + if (currentPlaying != null) { + Integer duration = currentPlaying.getSong().getDuration(); + if (duration != null) { + return duration * 1000; + } + } + if (playerState != IDLE && playerState != DOWNLOADING && playerState != PlayerState.PREPARING) { + try { + return mediaPlayer.getDuration(); + } catch (Exception x) { + handleError(x); + } + } + return 0; + } + + @Override + public PlayerState getPlayerState() { + return playerState; + } public synchronized void setPlayerState(final PlayerState playerState) { - Log.i(TAG, this.playerState.name() + " -> " + playerState.name() + " (" + currentPlaying + ")"); + Log.i(TAG, this.playerState.name() + " -> " + playerState.name() + " (" + currentPlaying + ")"); - if (playerState == PAUSED) { - lifecycleSupport.serializeDownloadQueue(); - } + if (playerState == PAUSED) { + lifecycleSupport.serializeDownloadQueue(); + } - boolean show = playerState == PlayerState.STARTED; - boolean pause = playerState == PlayerState.PAUSED; + boolean show = playerState == PlayerState.STARTED; + boolean pause = playerState == PlayerState.PAUSED; boolean hide = playerState == PlayerState.STOPPED; - Util.broadcastPlaybackStatusChange(this, (currentPlaying != null) ? currentPlaying.getSong() : null, playerState); + Util.broadcastPlaybackStatusChange(this, (currentPlaying != null) ? currentPlaying.getSong() : null, playerState); + + this.playerState = playerState; - this.playerState = playerState; - if(playerState == STARTED) { Util.requestAudioFocus(this); } - - if (show) { - Util.showPlayingNotification(this, this, handler, currentPlaying.getSong()); - } else if (pause) { + + if (show) { + Util.showPlayingNotification(this, this, handler, currentPlaying.getSong()); + } else if (pause) { SharedPreferences prefs = Util.getPreferences(this); if(prefs.getBoolean(Constants.PREFERENCES_KEY_PERSISTENT_NOTIFICATION, false)) { Util.showPlayingNotification(this, this, handler, currentPlaying.getSong()); } else { Util.hidePlayingNotification(this, this, handler); } - } else if(hide) { + } else if(hide) { Util.hidePlayingNotification(this, this, handler); } mRemoteControl.setPlaybackState(playerState.getRemoteControlClientPlayState()); - if (playerState == STARTED) { - scrobbler.scrobble(this, currentPlaying, false); - } else if (playerState == COMPLETED) { - scrobbler.scrobble(this, currentPlaying, true); - } - + if (playerState == STARTED) { + scrobbler.scrobble(this, currentPlaying, false); + } else if (playerState == COMPLETED) { + scrobbler.scrobble(this, currentPlaying, true); + } + if(playerState == STARTED && positionCache == null) { positionCache = new PositionCache(); Thread thread = new Thread(positionCache); @@ -1023,8 +1023,8 @@ public class DownloadServiceImpl extends Service implements DownloadService { positionCache.stop(); positionCache = null; } - } - + } + private class PositionCache implements Runnable { boolean isRunning = true; @@ -1050,7 +1050,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } } - + private void setPlayerStateCompleted() { Log.i(TAG, this.playerState.name() + " -> " + PlayerState.COMPLETED + " (" + currentPlaying + ")"); this.playerState = PlayerState.COMPLETED; @@ -1060,40 +1060,40 @@ public class DownloadServiceImpl extends Service implements DownloadService { } scrobbler.scrobble(this, currentPlaying, true); } - + private synchronized void setNextPlayerState(PlayerState playerState) { - Log.i(TAG, "Next: " + this.nextPlayerState.name() + " -> " + playerState.name() + " (" + nextPlaying + ")"); - this.nextPlayerState = playerState; - } + Log.i(TAG, "Next: " + this.nextPlayerState.name() + " -> " + playerState.name() + " (" + nextPlaying + ")"); + this.nextPlayerState = playerState; + } - @Override - public void setSuggestedPlaylistName(String name, String id) { - this.suggestedPlaylistName = name; + @Override + public void setSuggestedPlaylistName(String name, String id) { + this.suggestedPlaylistName = name; this.suggestedPlaylistId = id; - } + } + + @Override + public String getSuggestedPlaylistName() { + return suggestedPlaylistName; + } - @Override - public String getSuggestedPlaylistName() { - return suggestedPlaylistName; - } - @Override public String getSuggestedPlaylistId() { return suggestedPlaylistId; } - + @Override - public boolean getEqualizerAvailable() { - return equalizerAvailable; - } + public boolean getEqualizerAvailable() { + return equalizerAvailable; + } - @Override - public boolean getVisualizerAvailable() { - return visualizerAvailable; - } + @Override + public boolean getVisualizerAvailable() { + return visualizerAvailable; + } - @Override - public EqualizerController getEqualizerController() { + @Override + public EqualizerController getEqualizerController() { if (equalizerAvailable && equalizerController == null) { equalizerController = new EqualizerController(this, mediaPlayer); if (!equalizerController.isAvailable()) { @@ -1102,33 +1102,33 @@ public class DownloadServiceImpl extends Service implements DownloadService { equalizerController.loadSettings(); } } - return equalizerController; - } + return equalizerController; + } - @Override - public VisualizerController getVisualizerController() { + @Override + public VisualizerController getVisualizerController() { if (visualizerAvailable && visualizerController == null) { visualizerController = new VisualizerController(this, mediaPlayer); if (!visualizerController.isAvailable()) { visualizerController = null; } } - return visualizerController; - } + return visualizerController; + } - @Override - public boolean isRemoteEnabled() { - return remoteState != RemoteControlState.LOCAL; - } + @Override + public boolean isRemoteEnabled() { + return remoteState != RemoteControlState.LOCAL; + } - @Override - public void setRemoteEnabled(RemoteControlState newState) { + @Override + public void setRemoteEnabled(RemoteControlState newState) { setRemoteState(newState); - - SharedPreferences.Editor editor = Util.getPreferences(this).edit(); + + 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(); @@ -1154,7 +1154,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { currentDownloading.cancelDownload(); } } - + SharedPreferences prefs = Util.getPreferences(this); if(currentPlaying != null && prefs.getBoolean(Constants.PREFERENCES_KEY_PERSISTENT_NOTIFICATION, false)) { Util.showPlayingNotification(this, this, handler, currentPlaying.getSong()); @@ -1163,15 +1163,15 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } - @Override - public void setRemoteVolume(boolean up) { + @Override + public void setRemoteVolume(boolean up) { remoteController.setVolume(up); - } + } private synchronized void bufferAndPlay() { bufferAndPlay(0); } - private synchronized void bufferAndPlay(int position) { + private synchronized void bufferAndPlay(int position) { if(playerState != PREPARED) { reset(); @@ -1180,15 +1180,15 @@ public class DownloadServiceImpl extends Service implements DownloadService { } else { doPlay(currentPlaying, position, true); } - } + } - private synchronized void doPlay(final DownloadFile downloadFile, final int position, final boolean start) { - try { + private synchronized void doPlay(final DownloadFile downloadFile, final int position, final boolean start) { + try { downloadFile.setPlaying(true); - final File file = downloadFile.isCompleteFileAvailable() ? downloadFile.getCompleteFile() : downloadFile.getPartialFile(); + final File file = downloadFile.isCompleteFileAvailable() ? downloadFile.getCompleteFile() : downloadFile.getPartialFile(); isPartial = file.equals(downloadFile.getPartialFile()); - downloadFile.updateModificationDate(); - + downloadFile.updateModificationDate(); + mediaPlayer.setOnCompletionListener(null); mediaPlayer.reset(); setPlayerState(IDLE); @@ -1248,38 +1248,38 @@ public class DownloadServiceImpl extends Service implements DownloadService { }); setupHandlers(downloadFile, isPartial); - + mediaPlayer.prepareAsync(); - } catch (Exception x) { - handleError(x); - } - } - + } catch (Exception x) { + handleError(x); + } + } + private synchronized void setupNext(final DownloadFile downloadFile) { try { - final File file = downloadFile.isCompleteFileAvailable() ? downloadFile.getCompleteFile() : downloadFile.getPartialFile(); - if(nextMediaPlayer != null) { - nextMediaPlayer.setOnCompletionListener(null); - nextMediaPlayer.setOnErrorListener(null); - nextMediaPlayer.reset(); - nextMediaPlayer.release(); - nextMediaPlayer = null; - } - nextMediaPlayer = new MediaPlayer(); + final File file = downloadFile.isCompleteFileAvailable() ? downloadFile.getCompleteFile() : downloadFile.getPartialFile(); + if(nextMediaPlayer != null) { + nextMediaPlayer.setOnCompletionListener(null); + nextMediaPlayer.setOnErrorListener(null); + nextMediaPlayer.reset(); + nextMediaPlayer.release(); + nextMediaPlayer = null; + } + nextMediaPlayer = new MediaPlayer(); nextMediaPlayer.setWakeMode(DownloadServiceImpl.this, PowerManager.PARTIAL_WAKE_LOCK); try { - nextMediaPlayer.setAudioSessionId(mediaPlayer.getAudioSessionId()); + nextMediaPlayer.setAudioSessionId(mediaPlayer.getAudioSessionId()); } catch(Throwable e) { nextMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); } - nextMediaPlayer.setDataSource(file.getPath()); - setNextPlayerState(PREPARING); - + nextMediaPlayer.setDataSource(file.getPath()); + setNextPlayerState(PREPARING); + nextMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { public void onPrepared(MediaPlayer mp) { try { setNextPlayerState(PREPARED); - + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN && (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED)) { mediaPlayer.setNextMediaPlayer(nextMediaPlayer); nextSetup = true; @@ -1289,20 +1289,20 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } }); - + nextMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { public boolean onError(MediaPlayer mediaPlayer, int what, int extra) { Log.w(TAG, "Error on playing next " + "(" + what + ", " + extra + "): " + downloadFile); return true; } }); - + nextMediaPlayer.prepareAsync(); - } catch (Exception x) { - handleErrorNext(x); - } + } catch (Exception x) { + handleErrorNext(x); + } } - + private void setupHandlers(final DownloadFile downloadFile, final boolean isPartial) { final int duration = downloadFile.getSong().getDuration() == null ? 0 : downloadFile.getSong().getDuration() * 1000; mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { @@ -1320,7 +1320,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { return true; } }); - + mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { @@ -1328,7 +1328,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { // this callback the MediaPlayer will release its wakelock // and allow the device to go to sleep. wakeLock.acquire(60000); - + setPlayerStateCompleted(); int pos = cachedPosition; @@ -1361,12 +1361,12 @@ public class DownloadServiceImpl extends Service implements DownloadService { } }); } - + @Override public void setSleepTimerDuration(int duration){ timerDuration = duration; } - + @Override public void startSleepTimer(){ if(sleepTimer != null){ @@ -1374,9 +1374,9 @@ public class DownloadServiceImpl extends Service implements DownloadService { sleepTimer.purge(); } - sleepTimer = new Timer(); + sleepTimer = new Timer(); - sleepTimer.schedule(new TimerTask() { + sleepTimer.schedule(new TimerTask() { @Override public void run() { pause(); @@ -1387,7 +1387,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { }, timerDuration * 60 * 1000); } - + @Override public void stopSleepTimer() { if(sleepTimer != null){ @@ -1396,19 +1396,19 @@ public class DownloadServiceImpl extends Service implements DownloadService { } sleepTimer = null; } - + @Override public boolean getSleepTimer() { return sleepTimer != null; } - + @Override public void setVolume(float volume) { if(mediaPlayer != null) { mediaPlayer.setVolume(volume, volume); } } - + @Override public synchronized void swap(boolean mainList, int from, int to) { List<DownloadFile> list = mainList ? downloadList : backgroundDownloadList; @@ -1419,7 +1419,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { else if(to < 0) { to = 0; } - + int currentPlayingIndex = getCurrentPlayingIndex(); DownloadFile movedSong = list.remove(from); list.add(to, movedSong); @@ -1431,54 +1431,54 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } - private void handleError(Exception x) { - Log.w(TAG, "Media player error: " + x, x); - if(mediaPlayer != null) { - mediaPlayer.reset(); - } - setPlayerState(IDLE); - } + private void handleError(Exception x) { + Log.w(TAG, "Media player error: " + x, x); + if(mediaPlayer != null) { + mediaPlayer.reset(); + } + setPlayerState(IDLE); + } private void handleErrorNext(Exception x) { Log.w(TAG, "Next Media player error: " + x, x); - nextMediaPlayer.reset(); + nextMediaPlayer.reset(); setNextPlayerState(IDLE); } - protected synchronized void checkDownloads() { - if (!Util.isExternalStoragePresent() || !lifecycleSupport.isExternalStorageAvailable()) { - return; - } - - if (shufflePlay) { - checkShufflePlay(); - } - - if (remoteState != RemoteControlState.LOCAL || !Util.isNetworkConnected(this) || Util.isOffline(this)) { - return; - } - - if (downloadList.isEmpty() && backgroundDownloadList.isEmpty()) { - return; - } - - // Need to download current playing? - if (currentPlaying != null && currentPlaying != currentDownloading && !currentPlaying.isWorkDone()) { - // Cancel current download, if necessary. - if (currentDownloading != null) { - currentDownloading.cancelDownload(); - } - - currentDownloading = currentPlaying; - currentDownloading.download(); - cleanupCandidates.add(currentDownloading); - } - - // Find a suitable target for download. - else if (currentDownloading == null || currentDownloading.isWorkDone() || currentDownloading.isFailed() && (!downloadList.isEmpty() || !backgroundDownloadList.isEmpty())) { + protected synchronized void checkDownloads() { + if (!Util.isExternalStoragePresent() || !lifecycleSupport.isExternalStorageAvailable()) { + return; + } + + if (shufflePlay) { + checkShufflePlay(); + } + + if (remoteState != RemoteControlState.LOCAL || !Util.isNetworkConnected(this) || Util.isOffline(this)) { + return; + } + + if (downloadList.isEmpty() && backgroundDownloadList.isEmpty()) { + return; + } + + // Need to download current playing? + if (currentPlaying != null && currentPlaying != currentDownloading && !currentPlaying.isWorkDone()) { + // Cancel current download, if necessary. + if (currentDownloading != null) { + currentDownloading.cancelDownload(); + } + + currentDownloading = currentPlaying; + currentDownloading.download(); + cleanupCandidates.add(currentDownloading); + } + + // Find a suitable target for download. + else if (currentDownloading == null || currentDownloading.isWorkDone() || currentDownloading.isFailed() && (!downloadList.isEmpty() || !backgroundDownloadList.isEmpty())) { currentDownloading = null; - int n = size(); + int n = size(); - int preloaded = 0; + int preloaded = 0; if(n != 0) { int start = currentPlaying == null ? 0 : getCurrentPlayingIndex(); @@ -1505,7 +1505,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { i = (i + 1) % n; } while (i != start); } - + if((preloaded + 1 == n || preloaded >= Util.getPreloadCount(this) || downloadList.isEmpty()) && !backgroundDownloadList.isEmpty()) { for(int i = 0; i < backgroundDownloadList.size(); i++) { DownloadFile downloadFile = backgroundDownloadList.get(i); @@ -1524,7 +1524,7 @@ public class DownloadServiceImpl extends Service implements DownloadService { } } } - } + } if(!backgroundDownloadList.isEmpty() && downloadRevision != revision) { Util.showDownloadingNotification(this, currentDownloading, backgroundDownloadList.size()); @@ -1535,78 +1535,78 @@ public class DownloadServiceImpl extends Service implements DownloadService { downloadOngoing = false; } - // Delete obsolete .partial and .complete files. - cleanup(); - } + // Delete obsolete .partial and .complete files. + cleanup(); + } - private synchronized void checkShufflePlay() { + private synchronized void checkShufflePlay() { - // Get users desired random playlist size + // Get users desired random playlist size SharedPreferences prefs = Util.getPreferences(this); int listSize = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_RANDOM_SIZE, "20")); - boolean wasEmpty = downloadList.isEmpty(); - - long revisionBefore = revision; - - // First, ensure that list is at least 20 songs long. - int size = size(); - if (size < listSize) { - for (MusicDirectory.Entry song : shufflePlayBuffer.get(listSize - size)) { - DownloadFile downloadFile = new DownloadFile(this, song, false); - downloadList.add(downloadFile); - revision++; - } - } - - int currIndex = currentPlaying == null ? 0 : getCurrentPlayingIndex(); - - // Only shift playlist if playing song #5 or later. - if (currIndex > 4) { - int songsToShift = currIndex - 2; - for (MusicDirectory.Entry song : shufflePlayBuffer.get(songsToShift)) { - downloadList.add(new DownloadFile(this, song, false)); - downloadList.get(0).cancelDownload(); - downloadList.remove(0); - revision++; - } - } + boolean wasEmpty = downloadList.isEmpty(); + + long revisionBefore = revision; + + // First, ensure that list is at least 20 songs long. + int size = size(); + if (size < listSize) { + for (MusicDirectory.Entry song : shufflePlayBuffer.get(listSize - size)) { + DownloadFile downloadFile = new DownloadFile(this, song, false); + downloadList.add(downloadFile); + revision++; + } + } + + int currIndex = currentPlaying == null ? 0 : getCurrentPlayingIndex(); + + // Only shift playlist if playing song #5 or later. + if (currIndex > 4) { + int songsToShift = currIndex - 2; + for (MusicDirectory.Entry song : shufflePlayBuffer.get(songsToShift)) { + downloadList.add(new DownloadFile(this, song, false)); + downloadList.get(0).cancelDownload(); + downloadList.remove(0); + revision++; + } + } currentPlayingIndex = downloadList.indexOf(currentPlaying); - if (revisionBefore != revision) { - updateJukeboxPlaylist(); - } - - if (wasEmpty && !downloadList.isEmpty()) { - play(0); - } - } - - public long getDownloadListUpdateRevision() { - return revision; - } - - private synchronized void cleanup() { - Iterator<DownloadFile> iterator = cleanupCandidates.iterator(); - while (iterator.hasNext()) { - DownloadFile downloadFile = iterator.next(); - if (downloadFile != currentPlaying && downloadFile != currentDownloading) { - if (downloadFile.cleanup()) { - iterator.remove(); - } - } - } - } - - private class BufferTask extends CancellableTask { - private final DownloadFile downloadFile; - private final int position; - private final long expectedFileSize; - private final File partialFile; - - public BufferTask(DownloadFile downloadFile, int position) { - this.downloadFile = downloadFile; - this.position = position; - partialFile = downloadFile.getPartialFile(); + if (revisionBefore != revision) { + updateJukeboxPlaylist(); + } + + if (wasEmpty && !downloadList.isEmpty()) { + play(0); + } + } + + public long getDownloadListUpdateRevision() { + return revision; + } + + private synchronized void cleanup() { + Iterator<DownloadFile> iterator = cleanupCandidates.iterator(); + while (iterator.hasNext()) { + DownloadFile downloadFile = iterator.next(); + if (downloadFile != currentPlaying && downloadFile != currentDownloading) { + if (downloadFile.cleanup()) { + iterator.remove(); + } + } + } + } + + private class BufferTask extends CancellableTask { + private final DownloadFile downloadFile; + private final int position; + private final long expectedFileSize; + private final File partialFile; + + public BufferTask(DownloadFile downloadFile, int position) { + this.downloadFile = downloadFile; + this.position = position; + partialFile = downloadFile.getPartialFile(); SharedPreferences prefs = Util.getPreferences(DownloadServiceImpl.this); long bufferLength = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_BUFFER_LENGTH, "5")); @@ -1615,88 +1615,88 @@ public class DownloadServiceImpl extends Service implements DownloadService { bufferLength = 86400L; } - // Calculate roughly how many bytes BUFFER_LENGTH_SECONDS corresponds to. - int bitRate = downloadFile.getBitRate(); - long byteCount = Math.max(100000, bitRate * 1024L / 8L * bufferLength); + // Calculate roughly how many bytes BUFFER_LENGTH_SECONDS corresponds to. + int bitRate = downloadFile.getBitRate(); + long byteCount = Math.max(100000, bitRate * 1024L / 8L * bufferLength); - // Find out how large the file should grow before resuming playback. + // Find out how large the file should grow before resuming playback. Log.i(TAG, "Buffering from position " + position + " and bitrate " + bitRate); - expectedFileSize = (position * bitRate / 8) + byteCount; - } - - @Override - public void execute() { - setPlayerState(DOWNLOADING); - - while (!bufferComplete()) { - Util.sleepQuietly(1000L); - if (isCancelled()) { - return; - } - } - doPlay(downloadFile, position, true); - } - - private boolean bufferComplete() { - boolean completeFileAvailable = downloadFile.isWorkDone(); - long size = partialFile.length(); - - Log.i(TAG, "Buffering " + partialFile + " (" + size + "/" + expectedFileSize + ", " + completeFileAvailable + ")"); - return completeFileAvailable || size >= expectedFileSize; - } - - @Override - public String toString() { - return "BufferTask (" + downloadFile + ")"; - } - } - + expectedFileSize = (position * bitRate / 8) + byteCount; + } + + @Override + public void execute() { + setPlayerState(DOWNLOADING); + + while (!bufferComplete()) { + Util.sleepQuietly(1000L); + if (isCancelled()) { + return; + } + } + doPlay(downloadFile, position, true); + } + + private boolean bufferComplete() { + boolean completeFileAvailable = downloadFile.isWorkDone(); + long size = partialFile.length(); + + Log.i(TAG, "Buffering " + partialFile + " (" + size + "/" + expectedFileSize + ", " + completeFileAvailable + ")"); + return completeFileAvailable || size >= expectedFileSize; + } + + @Override + public String toString() { + return "BufferTask (" + downloadFile + ")"; + } + } + private class CheckCompletionTask extends CancellableTask { - private final DownloadFile downloadFile; - private final File partialFile; + private final DownloadFile downloadFile; + private final File partialFile; - public CheckCompletionTask(DownloadFile downloadFile) { + public CheckCompletionTask(DownloadFile downloadFile) { setNextPlayerState(PlayerState.IDLE); - this.downloadFile = downloadFile; + this.downloadFile = downloadFile; if(downloadFile != null) { partialFile = downloadFile.getPartialFile(); } else { partialFile = null; } - } + } - @Override - public void execute() { + @Override + public void execute() { if(downloadFile == null) { return; } - + // Do an initial sleep so this prepare can't compete with main prepare Util.sleepQuietly(5000L); - while (!bufferComplete()) { - Util.sleepQuietly(5000L); - if (isCancelled()) { - return; - } - } - + while (!bufferComplete()) { + Util.sleepQuietly(5000L); + if (isCancelled()) { + return; + } + } + // Start the setup of the next media player mediaPlayerHandler.post(new Runnable() { public void run() { setupNext(downloadFile); } }); - } - - private boolean bufferComplete() { - boolean completeFileAvailable = downloadFile.isWorkDone(); - Log.i(TAG, "Buffering next " + partialFile + " (" + partialFile.length() + ")"); - return completeFileAvailable && (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED); - } - - @Override - public String toString() { - return "CheckCompletionTask (" + downloadFile + ")"; - } - } + } + + private boolean bufferComplete() { + boolean completeFileAvailable = downloadFile.isWorkDone(); + Log.i(TAG, "Buffering next " + partialFile + " (" + partialFile.length() + ")"); + return completeFileAvailable && (playerState == PlayerState.STARTED || playerState == PlayerState.PAUSED); + } + + @Override + public String toString() { + return "CheckCompletionTask (" + downloadFile + ")"; + } + } } diff --git a/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java b/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java index 7b285953..a5f1cff1 100644 --- a/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java +++ b/src/github/daneren2005/dsub/service/DownloadServiceLifecycleSupport.java @@ -53,27 +53,27 @@ import github.daneren2005.dsub.util.Util; */ public class DownloadServiceLifecycleSupport { - private static final String TAG = DownloadServiceLifecycleSupport.class.getSimpleName(); - private static final String FILENAME_DOWNLOADS_SER = "downloadstate2.ser"; - - private final DownloadServiceImpl downloadService; - private Looper eventLooper; - private Handler eventHandler; - private ScheduledExecutorService executorService; - private BroadcastReceiver headsetEventReceiver; - private BroadcastReceiver ejectEventReceiver; - private PhoneStateListener phoneStateListener; - private boolean externalStorageAvailable= true; - private ReentrantLock lock = new ReentrantLock(); - private final AtomicBoolean setup = new AtomicBoolean(false); + private static final String TAG = DownloadServiceLifecycleSupport.class.getSimpleName(); + private static final String FILENAME_DOWNLOADS_SER = "downloadstate2.ser"; + + private final DownloadServiceImpl downloadService; + private Looper eventLooper; + private Handler eventHandler; + private ScheduledExecutorService executorService; + private BroadcastReceiver headsetEventReceiver; + private BroadcastReceiver ejectEventReceiver; + private PhoneStateListener phoneStateListener; + private boolean externalStorageAvailable= true; + private ReentrantLock lock = new ReentrantLock(); + private final AtomicBoolean setup = new AtomicBoolean(false); private long lastPressTime = 0; - /** - * This receiver manages the intent that could come from other applications. - */ - private BroadcastReceiver intentReceiver = new BroadcastReceiver() { - @Override - public void onReceive(final Context context, final Intent intent) { + /** + * This receiver manages the intent that could come from other applications. + */ + private BroadcastReceiver intentReceiver = new BroadcastReceiver() { + @Override + public void onReceive(final Context context, final Intent intent) { eventHandler.post(new Runnable() { @Override public void run() { @@ -95,29 +95,29 @@ public class DownloadServiceLifecycleSupport { } } }); - } - }; - - - public DownloadServiceLifecycleSupport(DownloadServiceImpl downloadService) { - this.downloadService = downloadService; - } - - public void onCreate() { - Runnable downloadChecker = new Runnable() { - @Override - public void run() { - try { - downloadService.checkDownloads(); - } catch (Throwable x) { - Log.e(TAG, "checkDownloads() failed.", x); - } - } - }; - - executorService = Executors.newSingleThreadScheduledExecutor(); - executorService.scheduleWithFixedDelay(downloadChecker, 5, 5, TimeUnit.SECONDS); - + } + }; + + + public DownloadServiceLifecycleSupport(DownloadServiceImpl downloadService) { + this.downloadService = downloadService; + } + + public void onCreate() { + Runnable downloadChecker = new Runnable() { + @Override + public void run() { + try { + downloadService.checkDownloads(); + } catch (Throwable x) { + Log.e(TAG, "checkDownloads() failed.", x); + } + } + }; + + executorService = Executors.newSingleThreadScheduledExecutor(); + executorService.scheduleWithFixedDelay(downloadChecker, 5, 5, TimeUnit.SECONDS); + new Thread(new Runnable() { @Override public void run() { @@ -138,13 +138,13 @@ public class DownloadServiceLifecycleSupport { } }).start(); - // Pause when headset is unplugged. - headsetEventReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - Log.i(TAG, "Headset event for: " + intent.getExtras().get("name")); - if (intent.getExtras().getInt("state") == 0) { - eventHandler.post(new Runnable() { + // Pause when headset is unplugged. + headsetEventReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + Log.i(TAG, "Headset event for: " + intent.getExtras().get("name")); + if (intent.getExtras().getInt("state") == 0) { + eventHandler.post(new Runnable() { @Override public void run() { if(!downloadService.isRemoteEnabled()) { @@ -155,55 +155,55 @@ public class DownloadServiceLifecycleSupport { } } } - }); - } - } - }; - downloadService.registerReceiver(headsetEventReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)); - - // Stop when SD card is ejected. - ejectEventReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - externalStorageAvailable = Intent.ACTION_MEDIA_MOUNTED.equals(intent.getAction()); - if (!externalStorageAvailable) { - Log.i(TAG, "External media is ejecting. Stopping playback."); - downloadService.reset(); - } else { - Log.i(TAG, "External media is available."); - } - } - }; - IntentFilter ejectFilter = new IntentFilter(Intent.ACTION_MEDIA_EJECT); - ejectFilter.addAction(Intent.ACTION_MEDIA_MOUNTED); - ejectFilter.addDataScheme("file"); - downloadService.registerReceiver(ejectEventReceiver, ejectFilter); - - // React to media buttons. - Util.registerMediaButtonEventReceiver(downloadService); - - // Pause temporarily on incoming phone calls. - phoneStateListener = new MyPhoneStateListener(); - TelephonyManager telephonyManager = (TelephonyManager) downloadService.getSystemService(Context.TELEPHONY_SERVICE); - telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); - - // Register the handler for outside intents. - IntentFilter commandFilter = new IntentFilter(); - commandFilter.addAction(DownloadServiceImpl.CMD_PLAY); - commandFilter.addAction(DownloadServiceImpl.CMD_TOGGLEPAUSE); - commandFilter.addAction(DownloadServiceImpl.CMD_PAUSE); - commandFilter.addAction(DownloadServiceImpl.CMD_STOP); - commandFilter.addAction(DownloadServiceImpl.CMD_PREVIOUS); - commandFilter.addAction(DownloadServiceImpl.CMD_NEXT); - downloadService.registerReceiver(intentReceiver, commandFilter); - - new CacheCleaner(downloadService, downloadService).clean(); - } - - public void onStart(Intent intent) { - if (intent != null && intent.getExtras() != null) { - final KeyEvent event = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT); - if (event != null) { + }); + } + } + }; + downloadService.registerReceiver(headsetEventReceiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG)); + + // Stop when SD card is ejected. + ejectEventReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + externalStorageAvailable = Intent.ACTION_MEDIA_MOUNTED.equals(intent.getAction()); + if (!externalStorageAvailable) { + Log.i(TAG, "External media is ejecting. Stopping playback."); + downloadService.reset(); + } else { + Log.i(TAG, "External media is available."); + } + } + }; + IntentFilter ejectFilter = new IntentFilter(Intent.ACTION_MEDIA_EJECT); + ejectFilter.addAction(Intent.ACTION_MEDIA_MOUNTED); + ejectFilter.addDataScheme("file"); + downloadService.registerReceiver(ejectEventReceiver, ejectFilter); + + // React to media buttons. + Util.registerMediaButtonEventReceiver(downloadService); + + // Pause temporarily on incoming phone calls. + phoneStateListener = new MyPhoneStateListener(); + TelephonyManager telephonyManager = (TelephonyManager) downloadService.getSystemService(Context.TELEPHONY_SERVICE); + telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); + + // Register the handler for outside intents. + IntentFilter commandFilter = new IntentFilter(); + commandFilter.addAction(DownloadServiceImpl.CMD_PLAY); + commandFilter.addAction(DownloadServiceImpl.CMD_TOGGLEPAUSE); + commandFilter.addAction(DownloadServiceImpl.CMD_PAUSE); + commandFilter.addAction(DownloadServiceImpl.CMD_STOP); + commandFilter.addAction(DownloadServiceImpl.CMD_PREVIOUS); + commandFilter.addAction(DownloadServiceImpl.CMD_NEXT); + downloadService.registerReceiver(intentReceiver, commandFilter); + + new CacheCleaner(downloadService, downloadService).clean(); + } + + public void onStart(Intent intent) { + if (intent != null && intent.getExtras() != null) { + final KeyEvent event = (KeyEvent) intent.getExtras().get(Intent.EXTRA_KEY_EVENT); + if (event != null) { eventHandler.post(new Runnable() { @Override public void run() { @@ -214,31 +214,31 @@ public class DownloadServiceLifecycleSupport { handleKeyEvent(event); } }); - } - } - } - - public void onDestroy() { - executorService.shutdown(); - eventLooper.quit(); - serializeDownloadQueueNow(); - downloadService.unregisterReceiver(ejectEventReceiver); - downloadService.unregisterReceiver(headsetEventReceiver); - downloadService.unregisterReceiver(intentReceiver); - - TelephonyManager telephonyManager = (TelephonyManager) downloadService.getSystemService(Context.TELEPHONY_SERVICE); - telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE); - } - - public boolean isExternalStorageAvailable() { - return externalStorageAvailable; - } - - public void serializeDownloadQueue() { - if(!setup.get()) { - return; - } - + } + } + } + + public void onDestroy() { + executorService.shutdown(); + eventLooper.quit(); + serializeDownloadQueueNow(); + downloadService.unregisterReceiver(ejectEventReceiver); + downloadService.unregisterReceiver(headsetEventReceiver); + downloadService.unregisterReceiver(intentReceiver); + + TelephonyManager telephonyManager = (TelephonyManager) downloadService.getSystemService(Context.TELEPHONY_SERVICE); + telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_NONE); + } + + public boolean isExternalStorageAvailable() { + return externalStorageAvailable; + } + + public void serializeDownloadQueue() { + if(!setup.get()) { + return; + } + eventHandler.post(new Runnable() { @Override public void run() { @@ -250,11 +250,11 @@ public class DownloadServiceLifecycleSupport { } } } - }); - } - - public void serializeDownloadQueueNow() { - List<DownloadFile> songs = new ArrayList<DownloadFile>(downloadService.getSongs()); + }); + } + + public void serializeDownloadQueueNow() { + List<DownloadFile> songs = new ArrayList<DownloadFile>(downloadService.getSongs()); State state = new State(); for (DownloadFile downloadFile : songs) { state.songs.add(downloadFile.getSong()); @@ -272,14 +272,14 @@ public class DownloadServiceLifecycleSupport { Log.i(TAG, "Serialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); FileUtil.serialize(downloadService, state, FILENAME_DOWNLOADS_SER); - } + } - private void deserializeDownloadQueueNow() { - State state = FileUtil.deserialize(downloadService, FILENAME_DOWNLOADS_SER, State.class); - if (state == null) { - return; - } - Log.i(TAG, "Deserialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); + private void deserializeDownloadQueueNow() { + State state = FileUtil.deserialize(downloadService, FILENAME_DOWNLOADS_SER, State.class); + if (state == null) { + return; + } + Log.i(TAG, "Deserialized currentPlayingIndex: " + state.currentPlayingIndex + ", currentPlayingPosition: " + state.currentPlayingPosition); // Rename first thing before anything else starts if(state.renameCurrent && state.currentPlayingIndex != -1 && state.currentPlayingIndex < state.songs.size()) { @@ -287,10 +287,10 @@ public class DownloadServiceLifecycleSupport { currentPlaying.renamePartial(); } - downloadService.restore(state.songs, state.toDelete, state.currentPlayingIndex, state.currentPlayingPosition); - } + downloadService.restore(state.songs, state.toDelete, state.currentPlayingIndex, state.currentPlayingPosition); + } - private void handleKeyEvent(KeyEvent event) { + private void handleKeyEvent(KeyEvent event) { if(event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() > 0) { switch (event.getKeyCode()) { case RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS: @@ -299,7 +299,7 @@ public class DownloadServiceLifecycleSupport { break; case RemoteControlClient.FLAG_KEY_MEDIA_NEXT: case KeyEvent.KEYCODE_MEDIA_NEXT: - downloadService.seekTo(downloadService.getPlayerPosition() + 10000); + downloadService.seekTo(downloadService.getPlayerPosition() + 10000); break; } } else if(event.getAction() == KeyEvent.ACTION_UP) { @@ -341,49 +341,49 @@ public class DownloadServiceLifecycleSupport { break; } } - } - - /** - * Logic taken from packages/apps/Music. Will pause when an incoming - * call rings or if a call (incoming or outgoing) is connected. - */ - private class MyPhoneStateListener extends PhoneStateListener { - private boolean resumeAfterCall; - - @Override - public void onCallStateChanged(final int state, String incomingNumber) { - eventHandler.post(new Runnable() { + } + + /** + * Logic taken from packages/apps/Music. Will pause when an incoming + * call rings or if a call (incoming or outgoing) is connected. + */ + private class MyPhoneStateListener extends PhoneStateListener { + private boolean resumeAfterCall; + + @Override + public void onCallStateChanged(final int state, String incomingNumber) { + eventHandler.post(new Runnable() { @Override public void run() { switch (state) { - case TelephonyManager.CALL_STATE_RINGING: - case TelephonyManager.CALL_STATE_OFFHOOK: - if (downloadService.getPlayerState() == PlayerState.STARTED && !downloadService.isRemoteEnabled()) { - resumeAfterCall = true; - downloadService.pause(); - } - break; - case TelephonyManager.CALL_STATE_IDLE: - if (resumeAfterCall) { - resumeAfterCall = false; - downloadService.start(); - } - break; - default: - break; - } + case TelephonyManager.CALL_STATE_RINGING: + case TelephonyManager.CALL_STATE_OFFHOOK: + if (downloadService.getPlayerState() == PlayerState.STARTED && !downloadService.isRemoteEnabled()) { + resumeAfterCall = true; + downloadService.pause(); + } + break; + case TelephonyManager.CALL_STATE_IDLE: + if (resumeAfterCall) { + resumeAfterCall = false; + downloadService.start(); + } + break; + default: + break; + } } - }); - } - } + }); + } + } - private static class State implements Serializable { - private static final long serialVersionUID = -6346438781062572271L; + private static class State implements Serializable { + private static final long serialVersionUID = -6346438781062572271L; - private List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>(); + private List<MusicDirectory.Entry> songs = new ArrayList<MusicDirectory.Entry>(); private List<MusicDirectory.Entry> toDelete = new ArrayList<MusicDirectory.Entry>(); - private int currentPlayingIndex; - private int currentPlayingPosition; + private int currentPlayingIndex; + private int currentPlayingPosition; private boolean renameCurrent = false; - } + } } diff --git a/src/github/daneren2005/dsub/util/ShufflePlayBuffer.java b/src/github/daneren2005/dsub/util/ShufflePlayBuffer.java index b92945c4..55858c03 100644 --- a/src/github/daneren2005/dsub/util/ShufflePlayBuffer.java +++ b/src/github/daneren2005/dsub/util/ShufflePlayBuffer.java @@ -39,103 +39,103 @@ import github.daneren2005.dsub.util.FileUtil; */ public class ShufflePlayBuffer { - private static final String TAG = ShufflePlayBuffer.class.getSimpleName(); - private static final String CACHE_FILENAME = "shuffleBuffer.ser"; - private static final int CAPACITY = 50; - private static final int REFILL_THRESHOLD = 40; + private static final String TAG = ShufflePlayBuffer.class.getSimpleName(); + private static final String CACHE_FILENAME = "shuffleBuffer.ser"; + private static final int CAPACITY = 50; + private static final int REFILL_THRESHOLD = 40; - private final ScheduledExecutorService executorService; + private final ScheduledExecutorService executorService; private boolean firstRun = true; - private final ArrayList<MusicDirectory.Entry> buffer = new ArrayList<MusicDirectory.Entry>(); + private final ArrayList<MusicDirectory.Entry> buffer = new ArrayList<MusicDirectory.Entry>(); private int lastCount = -1; - private Context context; - private int currentServer; + private Context context; + private int currentServer; private String currentFolder = ""; - + private String genre = ""; private String startYear = ""; private String endYear = ""; - public ShufflePlayBuffer(Context context) { - this.context = context; - - executorService = Executors.newSingleThreadScheduledExecutor(); - Runnable runnable = new Runnable() { - @Override - public void run() { + public ShufflePlayBuffer(Context context) { + this.context = context; + + executorService = Executors.newSingleThreadScheduledExecutor(); + Runnable runnable = new Runnable() { + @Override + public void run() { refill(); } - }; - executorService.scheduleWithFixedDelay(runnable, 1, 10, TimeUnit.SECONDS); - } - - public List<MusicDirectory.Entry> get(int size) { - clearBufferIfnecessary(); - - List<MusicDirectory.Entry> result = new ArrayList<MusicDirectory.Entry>(size); - synchronized (buffer) { - boolean removed = false; - while (!buffer.isEmpty() && result.size() < size) { - result.add(buffer.remove(buffer.size() - 1)); - removed = true; - } - - // Re-cache if anything is taken out - if(removed) { + }; + executorService.scheduleWithFixedDelay(runnable, 1, 10, TimeUnit.SECONDS); + } + + public List<MusicDirectory.Entry> get(int size) { + clearBufferIfnecessary(); + + List<MusicDirectory.Entry> result = new ArrayList<MusicDirectory.Entry>(size); + synchronized (buffer) { + boolean removed = false; + while (!buffer.isEmpty() && result.size() < size) { + result.add(buffer.remove(buffer.size() - 1)); + removed = true; + } + + // Re-cache if anything is taken out + if(removed) { FileUtil.serialize(context, buffer, CACHE_FILENAME); - } - } - Log.i(TAG, "Taking " + result.size() + " songs from shuffle play buffer. " + buffer.size() + " remaining."); - return result; - } + } + } + Log.i(TAG, "Taking " + result.size() + " songs from shuffle play buffer. " + buffer.size() + " remaining."); + return result; + } - public void shutdown() { - executorService.shutdown(); - } + public void shutdown() { + executorService.shutdown(); + } - private void refill() { + private void refill() { - // Check if active server has changed. - clearBufferIfnecessary(); + // Check if active server has changed. + clearBufferIfnecessary(); - if (buffer != null && (buffer.size() > REFILL_THRESHOLD || (!Util.isNetworkConnected(context) && !Util.isOffline(context)) || lastCount == 0)) { - return; - } + if (buffer != null && (buffer.size() > REFILL_THRESHOLD || (!Util.isNetworkConnected(context) && !Util.isOffline(context)) || lastCount == 0)) { + return; + } - try { - MusicService service = MusicServiceFactory.getMusicService(context); - int n = CAPACITY - buffer.size(); + try { + MusicService service = MusicServiceFactory.getMusicService(context); + int n = CAPACITY - buffer.size(); String folder = Util.getSelectedMusicFolderId(context); - MusicDirectory songs = service.getRandomSongs(n, folder, genre, startYear, endYear, context, null); + MusicDirectory songs = service.getRandomSongs(n, folder, genre, startYear, endYear, context, null); - synchronized (buffer) { - buffer.addAll(songs.getChildren()); - Log.i(TAG, "Refilled shuffle play buffer with " + songs.getChildrenSize() + " songs."); + synchronized (buffer) { + buffer.addAll(songs.getChildren()); + Log.i(TAG, "Refilled shuffle play buffer with " + songs.getChildrenSize() + " songs."); lastCount = songs.getChildrenSize(); - + // Cache buffer FileUtil.serialize(context, buffer, CACHE_FILENAME); - } - } catch (Exception x) { - Log.w(TAG, "Failed to refill shuffle play buffer.", x); - } - } - - private void clearBufferIfnecessary() { - synchronized (buffer) { + } + } catch (Exception x) { + Log.w(TAG, "Failed to refill shuffle play buffer.", x); + } + } + + private void clearBufferIfnecessary() { + synchronized (buffer) { final SharedPreferences prefs = Util.getPreferences(context); - if (currentServer != Util.getActiveServer(context) - || (currentFolder != null && !currentFolder.equals(Util.getSelectedMusicFolderId(context))) - || (genre != null && !genre.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""))) - || (startYear != null && !startYear.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""))) - || (endYear != null && !endYear.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, "")))) { + if (currentServer != Util.getActiveServer(context) + || (currentFolder != null && !currentFolder.equals(Util.getSelectedMusicFolderId(context))) + || (genre != null && !genre.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""))) + || (startYear != null && !startYear.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""))) + || (endYear != null && !endYear.equals(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, "")))) { lastCount = -1; - currentServer = Util.getActiveServer(context); + currentServer = Util.getActiveServer(context); currentFolder = Util.getSelectedMusicFolderId(context); genre = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_GENRE, ""); startYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_START_YEAR, ""); endYear = prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_END_YEAR, ""); - buffer.clear(); + buffer.clear(); if(firstRun) { ArrayList cacheList = FileUtil.deserialize(context, CACHE_FILENAME, ArrayList.class); @@ -148,7 +148,7 @@ public class ShufflePlayBuffer { File file = new File(context.getCacheDir(), CACHE_FILENAME); file.delete(); } - } - } - } + } + } + } } |