From 3fa5628a1efb5443afc37c8a46b79babaf25ee37 Mon Sep 17 00:00:00 2001 From: Alexander Capehart Date: Sat, 17 Aug 2024 18:10:55 -0600 Subject: [PATCH] playback: introduce foreground-safe restores - Allow DeferredPlayback.RestoreState to force-start playback - Allow DeferredPlayback.RestoreState to specify a fallback action guaranteed to succeed --- .../auxio/playback/service/ExoPlaybackStateHolder.kt | 12 ++++++++++-- .../auxio/playback/state/PlaybackStateHolder.kt | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/org/oxycblt/auxio/playback/service/ExoPlaybackStateHolder.kt b/app/src/main/java/org/oxycblt/auxio/playback/service/ExoPlaybackStateHolder.kt index 058b33403..804470a35 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/service/ExoPlaybackStateHolder.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/service/ExoPlaybackStateHolder.kt @@ -163,10 +163,18 @@ class ExoPlaybackStateHolder( is DeferredPlayback.RestoreState -> { logD("Restoring playback state") restoreScope.launch { - persistenceRepository.readState()?.let { + val state = persistenceRepository.readState() + if (state != null) { // Apply the saved state on the main thread to prevent code expecting // state updates on the main thread from crashing. - withContext(Dispatchers.Main) { playbackManager.applySavedState(it, false) } + withContext(Dispatchers.Main) { + playbackManager.applySavedState(state, false) + if (action.play) { + playbackManager.playing(true) + } + } + } else if (action.fallback != null) { + playbackManager.playDeferred(action.fallback) } } } diff --git a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateHolder.kt b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateHolder.kt index 857ac6898..471a6498c 100644 --- a/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateHolder.kt +++ b/app/src/main/java/org/oxycblt/auxio/playback/state/PlaybackStateHolder.kt @@ -276,7 +276,7 @@ data class QueueChange(val type: Type, val instructions: UpdateInstructions) { /** Possible long-running background tasks handled by the background playback task. */ sealed interface DeferredPlayback { /** Restore the previously saved playback state. */ - data object RestoreState : DeferredPlayback + data class RestoreState(val play: Boolean, val fallback: DeferredPlayback? = null) : DeferredPlayback /** * Start shuffled playback of the entire music library. Analogous to the "Shuffle All" shortcut.