Moved externally visible functions to interface, added comments

This commit is contained in:
Nite 2020-06-26 15:18:14 +02:00
parent 0bef3ae417
commit bbe9f39300
No known key found for this signature in database
GPG Key ID: 1D1AD59B1C6386C1
22 changed files with 180 additions and 74 deletions

View File

@ -34,6 +34,7 @@ import org.moire.ultrasonic.R;
import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
import org.moire.ultrasonic.service.DownloadFile;
import org.moire.ultrasonic.service.MediaPlayerController;
import org.moire.ultrasonic.service.MusicService;
import org.moire.ultrasonic.service.MusicServiceFactory;
import org.moire.ultrasonic.util.Constants;
@ -296,7 +297,8 @@ public class BookmarkActivity extends SubsonicTabActivity
private void enableButtons()
{
if (getMediaPlayerController() == null)
MediaPlayerController mediaPlayerController = getMediaPlayerController();
if (mediaPlayerController == null)
{
return;
}
@ -310,7 +312,7 @@ public class BookmarkActivity extends SubsonicTabActivity
for (MusicDirectory.Entry song : selection)
{
DownloadFile downloadFile = downloader.getValue().getDownloadFileForSong(song);
DownloadFile downloadFile = mediaPlayerController.getDownloadFileForSong(song);
if (downloadFile.isWorkDone())
{
deleteEnabled = true;

View File

@ -293,7 +293,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
@Override
protected Boolean doInBackground() throws Throwable
{
if (downloader.getValue().getCurrentPlayingIndex() < downloader.getValue().downloadList.size() - 1)
if (getMediaPlayerController().getCurrentPlayingNumberOnPlaylist() < getMediaPlayerController().getPlaylistSize() - 1)
{
getMediaPlayerController().next();
return true;
@ -567,7 +567,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
final MediaPlayerController mediaPlayerController = getMediaPlayerController();
if (mediaPlayerController == null || localMediaPlayer.getValue().currentPlaying == null)
if (mediaPlayerController == null || mediaPlayerController.getCurrentPlaying() == null)
{
playlistFlipper.setDisplayedChild(1);
}
@ -632,7 +632,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
}
}
final DownloadFile currentDownloading = downloader.getValue().currentDownloading;
final DownloadFile currentDownloading = getMediaPlayerController().getCurrentDownloading();
for (int i = 0; i < count; i++)
{
if (currentDownloading == playlistView.getItemAtPosition(i))
@ -782,7 +782,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
if (mediaPlayerController != null)
{
DownloadFile downloadFile = localMediaPlayer.getValue().currentPlaying;
DownloadFile downloadFile = mediaPlayerController.getCurrentPlaying();
if (downloadFile != null)
{
@ -1019,7 +1019,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
onDownloadListChanged();
return true;
case R.id.menu_item_save_playlist:
if (!downloader.getValue().downloadList.isEmpty())
if (getMediaPlayerController().getPlaylistSize() > 0)
{
showDialog(DIALOG_SAVE_PLAYLIST);
}
@ -1142,7 +1142,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
if (mediaPlayerController != null)
{
List<DownloadFile> downloadServiceSongs = downloader.getValue().downloadList;
List<DownloadFile> downloadServiceSongs = mediaPlayerController.getPlayList();
if (downloadServiceSongs != null)
{
@ -1170,17 +1170,18 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
private void update()
{
if (getMediaPlayerController() == null)
MediaPlayerController mediaPlayerController = getMediaPlayerController();
if (mediaPlayerController == null)
{
return;
}
if (currentRevision != downloader.getValue().getDownloadListUpdateRevision())
if (currentRevision != mediaPlayerController.getPlayListUpdateRevision())
{
onDownloadListChanged();
}
if (currentPlaying != localMediaPlayer.getValue().currentPlaying)
if (currentPlaying != mediaPlayerController.getCurrentPlaying())
{
onCurrentChanged();
}
@ -1199,7 +1200,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
protected Void doInBackground() throws Throwable
{
final List<MusicDirectory.Entry> entries = new LinkedList<MusicDirectory.Entry>();
for (final DownloadFile downloadFile : downloader.getValue().downloadList)
for (final DownloadFile downloadFile : getMediaPlayerController().getPlayList())
{
entries.add(downloadFile.getSong());
}
@ -1254,7 +1255,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
{
warnIfNetworkOrStorageUnavailable();
final int current = downloader.getValue().getCurrentPlayingIndex();
final int current = getMediaPlayerController().getCurrentPlayingNumberOnPlaylist();
if (current == -1)
{
@ -1275,7 +1276,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
return;
}
final List<DownloadFile> list = downloader.getValue().downloadList;
final List<DownloadFile> list = mediaPlayerController.getPlayList();
emptyTextView.setText(R.string.download_empty);
final SongListAdapter adapter = new SongListAdapter(this, list);
@ -1313,7 +1314,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
return;
}
DownloadFile currentPlaying = localMediaPlayer.getValue().currentPlaying;
DownloadFile currentPlaying = mediaPlayerController.getCurrentPlaying();
if (currentPlaying == item)
{
@ -1333,7 +1334,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
});
emptyTextView.setVisibility(list.isEmpty() ? View.VISIBLE : View.GONE);
currentRevision = downloader.getValue().getDownloadListUpdateRevision();
currentRevision = mediaPlayerController.getPlayListUpdateRevision();
switch (mediaPlayerController.getRepeatMode())
{
@ -1360,13 +1361,13 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
return;
}
currentPlaying = localMediaPlayer.getValue().currentPlaying;
currentPlaying = mediaPlayerController.getCurrentPlaying();
scrollToCurrent();
long totalDuration = downloader.getValue().getDownloadListDuration();
long totalSongs = downloader.getValue().downloadList.size();
int currentSongIndex = downloader.getValue().getCurrentPlayingIndex() + 1;
long totalDuration = mediaPlayerController.getPlayListDuration();
long totalSongs = mediaPlayerController.getPlaylistSize();
int currentSongIndex = mediaPlayerController.getCurrentPlayingNumberOnPlaylist() + 1;
String duration = Util.formatTotalDuration(totalDuration);
@ -1580,7 +1581,7 @@ public class DownloadActivity extends SubsonicTabActivity implements OnGestureLi
if (e1X - e2X > swipeDistance && absX > swipeVelocity)
{
warnIfNetworkOrStorageUnavailable();
if (downloader.getValue().getCurrentPlayingIndex() < downloader.getValue().downloadList.size() - 1)
if (mediaPlayerController.getCurrentPlayingNumberOnPlaylist() < mediaPlayerController.getPlaylistSize() - 1)
{
mediaPlayerController.next();
onCurrentChanged();

View File

@ -520,7 +520,7 @@ public class SearchActivity extends SubsonicTabActivity
if (autoplay)
{
mediaPlayerController.play(downloader.getValue().downloadList.size() - 1);
mediaPlayerController.play(mediaPlayerController.getPlaylistSize() - 1);
}
Util.toast(SearchActivity.this, getResources().getQuantityString(R.plurals.select_album_n_songs_added, 1, 1));

View File

@ -40,6 +40,7 @@ import org.moire.ultrasonic.R;
import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.domain.Share;
import org.moire.ultrasonic.service.DownloadFile;
import org.moire.ultrasonic.service.MediaPlayerController;
import org.moire.ultrasonic.service.MusicService;
import org.moire.ultrasonic.service.MusicServiceFactory;
import org.moire.ultrasonic.util.AlbumHeader;
@ -1010,7 +1011,8 @@ public class SelectAlbumActivity extends SubsonicTabActivity
private void enableButtons()
{
if (getMediaPlayerController() == null)
MediaPlayerController mediaPlayerController = getMediaPlayerController();
if (mediaPlayerController == null)
{
return;
}
@ -1024,7 +1026,7 @@ public class SelectAlbumActivity extends SubsonicTabActivity
for (MusicDirectory.Entry song : selection)
{
DownloadFile downloadFile = downloader.getValue().getDownloadFileForSong(song);
DownloadFile downloadFile = mediaPlayerController.getDownloadFileForSong(song);
if (downloadFile.isWorkDone())
{
deleteEnabled = true;

View File

@ -78,9 +78,6 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen
private Lazy<MediaPlayerController> mediaPlayerControllerLazy = inject(MediaPlayerController.class);
private Lazy<MediaPlayerLifecycleSupport> lifecycleSupport = inject(MediaPlayerLifecycleSupport.class);
protected Lazy<Downloader> downloader = inject(Downloader.class);
protected Lazy<LocalMediaPlayer> localMediaPlayer = inject(LocalMediaPlayer.class);
public MenuDrawer menuDrawer;
private int activePosition = 1;
@ -269,7 +266,7 @@ public class SubsonicTabActivity extends ResultActivity implements OnClickListen
if (playerState.equals(PlayerState.PAUSED) || playerState.equals(PlayerState.STARTED))
{
DownloadFile file = localMediaPlayer.getValue().currentPlaying;
DownloadFile file = mediaPlayerControllerLazy.getValue().getCurrentPlaying();
if (file != null)
{

View File

@ -6,8 +6,6 @@ import android.content.Intent;
import org.moire.ultrasonic.domain.MusicDirectory.Entry;
import org.moire.ultrasonic.service.MediaPlayerController;
import org.moire.ultrasonic.service.Downloader;
import org.moire.ultrasonic.service.LocalMediaPlayer;
import kotlin.Lazy;
@ -17,18 +15,16 @@ public class A2dpIntentReceiver extends BroadcastReceiver
{
private static final String PLAYSTATUS_RESPONSE = "com.android.music.playstatusresponse";
private Lazy<MediaPlayerController> mediaPlayerControllerLazy = inject(MediaPlayerController.class);
private Lazy<Downloader> downloader = inject(Downloader.class);
protected Lazy<LocalMediaPlayer> localMediaPlayer = inject(LocalMediaPlayer.class);
@Override
public void onReceive(Context context, Intent intent)
{
if (localMediaPlayer.getValue().currentPlaying == null)
if (mediaPlayerControllerLazy.getValue().getCurrentPlaying() == null)
{
return;
}
Entry song = localMediaPlayer.getValue().currentPlaying.getSong();
Entry song = mediaPlayerControllerLazy.getValue().getCurrentPlaying().getSong();
if (song == null)
{
@ -39,7 +35,7 @@ public class A2dpIntentReceiver extends BroadcastReceiver
Integer duration = song.getDuration();
int playerPosition = mediaPlayerControllerLazy.getValue().getPlayerPosition();
int listSize = downloader.getValue().getDownloads().size();
int listSize = mediaPlayerControllerLazy.getValue().getPlaylistSize();
if (duration != null)
{

View File

@ -1,5 +1,10 @@
package org.moire.ultrasonic.service;
/**
* Abstract class for consumers with two parameters
* @param <T> The type of the first object to consume
* @param <U> The type of the second object to consume
*/
public abstract class BiConsumer<T, U>
{
public abstract void accept(T t, U u);

View File

@ -1,5 +1,9 @@
package org.moire.ultrasonic.service;
/**
* Abstract class for consumers with one parameter
* @param <T> The type of the object to consume
*/
public abstract class Consumer<T>
{
public abstract void accept(T t);

View File

@ -24,6 +24,7 @@ import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;
import org.jetbrains.annotations.NotNull;
import org.moire.ultrasonic.domain.MusicDirectory;
import org.moire.ultrasonic.util.CacheCleaner;
import org.moire.ultrasonic.util.CancellableTask;
@ -51,7 +52,6 @@ import static org.koin.java.standalone.KoinJavaComponent.inject;
*/
public class DownloadFile
{
private static final String TAG = DownloadFile.class.getSimpleName();
private final Context context;
private final MusicDirectory.Entry song;
@ -70,7 +70,6 @@ public class DownloadFile
private Lazy<Downloader> downloader = inject(Downloader.class);
public DownloadFile(Context context, MusicDirectory.Entry song, boolean save)
{
super();
@ -287,6 +286,7 @@ public class DownloadFile
this.isPlaying = isPlaying;
}
@NotNull
@Override
public String toString()
{
@ -309,7 +309,7 @@ public class DownloadFile
{
PowerManager pm = (PowerManager) context.getSystemService(POWER_SERVICE);
wakeLock = pm.newWakeLock(SCREEN_DIM_WAKE_LOCK | ON_AFTER_RELEASE, toString());
wakeLock.acquire();
wakeLock.acquire(10*60*1000L /*10 minutes*/);
Log.i(TAG, String.format("Acquired wake lock %s", wakeLock));
}
@ -450,6 +450,7 @@ public class DownloadFile
}
}
@NotNull
@Override
public String toString()
{

View File

@ -11,6 +11,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* This class is responsible for the serialization / deserialization
* of the DownloadQueue (playlist) to the filesystem.
* It also serializes the player state e.g. current playing number and play position.
*/
public class DownloadQueueSerializer
{
private static final String TAG = DownloadQueueSerializer.class.getSimpleName();

View File

@ -22,6 +22,10 @@ import static org.koin.java.standalone.KoinJavaComponent.inject;
import static org.moire.ultrasonic.domain.PlayerState.DOWNLOADING;
import static org.moire.ultrasonic.domain.PlayerState.STARTED;
/**
* This class is responsible for maintaining the playlist and downloading
* its items from the network to the filesystem.
*/
public class Downloader
{
private static final String TAG = Downloader.class.getSimpleName();
@ -85,7 +89,7 @@ public class Downloader
Log.i(TAG, "Downloader destroyed");
}
protected synchronized void checkDownloads()
public synchronized void checkDownloads()
{
if (!Util.isExternalStoragePresent() || !externalStorageMonitor.isExternalStorageAvailable())
{

View File

@ -6,6 +6,9 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
/**
* Monitors the state of the mobile's external storage
*/
public class ExternalStorageMonitor
{
private static final String TAG = ExternalStorageMonitor.class.getSimpleName();

View File

@ -43,6 +43,9 @@ import static org.moire.ultrasonic.domain.PlayerState.PREPARED;
import static org.moire.ultrasonic.domain.PlayerState.PREPARING;
import static org.moire.ultrasonic.domain.PlayerState.STARTED;
/**
* Represents a Media Player which uses the mobile's resources for playback
*/
public class LocalMediaPlayer
{
private static final String TAG = LocalMediaPlayer.class.getSimpleName();
@ -59,6 +62,7 @@ public class LocalMediaPlayer
public PlayerState playerState = IDLE;
public DownloadFile currentPlaying;
public DownloadFile nextPlaying;
private PlayerState nextPlayerState = IDLE;
private boolean nextSetup;
private CancellableTask nextPlayingTask;

View File

@ -27,12 +27,14 @@ import org.moire.ultrasonic.domain.RepeatMode;
import java.util.List;
/**
* This interface contains all functions which are necessary for the Application UI
* to control the Media Player implementation.
*
* @author Sindre Mehus
* @version $Id$
*/
public interface MediaPlayerController
{
void download(List<Entry> songs, boolean save, boolean autoplay, boolean playNext, boolean shuffle, boolean newPlaylist);
void downloadBackground(List<Entry> songs, boolean save);
@ -114,4 +116,20 @@ public interface MediaPlayerController
void updateNotification();
void setSongRating(final int rating);
DownloadFile getCurrentPlaying();
int getPlaylistSize();
int getCurrentPlayingNumberOnPlaylist();
DownloadFile getCurrentDownloading();
List<DownloadFile> getPlayList();
long getPlayListUpdateRevision();
long getPlayListDuration();
DownloadFile getDownloadFileForSong(Entry song);
}

View File

@ -43,6 +43,10 @@ import kotlin.Lazy;
import static org.koin.java.standalone.KoinJavaComponent.inject;
/**
* The implementation of the Media Player Controller.
* This class contains everything that is necessary for the Application UI
* to control the Media Player implementation.
*
* @author Sindre Mehus, Joshua Bahnsen
* @version $Id$
*/
@ -58,21 +62,24 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
private Context context;
private Lazy<JukeboxMediaPlayer> jukeboxMediaPlayer = inject(JukeboxMediaPlayer.class);
private Lazy<DownloadQueueSerializer> downloadQueueSerializer = inject(DownloadQueueSerializer.class);
private Lazy<ExternalStorageMonitor> externalStorageMonitor = inject(ExternalStorageMonitor.class);
private final DownloadQueueSerializer downloadQueueSerializer;
private final ExternalStorageMonitor externalStorageMonitor;
private final Downloader downloader;
private final ShufflePlayBuffer shufflePlayBuffer;
private final LocalMediaPlayer localMediaPlayer;
public MediaPlayerControllerImpl(Context context, Downloader downloader, ShufflePlayBuffer shufflePlayBuffer,
LocalMediaPlayer localMediaPlayer)
public MediaPlayerControllerImpl(Context context, DownloadQueueSerializer downloadQueueSerializer,
ExternalStorageMonitor externalStorageMonitor, Downloader downloader,
ShufflePlayBuffer shufflePlayBuffer, LocalMediaPlayer localMediaPlayer)
{
this.context = context;
this.downloadQueueSerializer = downloadQueueSerializer;
this.externalStorageMonitor = externalStorageMonitor;
this.downloader = downloader;
this.shufflePlayBuffer = shufflePlayBuffer;
this.localMediaPlayer = localMediaPlayer;
externalStorageMonitor.getValue().onCreate(new Runnable() {
this.externalStorageMonitor.onCreate(new Runnable() {
@Override
public void run() {
reset();
@ -87,7 +94,7 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
public void onDestroy()
{
externalStorageMonitor.getValue().onDestroy();
externalStorageMonitor.onDestroy();
context.stopService(new Intent(context, MediaPlayerService.class));
Log.i(TAG, "MediaPlayerControllerImpl destroyed");
}
@ -235,14 +242,14 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
downloader.checkDownloads();
}
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
}
@Override
public synchronized void downloadBackground(List<MusicDirectory.Entry> songs, boolean save)
{
downloader.downloadBackground(songs, save);
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
}
public synchronized void setCurrentPlaying(DownloadFile currentPlaying)
@ -291,7 +298,7 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
{
downloader.shuffle();
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
jukeboxMediaPlayer.getValue().updatePlaylist();
MediaPlayerService mediaPlayerService = MediaPlayerService.getRunningInstance();
@ -365,7 +372,7 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
}
}
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
jukeboxMediaPlayer.getValue().updatePlaylist();
}
@ -380,7 +387,7 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
downloader.removeDownloadFile(downloadFile);
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
jukeboxMediaPlayer.getValue().updatePlaylist();
if (downloadFile == localMediaPlayer.nextPlaying)
@ -597,4 +604,44 @@ public class MediaPlayerControllerImpl implements MediaPlayerController
updateNotification();
}
@Override
public DownloadFile getCurrentPlaying() {
return localMediaPlayer.currentPlaying;
}
@Override
public int getPlaylistSize() {
return downloader.downloadList.size();
}
@Override
public int getCurrentPlayingNumberOnPlaylist() {
return downloader.getCurrentPlayingIndex();
}
@Override
public DownloadFile getCurrentDownloading() {
return downloader.currentDownloading;
}
@Override
public List<DownloadFile> getPlayList() {
return downloader.downloadList;
}
@Override
public long getPlayListUpdateRevision() {
return downloader.getDownloadListUpdateRevision();
}
@Override
public long getPlayListDuration() {
return downloader.getDownloadListDuration();
}
@Override
public DownloadFile getDownloadFileForSong(Entry song) {
return downloader.getDownloadFileForSong(song);
}
}

View File

@ -35,26 +35,26 @@ import org.moire.ultrasonic.util.CacheCleaner;
import org.moire.ultrasonic.util.Constants;
import org.moire.ultrasonic.util.Util;
import kotlin.Lazy;
import static org.koin.java.standalone.KoinJavaComponent.inject;
/**
* This class is responsible for handling received events for the Media Player implementation
*
* @author Sindre Mehus
*/
public class MediaPlayerLifecycleSupport
{
private static final String TAG = MediaPlayerLifecycleSupport.class.getSimpleName();
private Lazy<DownloadQueueSerializer> downloadQueueSerializer = inject(DownloadQueueSerializer.class);
private DownloadQueueSerializer downloadQueueSerializer; // From DI
private final MediaPlayerControllerImpl mediaPlayerController; // From DI
private final Downloader downloader; // From DI
private Context context;
private BroadcastReceiver headsetEventReceiver;
public MediaPlayerLifecycleSupport(Context context, final MediaPlayerControllerImpl mediaPlayerController, final Downloader downloader)
public MediaPlayerLifecycleSupport(Context context, DownloadQueueSerializer downloadQueueSerializer,
final MediaPlayerControllerImpl mediaPlayerController, final Downloader downloader)
{
this.downloadQueueSerializer = downloadQueueSerializer;
this.mediaPlayerController = mediaPlayerController;
this.context = context;
this.downloader = downloader;
@ -75,14 +75,14 @@ public class MediaPlayerLifecycleSupport
commandFilter.addAction(Constants.CMD_PROCESS_KEYCODE);
context.registerReceiver(intentReceiver, commandFilter);
downloadQueueSerializer.getValue().deserializeDownloadQueue(new Consumer<State>() {
this.downloadQueueSerializer.deserializeDownloadQueue(new Consumer<State>() {
@Override
public void accept(State state) {
// TODO: here the autoPlay = false creates problems when Ultrasonic is started by a Play MediaButton as the player won't start this way.
mediaPlayerController.restore(state.songs, state.currentPlayingIndex, state.currentPlayingPosition, false, false);
// Work-around: Serialize again, as the restore() method creates a serialization without current playing info.
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList,
MediaPlayerLifecycleSupport.this.downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList,
downloader.getCurrentPlayingIndex(), mediaPlayerController.getPlayerPosition());
}
});

View File

@ -47,6 +47,10 @@ import static org.moire.ultrasonic.domain.PlayerState.PREPARING;
import static org.moire.ultrasonic.domain.PlayerState.STARTED;
import static org.moire.ultrasonic.domain.PlayerState.STOPPED;
/**
* Android Foreground Service for playing music
* while the rest of the Ultrasonic App is in the background.
*/
public class MediaPlayerService extends Service
{
private static final String TAG = MediaPlayerService.class.getSimpleName();
@ -61,13 +65,14 @@ public class MediaPlayerService extends Service
private final Scrobbler scrobbler = new Scrobbler();
public Lazy<JukeboxMediaPlayer> jukeboxMediaPlayer = inject(JukeboxMediaPlayer.class);
private Lazy<DownloadQueueSerializer> downloadQueueSerializer = inject(DownloadQueueSerializer.class);
private Lazy<DownloadQueueSerializer> downloadQueueSerializerLazy = inject(DownloadQueueSerializer.class);
private Lazy<ShufflePlayBuffer> shufflePlayBufferLazy = inject(ShufflePlayBuffer.class);
private Lazy<Downloader> downloaderLazy = inject(Downloader.class);
private Lazy<LocalMediaPlayer> localMediaPlayerLazy = inject(LocalMediaPlayer.class);
private LocalMediaPlayer localMediaPlayer;
private Downloader downloader;
private ShufflePlayBuffer shufflePlayBuffer;
private DownloadQueueSerializer downloadQueueSerializer;
private boolean isInForeground = false;
private NotificationCompat.Builder notificationBuilder;
@ -129,6 +134,7 @@ public class MediaPlayerService extends Service
downloader = downloaderLazy.getValue();
localMediaPlayer = localMediaPlayerLazy.getValue();
shufflePlayBuffer = shufflePlayBufferLazy.getValue();
downloadQueueSerializer = downloadQueueSerializerLazy.getValue();
downloader.onCreate();
shufflePlayBuffer.onCreate();
@ -140,7 +146,7 @@ public class MediaPlayerService extends Service
localMediaPlayer.onPrepared = new Runnable() {
@Override
public void run() {
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList,
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList,
downloader.getCurrentPlayingIndex(), getPlayerPosition());
}
};
@ -401,7 +407,7 @@ public class MediaPlayerService extends Service
{
localMediaPlayer.reset();
localMediaPlayer.setCurrentPlaying(null);
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList,
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList,
downloader.getCurrentPlayingIndex(), getPlayerPosition());
}
@ -457,7 +463,7 @@ public class MediaPlayerService extends Service
public void accept(PlayerState playerState, DownloadFile currentPlaying) {
if (playerState == PAUSED)
{
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList, downloader.getCurrentPlayingIndex(), getPlayerPosition());
}
boolean showWhenPaused = (playerState != PlayerState.STOPPED && Util.isNotificationAlwaysEnabled(MediaPlayerService.this));
@ -579,7 +585,7 @@ public class MediaPlayerService extends Service
setNextPlaying();
if (serialize) {
downloadQueueSerializer.getValue().serializeDownloadQueue(downloader.downloadList,
downloadQueueSerializer.serializeDownloadQueue(downloader.downloadList,
downloader.getCurrentPlayingIndex(), getPlayerPosition());
}
}

View File

@ -6,6 +6,9 @@ import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* Represents the state of the Media Player implementation
*/
public class State implements Serializable
{
public static final long serialVersionUID = -6346438781062572270L;

View File

@ -1,5 +1,9 @@
package org.moire.ultrasonic.service;
/**
* Abstract class for supplying items to a consumer
* @param <T> The type of the item supplied
*/
public abstract class Supplier<T>
{
public abstract T get();

View File

@ -27,6 +27,10 @@ import static org.koin.java.standalone.KoinJavaComponent.inject;
* @author Sindre Mehus
* @version $Id$
*/
/**
* Responsible for cleaning up files from the offline download cache on the filesystem
*/
public class CacheCleaner
{

View File

@ -37,10 +37,9 @@ import org.moire.ultrasonic.domain.MusicDirectory.Entry;
import org.moire.ultrasonic.featureflags.Feature;
import org.moire.ultrasonic.featureflags.FeatureStorage;
import org.moire.ultrasonic.service.DownloadFile;
import org.moire.ultrasonic.service.Downloader;
import org.moire.ultrasonic.service.MediaPlayerController;
import org.moire.ultrasonic.service.MusicService;
import org.moire.ultrasonic.service.MusicServiceFactory;
import org.moire.ultrasonic.service.LocalMediaPlayer;
import org.moire.ultrasonic.util.Util;
import org.moire.ultrasonic.util.VideoPlayerType;
@ -82,8 +81,7 @@ public class SongView extends UpdateView implements Checkable
private boolean maximized = false;
private boolean useFiveStarRating;
private Lazy<Downloader> downloader = inject(Downloader.class);
protected Lazy<LocalMediaPlayer> localMediaPlayer = inject(LocalMediaPlayer.class);
private Lazy<MediaPlayerController> mediaPlayerControllerLazy = inject(MediaPlayerController.class);
public SongView(Context context)
{
@ -170,7 +168,7 @@ public class SongView extends UpdateView implements Checkable
this.song = song;
this.downloadFile = downloader.getValue().getDownloadFileForSong(song);
this.downloadFile = mediaPlayerControllerLazy.getValue().getDownloadFileForSong(song);
StringBuilder artist = new StringBuilder(60);
@ -321,7 +319,7 @@ public class SongView extends UpdateView implements Checkable
{
updateBackground();
downloadFile = downloader.getValue().getDownloadFileForSong(this.song);
downloadFile = mediaPlayerControllerLazy.getValue().getDownloadFileForSong(this.song);
File partialFile = downloadFile.getPartialFile();
if (downloadFile.isWorkDone())
@ -411,7 +409,7 @@ public class SongView extends UpdateView implements Checkable
viewHolder.fiveStar4.setImageDrawable(rating > 3 ? starDrawable : starHollowDrawable);
viewHolder.fiveStar5.setImageDrawable(rating > 4 ? starDrawable : starHollowDrawable);
boolean playing = localMediaPlayer.getValue().currentPlaying == downloadFile;
boolean playing = mediaPlayerControllerLazy.getValue().getCurrentPlaying() == downloadFile;
if (playing)
{

View File

@ -113,13 +113,15 @@ val musicServiceModule = module(MUSIC_SERVICE_CONTEXT) {
single { SubsonicImageLoader(getProperty(DiProperties.APP_CONTEXT), get()) }
single<MediaPlayerController> { MediaPlayerControllerImpl(androidContext(), get(), get(), get()) }
single { MediaPlayerControllerImpl(androidContext(), get(), get(), get()) }
single<MediaPlayerController> { MediaPlayerControllerImpl(androidContext(), get(), get(), get(), get(), get()) }
single { JukeboxMediaPlayer(androidContext(), get()) }
single { MediaPlayerLifecycleSupport(androidContext(), get(), get()) }
single { MediaPlayerLifecycleSupport(androidContext(), get(), get(), get()) }
single { DownloadQueueSerializer(androidContext()) }
single { ExternalStorageMonitor(androidContext()) }
single { ShufflePlayBuffer(androidContext()) }
single { Downloader(androidContext(), get(), get(), get()) }
single { LocalMediaPlayer(androidContext()) }
// TODO: Ideally this can be cleaned up when all circular references are removed.
single { MediaPlayerControllerImpl(androidContext(), get(), get(), get(), get(), get()) }
}