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.
This commit is contained in:
austinried
2026-11-05 13:13:22 +00:00
parent eb55858cc4
commit 11276c2e1f
2 changed files with 4 additions and 62 deletions
@@ -1070,7 +1070,6 @@ class PlaybackController(
} }
lastSavedPositionMs = savedPositionMs lastSavedPositionMs = savedPositionMs
loadWindow(anchor.position, autoplay = false, startPositionMs = savedPositionMs) loadWindow(anchor.position, autoplay = false, startPositionMs = savedPositionMs)
player?.takeIf { it.itemCount > 0 }?.ensurePrepared()
} }
private suspend fun stop() = startLock.withLock { stopLocked() } private suspend fun stop() = startLock.withLock { stopLocked() }
@@ -1452,7 +1451,7 @@ class PlaybackController(
} }
override fun onError(message: UiMessage) { override fun onError(message: UiMessage) {
if (player?.playWhenReady == true) showMessage(message) showMessage(message)
refresh() refresh()
} }
} }
@@ -343,75 +343,18 @@ class PlaybackControllerTest {
} }
@Test @Test
fun restoringAPreviousQueuePreparesTheSessionWithoutPlaying() { fun togglingPlayOnARestoredQueuePreparesBeforePlaying() {
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() {
seedAlbum(5, sourceId = 1) seedAlbum(5, sourceId = 1)
runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) } runBlocking { queues.replace(listOf(queues.albumEntry(1, "al1"))) }
controller.connect() controller.connect()
await { handle.operations.contains("prepare") } await { handle.items.isNotEmpty() }
handle.operations.clear() handle.operations.clear()
controller.togglePlayPause() controller.togglePlayPause()
await { handle.operations.contains("play") } await { handle.operations.contains("play") }
assertEquals(listOf("play"), handle.operations) assertEquals(listOf("prepare", "play"), handle.operations)
} }
@Test @Test