feat(android): track UPnP play-intent surviving SOAP errors
This commit is contained in:
@@ -27,6 +27,13 @@ class RemotePlayerState @Inject constructor() {
|
||||
@Volatile var lastError: Throwable? = null; private set
|
||||
@Volatile var trackNumber: Int = 0; private set
|
||||
|
||||
// The operator's last explicit transport intent (play=true, pause=false),
|
||||
// distinct from the observed remote isPlaying. handleRemoteDrop resumes
|
||||
// local playback based on THIS, not isPlaying -- so a play() that fails
|
||||
// its SOAP (stale/dead renderer) still resumes on the phone instead of
|
||||
// swallowing the tap. Deliberately NOT cleared by applyError.
|
||||
@Volatile var lastPlayIntent: Boolean = false; private set
|
||||
|
||||
// Pending-transport deadline (SystemClock.elapsedRealtime() at which we
|
||||
// give up waiting). When > 0, a user transport action (next/prev/seekTo
|
||||
// idx) is in flight: ForwardingPlayer has already moved the wrapped
|
||||
@@ -63,6 +70,8 @@ class RemotePlayerState @Inject constructor() {
|
||||
positionMs = 0L
|
||||
}
|
||||
|
||||
fun setPlayIntent(intended: Boolean) { lastPlayIntent = intended }
|
||||
|
||||
fun applyError(t: Throwable) {
|
||||
isPlaying = false
|
||||
lastError = t
|
||||
@@ -80,6 +89,7 @@ class RemotePlayerState @Inject constructor() {
|
||||
positionMs = 0L
|
||||
durationMs = 0L
|
||||
isPlaying = false
|
||||
lastPlayIntent = false
|
||||
currentTrackUri = ""
|
||||
lastError = null
|
||||
consecutivePollFailures = 0
|
||||
|
||||
@@ -69,6 +69,32 @@ class RemotePlayerStateTest {
|
||||
assertFalse(state.recordPollFailure())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `play intent survives a SOAP error so a failed play can resume locally`() {
|
||||
val state = RemotePlayerState()
|
||||
state.setPlayIntent(true)
|
||||
state.applyError(RuntimeException("connect timeout"))
|
||||
// isPlaying is cleared by the error, but the operator's intent persists.
|
||||
assertFalse(state.isPlaying)
|
||||
assertTrue(state.lastPlayIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `pausing clears play intent`() {
|
||||
val state = RemotePlayerState()
|
||||
state.setPlayIntent(true)
|
||||
state.setPlayIntent(false)
|
||||
assertFalse(state.lastPlayIntent)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `reset clears play intent`() {
|
||||
val state = RemotePlayerState()
|
||||
state.setPlayIntent(true)
|
||||
state.reset()
|
||||
assertFalse(state.lastPlayIntent)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val DROP_THRESHOLD = 30
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user