playback: prepare the restored queue so the session starts on launch

Restoring the saved queue left the player idle, so the media session had no
notification and Bluetooth or Automate saw no active player until playback
began. Prepare the restored window without autoplaying, which surfaces the
paused session when the app opens. A queue from another source stays stopped,
and an offline queue without downloads has no window to prepare.

Closes austinried/subtracks#202
This commit is contained in:
austinried
2026-11-04 11:12:07 +00:00
parent 599924bdd0
commit 484cc55385
2 changed files with 43 additions and 2 deletions
@@ -1070,6 +1070,7 @@ class PlaybackController(
}
lastSavedPositionMs = savedPositionMs
loadWindow(anchor.position, autoplay = false, startPositionMs = savedPositionMs)
if ((player?.itemCount ?: 0) > 0) player?.ensurePrepared()
}
private suspend fun stop() = startLock.withLock { stopLocked() }
@@ -343,7 +343,46 @@ class PlaybackControllerTest {
}
@Test
fun togglingPlayOnARestoredQueuePreparesBeforePlaying() {
fun restoringAPreviousQueuePreparesTheSessionWithoutPlaying() {
seedAlbum(3, sourceId = 1)
runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) }
controller.connect()
await { handle.items.isNotEmpty() }
assertTrue(handle.operations.contains("prepare"))
assertFalse(handle.operations.contains("play"))
assertFalse(handle.isIdle)
assertFalse(handle.playWhenReady)
assertFalse(controller.state.value.isPlaying)
}
@Test
fun restoringAnEmptyQueueDoesNotPrepare() {
seedAlbum(3, sourceId = 1)
controller.connect()
await { controller.ready.value }
assertTrue(handle.items.isEmpty())
assertFalse(handle.operations.contains("prepare"))
}
@Test
fun restoringAnOfflineQueueWithoutDownloadsDoesNotPrepare() {
seedAlbum(3, sourceId = 1)
runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) }
setOffline()
controller.connect()
await { controller.ready.value }
assertTrue(handle.items.isEmpty())
assertFalse(handle.operations.contains("prepare"))
}
@Test
fun togglingPlayOnARestoredQueuePlaysThePreparedWindow() {
seedAlbum(5, sourceId = 1)
runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) }
@@ -354,7 +393,8 @@ class PlaybackControllerTest {
controller.togglePlayPause()
await { handle.operations.contains("play") }
assertEquals(listOf("prepare", "play"), handle.operations)
assertEquals(listOf("play"), handle.operations)
assertTrue(handle.playWhenReady)
}
@Test