fix(android): remove pollLoop cursor sync -- races with queue load and SOAP
android / Build + lint + test (push) Has been cancelled

This commit is contained in:
2026-06-03 22:24:34 -04:00
parent e2866795ef
commit e011b04e04
@@ -216,13 +216,15 @@ class MinstrelForwardingPlayer(
/**
* One poll tick: read position + transport state from Sonos and apply to
* [remoteState]. Cursor sync: Sonos's 1-based Track index is the truth —
* if it disagrees with the local cursor, post an advance on the player
* thread so they converge. This handles Sonos hardware-button advances
* and natural auto-advance without GENA eventing.
*
* Extracted from [pollLoop] to keep that method within detekt's
* LongMethod=60 limit.
* [remoteState]. The local cursor is NOT synced to Sonos's Track index --
* during the 17-second queue load Sonos reports Track=1 (the first added
* track) which would silently walk the local cursor to 0, then SetAV+Seek
* lands and Sonos jumps to the user's actual track, racing with the
* sync. Local + Sonos cursors stay in sync because every override
* (seekToNext/Prev/seekTo) advances both sides by the same delta.
* Hardware-button or Sonos-app driven advances ARE missed until the
* user takes a transport action -- accepted tradeoff pending GENA
* event subscriptions.
*/
private suspend fun pollOnce(active: ActiveUpnp) {
val info = active.avTransport.getPositionInfo()
@@ -239,18 +241,6 @@ class MinstrelForwardingPlayer(
TransportState.STOPPED -> remoteState.applyTransportStopped()
TransportState.TRANSITIONING, TransportState.UNKNOWN -> Unit
}
// Cursor sync: post a check to the player thread. Track is 1-based;
// sonosIndex is 0-based. If Sonos advanced (hardware button, natural
// end-of-track) and our local cursor is behind, walk it forward.
val sonosIndex = info.track - 1
if (sonosIndex >= 0) {
handler.post {
val localIndex = delegate.currentMediaItemIndex
if (sonosIndex != localIndex && sonosIndex < delegate.mediaItemCount) {
delegate.seekTo(sonosIndex, 0L)
}
}
}
}
private companion object {