feat(android): pure idle-revert decision for UPnP output

This commit is contained in:
2026-06-06 17:27:52 -04:00
parent e185b36138
commit d7b011e52f
2 changed files with 76 additions and 0 deletions
@@ -0,0 +1,21 @@
package com.fabledsword.minstrel.player.output
/** Action the idle-revert collector should take on a player-state change. */
internal enum class IdleRevertAction { ARM, CANCEL, IGNORE }
/**
* Pure decision for the UPnP idle-revert timer. [armed] is whether the
* idle timer Job is currently running. We ARM only on the transition INTO
* "engaged + not playing" (so repeated paused emissions don't reset the
* countdown), CANCEL whenever playback resumes or UPnP disengages, and
* otherwise IGNORE.
*/
internal fun idleRevertAction(
upnpEngaged: Boolean,
isPlaying: Boolean,
armed: Boolean,
): IdleRevertAction = when {
upnpEngaged && !isPlaying -> if (armed) IdleRevertAction.IGNORE else IdleRevertAction.ARM
armed -> IdleRevertAction.CANCEL
else -> IdleRevertAction.IGNORE
}
@@ -0,0 +1,55 @@
package com.fabledsword.minstrel.player.output
import org.junit.jupiter.api.Test
import kotlin.test.assertEquals
class IdleRevertDecisionTest {
@Test
fun `engaged and paused and not armed arms the timer`() {
assertEquals(
IdleRevertAction.ARM,
idleRevertAction(upnpEngaged = true, isPlaying = false, armed = false),
)
}
@Test
fun `engaged and paused and already armed is ignored`() {
assertEquals(
IdleRevertAction.IGNORE,
idleRevertAction(upnpEngaged = true, isPlaying = false, armed = true),
)
}
@Test
fun `resuming playback cancels an armed timer`() {
assertEquals(
IdleRevertAction.CANCEL,
idleRevertAction(upnpEngaged = true, isPlaying = true, armed = true),
)
}
@Test
fun `playing with no timer armed is ignored`() {
assertEquals(
IdleRevertAction.IGNORE,
idleRevertAction(upnpEngaged = true, isPlaying = true, armed = false),
)
}
@Test
fun `disengaging UPnP cancels an armed timer`() {
assertEquals(
IdleRevertAction.CANCEL,
idleRevertAction(upnpEngaged = false, isPlaying = false, armed = true),
)
}
@Test
fun `disengaged with no timer armed is ignored`() {
assertEquals(
IdleRevertAction.IGNORE,
idleRevertAction(upnpEngaged = false, isPlaying = true, armed = false),
)
}
}