playback: introduce foreground-safe restores

- Allow DeferredPlayback.RestoreState to force-start playback
- Allow DeferredPlayback.RestoreState to specify a fallback action
guaranteed to succeed
This commit is contained in:
Alexander Capehart 2024-08-17 18:10:55 -06:00
parent aa140bebaa
commit 3fa5628a1e
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
2 changed files with 11 additions and 3 deletions

View file

@ -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)
}
}
}

View file

@ -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.