From f0879be88ce68f3c1ce197ff35141f2d68edd046 Mon Sep 17 00:00:00 2001 From: Scott Jackson Date: Mon, 16 Feb 2015 19:10:39 -0800 Subject: #435 Add Artist Radio --- res/drawable-hdpi/ic_menu_radio_dark.png | Bin 0 -> 768 bytes res/drawable-hdpi/ic_menu_radio_light.png | Bin 0 -> 878 bytes res/drawable-mdpi/ic_menu_radio_dark.png | Bin 0 -> 578 bytes res/drawable-mdpi/ic_menu_radio_light.png | Bin 0 -> 675 bytes res/drawable-xhdpi/ic_menu_radio_dark.png | Bin 0 -> 1131 bytes res/drawable-xhdpi/ic_menu_radio_light.png | Bin 0 -> 1376 bytes res/drawable-xxhdpi/ic_menu_radio_dark.png | Bin 0 -> 1992 bytes res/drawable-xxhdpi/ic_menu_radio_light.png | Bin 0 -> 2310 bytes res/menu/select_album.xml | 6 + res/values/attrs.xml | 1 + res/values/strings.xml | 1 + res/values/themes.xml | 2 + .../dsub/fragments/SelectDirectoryFragment.java | 27 +++- .../dsub/service/CachedMusicService.java | 5 + .../daneren2005/dsub/service/DownloadService.java | 100 ++++++++++++-- .../daneren2005/dsub/service/MusicService.java | 1 + .../dsub/service/OfflineMusicService.java | 7 +- .../daneren2005/dsub/service/RESTMusicService.java | 22 +++ .../daneren2005/dsub/util/ArtistRadioBuffer.java | 150 +++++++++++++++++++++ src/github/daneren2005/dsub/util/Constants.java | 3 +- 20 files changed, 309 insertions(+), 16 deletions(-) create mode 100644 res/drawable-hdpi/ic_menu_radio_dark.png create mode 100644 res/drawable-hdpi/ic_menu_radio_light.png create mode 100644 res/drawable-mdpi/ic_menu_radio_dark.png create mode 100644 res/drawable-mdpi/ic_menu_radio_light.png create mode 100644 res/drawable-xhdpi/ic_menu_radio_dark.png create mode 100644 res/drawable-xhdpi/ic_menu_radio_light.png create mode 100644 res/drawable-xxhdpi/ic_menu_radio_dark.png create mode 100644 res/drawable-xxhdpi/ic_menu_radio_light.png create mode 100644 src/github/daneren2005/dsub/util/ArtistRadioBuffer.java diff --git a/res/drawable-hdpi/ic_menu_radio_dark.png b/res/drawable-hdpi/ic_menu_radio_dark.png new file mode 100644 index 00000000..a801dce0 Binary files /dev/null and b/res/drawable-hdpi/ic_menu_radio_dark.png differ diff --git a/res/drawable-hdpi/ic_menu_radio_light.png b/res/drawable-hdpi/ic_menu_radio_light.png new file mode 100644 index 00000000..b723d574 Binary files /dev/null and b/res/drawable-hdpi/ic_menu_radio_light.png differ diff --git a/res/drawable-mdpi/ic_menu_radio_dark.png b/res/drawable-mdpi/ic_menu_radio_dark.png new file mode 100644 index 00000000..bab20118 Binary files /dev/null and b/res/drawable-mdpi/ic_menu_radio_dark.png differ diff --git a/res/drawable-mdpi/ic_menu_radio_light.png b/res/drawable-mdpi/ic_menu_radio_light.png new file mode 100644 index 00000000..72578d54 Binary files /dev/null and b/res/drawable-mdpi/ic_menu_radio_light.png differ diff --git a/res/drawable-xhdpi/ic_menu_radio_dark.png b/res/drawable-xhdpi/ic_menu_radio_dark.png new file mode 100644 index 00000000..3a4114a3 Binary files /dev/null and b/res/drawable-xhdpi/ic_menu_radio_dark.png differ diff --git a/res/drawable-xhdpi/ic_menu_radio_light.png b/res/drawable-xhdpi/ic_menu_radio_light.png new file mode 100644 index 00000000..5bcc9261 Binary files /dev/null and b/res/drawable-xhdpi/ic_menu_radio_light.png differ diff --git a/res/drawable-xxhdpi/ic_menu_radio_dark.png b/res/drawable-xxhdpi/ic_menu_radio_dark.png new file mode 100644 index 00000000..0c63afbe Binary files /dev/null and b/res/drawable-xxhdpi/ic_menu_radio_dark.png differ diff --git a/res/drawable-xxhdpi/ic_menu_radio_light.png b/res/drawable-xxhdpi/ic_menu_radio_light.png new file mode 100644 index 00000000..133772f8 Binary files /dev/null and b/res/drawable-xxhdpi/ic_menu_radio_light.png differ diff --git a/res/menu/select_album.xml b/res/menu/select_album.xml index 39eb2206..a9741d84 100644 --- a/res/menu/select_album.xml +++ b/res/menu/select_album.xml @@ -6,6 +6,12 @@ android:icon="?media_button_start" android:title="@string/menu.play" compat:showAsAction="always|withText"/> + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 43c4650b..eed2f1c7 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -107,6 +107,7 @@ Last.FM Top Tracks Similar Artists Show missing + Start Radio Playlists Update Information diff --git a/res/values/themes.xml b/res/values/themes.xml index 70f30e56..78a2c34d 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -28,6 +28,7 @@ @drawable/ic_menu_password_light @drawable/ic_action_rating_bad_light @drawable/ic_action_rating_good_light + @drawable/ic_menu_radio_light @array/drawerItemIconsLight @style/DSub.TextViewStyle @style/DSub.ButtonStyle.Light @@ -62,6 +63,7 @@ @drawable/ic_menu_password_dark @drawable/ic_action_rating_bad_dark @drawable/ic_action_rating_good_dark + @drawable/ic_menu_radio_dark @array/drawerItemIconsDark @style/DSub.TextViewStyle @style/DSub.ButtonStyle.Dark diff --git a/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java b/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java index 9e6608cf..b8a1006b 100644 --- a/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java +++ b/src/github/daneren2005/dsub/fragments/SelectDirectoryFragment.java @@ -42,6 +42,7 @@ import github.daneren2005.dsub.domain.ArtistInfo; import github.daneren2005.dsub.domain.MusicDirectory; import github.daneren2005.dsub.domain.ServerInfo; import github.daneren2005.dsub.domain.Share; +import github.daneren2005.dsub.service.DownloadService; import github.daneren2005.dsub.util.ImageLoader; import github.daneren2005.dsub.view.AlbumGridAdapter; import github.daneren2005.dsub.view.EntryAdapter; @@ -227,8 +228,9 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter if(!ServerInfo.isMadsonic(context)) { menu.removeItem(R.id.menu_top_tracks); } - if(!ServerInfo.checkServerVersion(context, "1.11")) { + if(!ServerInfo.checkServerVersion(context, "1.11") || !ServerInfo.isStockSubsonic(context)) { menu.removeItem(R.id.menu_similar_artists); + menu.removeItem(R.id.menu_radio); } } else { if(podcastId == null) { @@ -320,6 +322,9 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter case R.id.menu_similar_artists: showSimilarArtists(id); return true; + case R.id.menu_radio: + startArtistRadio(id); + return true; } return super.onOptionsItemSelected(item); @@ -1268,6 +1273,26 @@ public class SelectDirectoryFragment extends SubsonicFragment implements Adapter replaceFragment(fragment, true); } + private void startArtistRadio(final String artistId) { + new LoadingTask(context) { + @Override + protected Void doInBackground() throws Throwable { + DownloadService downloadService = getDownloadService(); + downloadService.setArtistRadio(artistId); + if(downloadService.size() == 0) { + Log.e(TAG, "Failed to create artist radio"); + throw new Exception("Failed to create artist radio"); + } + return null; + } + + @Override + protected void done(Void result) { + Util.startActivityWithoutTransition(context, DownloadActivity.class); + } + }.execute(); + } + private View createHeader() { View header = entryList.findViewById(R.id.select_album_header); boolean add = false; diff --git a/src/github/daneren2005/dsub/service/CachedMusicService.java b/src/github/daneren2005/dsub/service/CachedMusicService.java index 124ae615..09347d1d 100644 --- a/src/github/daneren2005/dsub/service/CachedMusicService.java +++ b/src/github/daneren2005/dsub/service/CachedMusicService.java @@ -465,6 +465,11 @@ public class CachedMusicService implements MusicService { return musicService.getAlbumList(type, extra, size, offset, context, progressListener); } + @Override + public MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception { + return musicService.getRandomSongs(size, artistId, context, progressListener); + } + @Override public MusicDirectory getStarredList(Context context, ProgressListener progressListener) throws Exception { MusicDirectory dir = musicService.getStarredList(context, progressListener); diff --git a/src/github/daneren2005/dsub/service/DownloadService.java b/src/github/daneren2005/dsub/service/DownloadService.java index 8c6016ba..5726b696 100644 --- a/src/github/daneren2005/dsub/service/DownloadService.java +++ b/src/github/daneren2005/dsub/service/DownloadService.java @@ -41,6 +41,7 @@ import github.daneren2005.dsub.domain.RemoteControlState; import github.daneren2005.dsub.domain.RepeatMode; import github.daneren2005.dsub.domain.ServerInfo; import github.daneren2005.dsub.receiver.MediaButtonIntentReceiver; +import github.daneren2005.dsub.util.ArtistRadioBuffer; import github.daneren2005.dsub.util.Notifications; import github.daneren2005.dsub.util.SilentBackgroundTask; import github.daneren2005.dsub.util.Constants; @@ -100,6 +101,9 @@ public class DownloadService extends Service { public static final int REWIND = 10000; private static final double DELETE_CUTOFF = 0.84; private static final int REQUIRED_ALBUM_MATCHES = 4; + private static final int SHUFFLE_MODE_NONE = 0; + private static final int SHUFFLE_MODE_ALL = 1; + private static final int SHUFFLE_MODE_ARTIST = 2; private RemoteControlClientHelper mRemoteControl; @@ -116,6 +120,7 @@ public class DownloadService extends Service { private Handler mediaPlayerHandler; private final DownloadServiceLifecycleSupport lifecycleSupport = new DownloadServiceLifecycleSupport(this); private ShufflePlayBuffer shufflePlayBuffer; + private ArtistRadioBuffer artistRadioBuffer; private final LruCache downloadFileCache = new LruCache(100); private final List cleanupCandidates = new ArrayList(); @@ -131,6 +136,7 @@ public class DownloadService extends Service { private PlayerState nextPlayerState = IDLE; private boolean removePlayed; private boolean shufflePlay; + private boolean artistRadio; private long revision; private static DownloadService instance; private String suggestedPlaylistName; @@ -229,6 +235,7 @@ public class DownloadService extends Service { instance = this; lifecycleSupport.onCreate(); shufflePlayBuffer = new ShufflePlayBuffer(this); + artistRadioBuffer = new ArtistRadioBuffer(this); } @Override @@ -313,6 +320,7 @@ public class DownloadService extends Service { } public synchronized void download(List songs, boolean save, boolean autoplay, boolean playNext, boolean shuffle, int start, int position) { setShufflePlayEnabled(false); + setArtistRadio(null); int offset = 1; boolean noNetwork = !Util.isOffline(this) && !Util.isNetworkConnected(this); boolean warnNetwork = false; @@ -355,7 +363,7 @@ public class DownloadService extends Service { } revision++; } - updateJukeboxPlaylist(); + updateRemotePlaylist(); if(shuffle) { shuffle(); @@ -406,7 +414,7 @@ public class DownloadService extends Service { lifecycleSupport.serializeDownloadQueue(); } - private void updateJukeboxPlaylist() { + private void updateRemotePlaylist() { if (remoteState != LOCAL && remoteController != null) { remoteController.updatePlaylist(); } @@ -422,12 +430,17 @@ public class DownloadService extends Service { if(prefs.getBoolean(Constants.PREFERENCES_KEY_REMOVE_PLAYED, false)) { removePlayed = true; } - boolean startShufflePlay = prefs.getBoolean(Constants.PREFERENCES_KEY_SHUFFLE_MODE, false); + int startShufflePlay = prefs.getInt(Constants.PREFERENCES_KEY_SHUFFLE_MODE, SHUFFLE_MODE_NONE); download(songs, false, false, false, false); - if(startShufflePlay) { - shufflePlay = true; + if(startShufflePlay != SHUFFLE_MODE_NONE) { + if(startShufflePlay == SHUFFLE_MODE_ALL) { + shufflePlay = true; + } else { + artistRadio = true; + artistRadioBuffer.restoreArtist(prefs.getString(Constants.PREFERENCES_KEY_SHUFFLE_MODE_EXTRA, null)); + } SharedPreferences.Editor editor = prefs.edit(); - editor.putBoolean(Constants.PREFERENCES_KEY_SHUFFLE_MODE, true); + editor.putInt(Constants.PREFERENCES_KEY_SHUFFLE_MODE, startShufflePlay); editor.commit(); } if (currentPlayingIndex != -1) { @@ -470,7 +483,7 @@ public class DownloadService extends Service { checkDownloads(); } SharedPreferences.Editor editor = Util.getPreferences(this).edit(); - editor.putBoolean(Constants.PREFERENCES_KEY_SHUFFLE_MODE, enabled); + editor.putInt(Constants.PREFERENCES_KEY_SHUFFLE_MODE, enabled ? SHUFFLE_MODE_ALL : SHUFFLE_MODE_NONE); editor.commit(); } @@ -478,6 +491,20 @@ public class DownloadService extends Service { return shufflePlay; } + public void setArtistRadio(String artistId) { + if(artistId == null) { + artistRadio = false; + } else { + artistRadio = true; + artistRadioBuffer.setArtist(artistId); + } + + SharedPreferences.Editor editor = Util.getPreferences(this).edit(); + editor.putInt(Constants.PREFERENCES_KEY_SHUFFLE_MODE, (artistId != null) ? SHUFFLE_MODE_ARTIST : SHUFFLE_MODE_NONE); + editor.putString(Constants.PREFERENCES_KEY_SHUFFLE_MODE_EXTRA, artistId); + editor.commit(); + } + public synchronized void shuffle() { Collections.shuffle(downloadList); currentPlayingIndex = downloadList.indexOf(currentPlaying); @@ -488,7 +515,7 @@ public class DownloadService extends Service { } revision++; lifecycleSupport.serializeDownloadQueue(); - updateJukeboxPlaylist(); + updateRemotePlaylist(); setNextPlaying(); } @@ -575,7 +602,7 @@ public class DownloadService extends Service { } } lifecycleSupport.serializeDownloadQueue(); - updateJukeboxPlaylist(); + updateRemotePlaylist(); } public void setOnline(final boolean online) { @@ -587,6 +614,9 @@ public class DownloadService extends Service { if(shufflePlay) { setShufflePlayEnabled(false); } + if(artistRadio) { + setArtistRadio(null); + } lifecycleSupport.post(new Runnable() { @Override @@ -645,7 +675,7 @@ public class DownloadService extends Service { if (serialize) { lifecycleSupport.serializeDownloadQueue(); } - updateJukeboxPlaylist(); + updateRemotePlaylist(); setNextPlaying(); if(proxy != null) { proxy.stop(); @@ -675,7 +705,7 @@ public class DownloadService extends Service { backgroundDownloadList.remove(downloadFile); revision++; lifecycleSupport.serializeDownloadQueue(); - updateJukeboxPlaylist(); + updateRemotePlaylist(); if(downloadFile == nextPlaying) { setNextPlaying(); } @@ -1742,7 +1772,7 @@ public class DownloadService extends Service { list.add(to, movedSong); currentPlayingIndex = downloadList.indexOf(currentPlaying); if(remoteState != LOCAL && mainList) { - updateJukeboxPlaylist(); + updateRemotePlaylist(); } else if(mainList && (movedSong == nextPlaying || movedSong == currentPlaying || (currentPlayingIndex + 1) == to)) { // Moving next playing, current playing, or moving a song to be next playing setNextPlaying(); @@ -1787,6 +1817,9 @@ public class DownloadService extends Service { if (shufflePlay) { checkShufflePlay(); } + if(artistRadio) { + checkArtistRadio(); + } if (!Util.isNetworkConnected(this, true) || Util.isOffline(this)) { return; @@ -1913,7 +1946,48 @@ public class DownloadService extends Service { currentPlayingIndex = downloadList.indexOf(currentPlaying); if (revisionBefore != revision) { - updateJukeboxPlaylist(); + updateRemotePlaylist(); + } + + if (wasEmpty && !downloadList.isEmpty()) { + play(0); + } + } + + private synchronized void checkArtistRadio() { + // 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 : artistRadioBuffer.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 : artistRadioBuffer.get(songsToShift)) { + downloadList.add(new DownloadFile(this, song, false)); + downloadList.get(0).cancelDownload(); + downloadList.remove(0); + revision++; + } + } + currentPlayingIndex = downloadList.indexOf(currentPlaying); + + if (revisionBefore != revision) { + updateRemotePlaylist(); } if (wasEmpty && !downloadList.isEmpty()) { diff --git a/src/github/daneren2005/dsub/service/MusicService.java b/src/github/daneren2005/dsub/service/MusicService.java index 854a0aa4..2c5a7f2a 100644 --- a/src/github/daneren2005/dsub/service/MusicService.java +++ b/src/github/daneren2005/dsub/service/MusicService.java @@ -93,6 +93,7 @@ public interface MusicService { MusicDirectory getAlbumList(String type, String extra, int size, int offset, Context context, ProgressListener progressListener) throws Exception; + MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception; MusicDirectory getRandomSongs(int size, String folder, String genre, String startYear, String endYear, Context context, ProgressListener progressListener) throws Exception; String getCoverArtUrl(Context context, MusicDirectory.Entry entry) throws Exception; diff --git a/src/github/daneren2005/dsub/service/OfflineMusicService.java b/src/github/daneren2005/dsub/service/OfflineMusicService.java index 254592da..c0fc89fe 100644 --- a/src/github/daneren2005/dsub/service/OfflineMusicService.java +++ b/src/github/daneren2005/dsub/service/OfflineMusicService.java @@ -531,7 +531,12 @@ public class OfflineMusicService implements MusicService { throw new OfflineException(ERRORMSG); } - @Override + @Override + public MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception { + throw new OfflineException(ERRORMSG); + } + + @Override public String getVideoUrl(int maxBitrate, Context context, String id) { return null; } diff --git a/src/github/daneren2005/dsub/service/RESTMusicService.java b/src/github/daneren2005/dsub/service/RESTMusicService.java index 8db42677..715d07da 100644 --- a/src/github/daneren2005/dsub/service/RESTMusicService.java +++ b/src/github/daneren2005/dsub/service/RESTMusicService.java @@ -570,6 +570,28 @@ public class RESTMusicService implements MusicService { } } + @Override + public MusicDirectory getRandomSongs(int size, String artistId, Context context, ProgressListener progressListener) throws Exception { + checkServerVersion(context, "1.11", "Artist radio is not supported"); + + List names = new ArrayList(); + List values = new ArrayList(); + + names.add("id"); + names.add("count"); + + values.add(artistId); + values.add(size); + + int instance = getInstance(context); + Reader reader = getReader(context, progressListener, Util.isTagBrowsing(context, instance) ? "getSimilarSongs2" : "getSimilarSongs", null, names, values); + try { + return new RandomSongsParser(context, instance).parse(reader, progressListener); + } finally { + Util.close(reader); + } + } + @Override public MusicDirectory getStarredList(Context context, ProgressListener progressListener) throws Exception { Reader reader = getReader(context, progressListener, Util.isTagBrowsing(context, getInstance(context)) ? "getStarred2" : "getStarred", null); diff --git a/src/github/daneren2005/dsub/util/ArtistRadioBuffer.java b/src/github/daneren2005/dsub/util/ArtistRadioBuffer.java new file mode 100644 index 00000000..829478f7 --- /dev/null +++ b/src/github/daneren2005/dsub/util/ArtistRadioBuffer.java @@ -0,0 +1,150 @@ +/* + This file is part of Subsonic. + Subsonic is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + Subsonic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with Subsonic. If not, see . + Copyright 2014 (C) Scott Jackson +*/ + +package github.daneren2005.dsub.util; + +import android.util.Log; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; + +import github.daneren2005.dsub.domain.MusicDirectory; +import github.daneren2005.dsub.service.DownloadService; +import github.daneren2005.dsub.service.MusicService; +import github.daneren2005.dsub.service.MusicServiceFactory; + +public class ArtistRadioBuffer { + private static final String TAG = ArtistRadioBuffer.class.getSimpleName(); + + private ScheduledExecutorService executorService; + private Runnable runnable; + private final ArrayList buffer = new ArrayList(); + private int lastCount = -1; + private DownloadService context; + private boolean awaitingResults = false; + private int capacity; + private int refillThreshold; + + private String artistId; + + public ArtistRadioBuffer(DownloadService context) { + this.context = context; + + executorService = Executors.newSingleThreadScheduledExecutor(); + runnable = new Runnable() { + @Override + public void run() { + refill(); + } + }; + + // Calculate out the capacity and refill threshold based on the user's random size preference + int shuffleListSize = Integer.parseInt(Util.getPreferences(context).getString(Constants.PREFERENCES_KEY_RANDOM_SIZE, "20")); + // ex: default 20 -> 50 + capacity = shuffleListSize * 5 / 2; + capacity = Math.min(500, capacity); + + // ex: default 20 -> 40 + refillThreshold = capacity * 4 / 5; + } + + public void setArtist(String artistId) { + if(!Util.equals(this.artistId, artistId)) { + buffer.clear(); + } + + context.clear(); + this.artistId = artistId; + awaitingResults = true; + refill(); + } + public void restoreArtist(String artistId) { + this.artistId = artistId; + awaitingResults = false; + restart(); + } + + public List get(int size) { + // Make sure fetcher is running if needed + restart(); + + List result = new ArrayList(size); + synchronized (buffer) { + while (!buffer.isEmpty() && result.size() < size) { + result.add(buffer.remove(buffer.size() - 1)); + } + } + Log.i(TAG, "Taking " + result.size() + " songs from shuffle play buffer. " + buffer.size() + " remaining."); + if(result.isEmpty()) { + awaitingResults = true; + } + return result; + } + + public void shutdown() { + executorService.shutdown(); + } + + private void restart() { + synchronized(buffer) { + if(buffer.size() <= refillThreshold && lastCount != 0 && executorService.isShutdown()) { + executorService = Executors.newSingleThreadScheduledExecutor(); + executorService.scheduleWithFixedDelay(runnable, 0, 10, TimeUnit.SECONDS); + } + } + } + + private void refill() { + if (buffer != null && (buffer.size() > refillThreshold || (!Util.isNetworkConnected(context) && !Util.isOffline(context)) || lastCount == 0)) { + executorService.shutdown(); + return; + } + + try { + MusicService service = MusicServiceFactory.getMusicService(context); + + // Get capacity based + int n = capacity - buffer.size(); + MusicDirectory songs = service.getRandomSongs(n, artistId, context, null); + + synchronized (buffer) { + lastCount = 0; + for(MusicDirectory.Entry entry: songs.getChildren()) { + if(!buffer.contains(entry)) { + buffer.add(entry); + lastCount++; + } + } + Log.i(TAG, "Refilled artist radio buffer with " + lastCount + " songs."); + } + } catch (Exception x) { + // Give it one more try before quitting + if(lastCount != -2) { + lastCount = -2; + } else if(lastCount == -2) { + lastCount = 0; + } + Log.w(TAG, "Failed to refill artist radio buffer.", x); + } + + if(awaitingResults) { + awaitingResults = false; + context.checkDownloads(); + } + } +} diff --git a/src/github/daneren2005/dsub/util/Constants.java b/src/github/daneren2005/dsub/util/Constants.java index 7298c7b4..d97fe8d0 100644 --- a/src/github/daneren2005/dsub/util/Constants.java +++ b/src/github/daneren2005/dsub/util/Constants.java @@ -113,7 +113,8 @@ public final class Constants { public static final String PREFERENCES_KEY_PERSISTENT_NOTIFICATION = "persistentNotification"; public static final String PREFERENCES_KEY_GAPLESS_PLAYBACK = "gaplessPlayback"; public static final String PREFERENCES_KEY_REMOVE_PLAYED = "removePlayed"; - public static final String PREFERENCES_KEY_SHUFFLE_MODE = "shuffleMode"; + public static final String PREFERENCES_KEY_SHUFFLE_MODE = "shuffleMode2"; + public static final String PREFERENCES_KEY_SHUFFLE_MODE_EXTRA = "shuffleModeExtra"; public static final String PREFERENCES_KEY_CHAT_REFRESH = "chatRefreshRate"; public static final String PREFERENCES_KEY_CHAT_ENABLED = "chatEnabled"; public static final String PREFERENCES_KEY_VIDEO_PLAYER = "videoPlayer"; -- cgit v1.2.3