From 29cc680c34a60d6fc1dde18524d5803462d1ac77 Mon Sep 17 00:00:00 2001 From: OxygenCobalt Date: Thu, 7 Jul 2022 16:14:47 -0600 Subject: [PATCH] revert playback: save state when sanitizing Edge case I thought existed did not. PlaybackService must have saved before dying, and thus if it did not foreground after a sanitization, the saved state would still sanitize in a similar manner. --- .../org/oxycblt/auxio/music/IndexerService.kt | 4 +- .../playback/state/PlaybackStateManager.kt | 90 ++++++++----------- .../playback/system/MediaSessionComponent.kt | 4 + .../auxio/playback/system/PlaybackService.kt | 2 - 4 files changed, 42 insertions(+), 58 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt b/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt index 0791755c6..d461e0431 100644 --- a/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt +++ b/app/src/main/java/org/oxycblt/auxio/music/IndexerService.kt @@ -28,7 +28,6 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import org.oxycblt.auxio.IntegerTable import org.oxycblt.auxio.R -import org.oxycblt.auxio.playback.state.PlaybackStateDatabase import org.oxycblt.auxio.playback.state.PlaybackStateManager import org.oxycblt.auxio.settings.Settings import org.oxycblt.auxio.util.logD @@ -119,8 +118,7 @@ class IndexerService : Service(), Indexer.Controller, Settings.Callback { imageLoader.memoryCache?.clear() // Clear invalid models from PlaybackStateManager. - playbackManager.sanitize( - PlaybackStateDatabase.getInstance(this@IndexerService), newLibrary) + playbackManager.sanitize(newLibrary) } musicStore.updateLibrary(newLibrary) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt index bbb7dec33..7cdb1420e 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateManager.kt @@ -70,7 +70,7 @@ class PlaybackStateManager private constructor() { notifyPlayingChanged() } /** The current playback progress */ - private var positionMs = 0L + var positionMs = 0L /** The current [RepeatMode] */ var repeatMode = RepeatMode.NONE set(value) { @@ -81,7 +81,7 @@ class PlaybackStateManager private constructor() { var isShuffled = false private set - /** Whether this instance has been initialized */ + /** Whether this instance has played something or restored a state. */ var isInitialized = false private set @@ -141,10 +141,7 @@ class PlaybackStateManager private constructor() { // --- PLAYING FUNCTIONS --- - /** - * Play a [song]. - * @param playbackMode The [PlaybackMode] to construct the queue off of. - */ + /** Play a [song]. */ @Synchronized fun play(song: Song, playbackMode: PlaybackMode, settings: Settings) { val library = musicStore.library ?: return @@ -165,10 +162,7 @@ class PlaybackStateManager private constructor() { isInitialized = true } - /** - * Play a [parent], such as an artist or album. - * @param shuffled Whether the queue is shuffled or not - */ + /** Play a [parent], such as an artist or album. */ @Synchronized fun play(parent: MusicParent, shuffled: Boolean, settings: Settings) { val library = musicStore.library ?: return @@ -321,11 +315,7 @@ class PlaybackStateManager private constructor() { // --- STATE FUNCTIONS --- - /** - * Update the current [positionMs]. Will not notify listeners of a seek event. - * @param positionMs The new position in millis. - * @see seekTo - */ + /** Update the current [positionMs]. Only meant for use by [Controller] */ @Synchronized fun synchronizePosition(controller: Controller, positionMs: Long) { if (BuildConfig.DEBUG && this.controller !== controller) { @@ -400,47 +390,41 @@ class PlaybackStateManager private constructor() { withContext(Dispatchers.IO) { database.write(state) } } - /** Sanitize the state with [newLibrary]. Writes the state to [database] */ - suspend fun sanitize(database: PlaybackStateDatabase, newLibrary: MusicStore.Library) { - val state = - synchronized(this) { - if (!isInitialized) { - logD("Not initialized, no need to sanitize") - return + /** Sanitize the state with [newLibrary]. */ + @Synchronized + fun sanitize(newLibrary: MusicStore.Library) { + if (!isInitialized) { + logD("Not initialized, no need to sanitize") + return + } + + logD("Sanitizing state") + + val oldSongId = song?.id + val oldPosition = positionMs + + parent = + parent?.let { + when (it) { + is Album -> newLibrary.sanitize(it) + is Artist -> newLibrary.sanitize(it) + is Genre -> newLibrary.sanitize(it) } - - logD("Sanitizing state") - - val oldSongId = song?.id - val oldPosition = positionMs - - parent = - parent?.let { - when (it) { - is Album -> newLibrary.sanitize(it) - is Artist -> newLibrary.sanitize(it) - is Genre -> newLibrary.sanitize(it) - } - } - - _queue = newLibrary.sanitize(_queue).toMutableList() - - while (song?.id != oldSongId && index > -1) { - index-- - } - - // Continuing playback while also possibly doing drastic state updates is - // a bad idea, so pause. - isPlaying = false - notifyNewPlayback() - - // Controller may have reloaded the media item, re-seek to the previous position - seekTo(oldPosition) - - makeStateImpl() } - withContext(Dispatchers.IO) { database.write(state) } + _queue = newLibrary.sanitize(_queue).toMutableList() + + while (song?.id != oldSongId && index > -1) { + index-- + } + + // Continuing playback while also possibly doing drastic state updates is + // a bad idea, so pause. + isPlaying = false + notifyNewPlayback() + + // Controller may have reloaded the media item, re-seek to the previous position + seekTo(oldPosition) } private fun makeStateImpl() = diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt index b311504c6..264fc32de 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/MediaSessionComponent.kt @@ -221,6 +221,10 @@ class MediaSessionComponent( playbackManager.seekTo(position) } + override fun onFastForward() { + playbackManager.next() + } + override fun onRewind() { playbackManager.rewind() playbackManager.isPlaying = true diff --git a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt index c35067152..66c03a1ff 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/system/PlaybackService.kt @@ -69,8 +69,6 @@ import org.oxycblt.auxio.widgets.WidgetProvider * * TODO: Android Auto * - * TODO: Attempt to re-unify delayed actions again - * * @author OxygenCobalt */ class PlaybackService :