playback: fix broken state restore

That didn't properly handle when the index was invalid and kept stale
song entries.

Resolves #723.
This commit is contained in:
Alexander Capehart 2024-02-26 16:41:31 -07:00
parent b6f89de88d
commit dbfe9927bf
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
3 changed files with 23 additions and 11 deletions

View file

@ -470,6 +470,10 @@ constructor(
ack?.let { playbackManager.ack(this, it) }
}
override fun reset() {
player.setMediaItems(emptyList())
}
// --- PLAYER OVERRIDES ---
override fun onPlayWhenReadyChanged(playWhenReady: Boolean, reason: Int) {

View file

@ -153,6 +153,9 @@ interface PlaybackStateHolder {
* ack.
*/
fun applySavedState(parent: MusicParent?, rawQueue: RawQueue, ack: StateAck.NewPlayback?)
/** Reset this instance to an empty state. */
fun reset()
}
/**

View file

@ -717,6 +717,8 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
return
}
val stateHolder = stateHolder ?: return
// The heap may not be the same if the song composition changed between state saves/reloads.
// This also means that we must modify the shuffled mapping as well, in what it points to
// and it's general composition.
@ -763,27 +765,30 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
"Queue inconsistency detected: Shuffled mapping indices out of heap bounds"
}
if (index < 0) {
stateHolder.reset()
return
}
val rawQueue =
RawQueue(
heap = heap,
shuffledMapping = shuffledMapping,
heapIndex =
if (shuffledMapping.isNotEmpty()) {
shuffledMapping[savedState.index]
shuffledMapping[index]
} else {
index
})
if (index > -1) {
// Valid state where something needs to be played, direct the stateholder to apply
// this new state.
val oldStateMirror = stateMirror
if (oldStateMirror.rawQueue != rawQueue) {
logD("Queue changed, must reload player")
stateHolder?.playing(false)
stateHolder?.applySavedState(parent, rawQueue, StateAck.NewPlayback)
stateHolder?.seekTo(savedState.positionMs)
}
// Valid state where something needs to be played, direct the stateholder to apply
// this new state.
val oldStateMirror = stateMirror
if (oldStateMirror.rawQueue != rawQueue) {
logD("Queue changed, must reload player")
stateHolder.playing(false)
stateHolder.applySavedState(parent, rawQueue, StateAck.NewPlayback)
stateHolder.seekTo(savedState.positionMs)
}
isInitialized = true