1 Commits
Author SHA1 Message Date
austinried 11276c2e1f playback: revert the restored session prepare
Preparing the restored window on launch was meant to make the paused
session reachable from Bluetooth and Automate. The follow-up on the issue
shows the notification appears, but the car's play command still does not
reach the app until the phone is unlocked, and the speculative prepare
buffered up to 50 seconds of the restored track on every launch while
claiming the media controls whenever the app opened.

Removing the prepare also removes the error gate it needed, which could
hide genuine playback errors while paused.

Reverts #230.
2026-11-05 13:13:22 +00:00
2 changed files with 4 additions and 62 deletions
@@ -1070,7 +1070,6 @@ class PlaybackController(
}
lastSavedPositionMs = savedPositionMs
loadWindow(anchor.position, autoplay = false, startPositionMs = savedPositionMs)
player?.takeIf { it.itemCount > 0 }?.ensurePrepared()
}
private suspend fun stop() = startLock.withLock { stopLocked() }
@@ -1452,7 +1451,7 @@ class PlaybackController(
}
override fun onError(message: UiMessage) {
if (player?.playWhenReady == true) showMessage(message)
showMessage(message)
refresh()
}
}
@@ -343,75 +343,18 @@ class PlaybackControllerTest {
}
@Test
fun restoringAPreviousQueuePreparesTheSessionWithoutPlaying() {
seedAlbum(3, sourceId = 1)
runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) }
controller.connect()
await { handle.operations.contains("prepare") }
assertFalse(handle.operations.contains("play"))
assertFalse(handle.isIdle)
assertFalse(handle.playWhenReady)
assertFalse(controller.state.value.isPlaying)
}
@Test
fun aPrepareFailureBeforePlaybackIsNotReported() {
seedAlbum(3, sourceId = 1)
runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) }
controller.connect()
await { handle.operations.contains("prepare") }
handle.fail(UiMessage(R.string.playback_error_network))
assertTrue(messages.isEmpty())
controller.togglePlayPause()
await { handle.operations.contains("play") }
handle.fail(UiMessage(R.string.playback_error_network))
await { messages.isNotEmpty() }
assertEquals(1, messages.size)
}
@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() {
fun togglingPlayOnARestoredQueuePreparesBeforePlaying() {
seedAlbum(5, sourceId = 1)
runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) }
controller.connect()
await { handle.operations.contains("prepare") }
await { handle.items.isNotEmpty() }
handle.operations.clear()
controller.togglePlayPause()
await { handle.operations.contains("play") }
assertEquals(listOf("play"), handle.operations)
assertEquals(listOf("prepare", "play"), handle.operations)
}
@Test