playback: apply the item's gain in one tested step

Review follow-ups.

- `ReplayGainController.applyItem` owns reading the gain off a
  `MediaItem`, so the transition, the controller and the extras read are
  exercised together rather than only in isolation.
- drop the leftover `setTrack(null)` on a missing active source: now that
  the transition sets the gain from the item, that line only raced it and
  could reset a playing item to unity.
- tests for a zero gain surviving the extras round trip (zero is a real
  gain, not an absent one), for the latest item's gain being the one left
  applied, and for a missing item applying unity.
This commit is contained in:
austinried
2026-10-16 13:07:07 +00:00
parent 5f5ad85dff
commit 7ce754f95a
4 changed files with 68 additions and 6 deletions
@@ -266,6 +266,10 @@ private fun Bundle.putGain(
private fun Bundle.gain(key: String): Float? = if (containsKey(key)) getFloat(key) else null
internal fun ReplayGainController.applyItem(mediaItem: MediaItem?) {
setTrack(mediaItem.replayGain())
}
internal fun queueMediaItem(
item: QueueItem,
local: String?,
@@ -140,7 +140,7 @@ class PlaybackService : MediaSessionService() {
reason: Int,
) {
observeCurrentSong(mediaItem?.mediaId)
replayGain.setTrack(mediaItem?.replayGain())
replayGain.applyItem(mediaItem)
}
},
)
@@ -187,11 +187,7 @@ class PlaybackService : MediaSessionService() {
session?.setMediaButtonPreferences(listOf(starButton(false)))
songJob =
scope.launch {
val sourceId = sourceRepository?.activeSourceIdOnce()
if (sourceId == null) {
replayGain.setTrack(null)
return@launch
}
val sourceId = sourceRepository?.activeSourceIdOnce() ?: return@launch
library.song(sourceId, songId).collect { song ->
if (currentSongId != songId) return@collect
starred = song?.starred != null