fix(android): instant cold-start resume + play button icon flicker

WebBridge: skip setMediaItems/prepare when the track is already buffered
from the cold-start pre-warm, so resuming the last song is instant (~0s)
instead of re-buffering from scratch (~10s).

Player: show pause icon during buffering (isPlaying=false, isBuffering=true)
so the button doesn't flash back to "play" between tracks. Also optimistically
set _nativePlaying=true and call setPlayIcon immediately on playCurrent so the
icon updates before the native callback round-trip.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
HoneyandClaude Sonnet 4.6 committed 2026-06-08 20:08:56 +02:00
1 parent 76efa393ea
commit 60e89fe3b6
2 files changed
+21 -7

No files matched your search

@@ -28,11 +28,20 @@ class WebBridge(private val controllerProvider: () -> MediaController?) {
runOnMain {
val ctrl = controllerProvider() ?: return@runOnMain
val idx = startIndex.coerceAtLeast(0)
ctrl.setMediaItems(items, idx, 0L)
// Pre-warm artwork before prepare()/play() so the notification bitmap
// cache is populated before Media3 renders the first notification.
MusicService.instance?.publicWarmArtwork(idx)
ctrl.prepare()
// If ExoPlayer already has this exact single track buffered from the cold-start
// pre-warm, skip setMediaItems+prepare so we don't throw away the buffered data.
// Just call play() — this makes the "resume last track" instant instead of ~10s.
val alreadyReady = items.size == 1 &&
ctrl.mediaItemCount == 1 &&
ctrl.currentMediaItem?.mediaId == items[0].mediaId &&
ctrl.playbackState != Player.STATE_IDLE
if (!alreadyReady) {
ctrl.setMediaItems(items, idx, 0L)
// Pre-warm artwork before prepare()/play() so the notification bitmap
// cache is populated before Media3 renders the first notification.
MusicService.instance?.publicWarmArtwork(idx)
ctrl.prepare()
}
if (autoPlay) ctrl.play()
}
}