From 4021938046e7b7992a198d3e5a4f4544b67757f5 Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 4 Jun 2026 07:06:07 -0400 Subject: [PATCH] fix(android): polling tick no longer force-syncs controller -- avoids Sonos seek-to-0 --- .../minstrel/player/PlayerController.kt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/android/app/src/main/java/com/fabledsword/minstrel/player/PlayerController.kt b/android/app/src/main/java/com/fabledsword/minstrel/player/PlayerController.kt index fbb993de..df1cae82 100644 --- a/android/app/src/main/java/com/fabledsword/minstrel/player/PlayerController.kt +++ b/android/app/src/main/java/com/fabledsword/minstrel/player/PlayerController.kt @@ -534,7 +534,7 @@ class PlayerController @Inject constructor( desiredIdx > current.queueIndex && desiredIdx in queueRefs.indices publishTickIfChanged( - controller, current, trackChanged, desiredIdx, + current, trackChanged, desiredIdx, effectiveIsPlaying, newPos, newDur, newBuf, ) } @@ -555,7 +555,6 @@ class PlayerController @Inject constructor( @Suppress("LongParameterList") // assembled at one tick call site; refactor would cost clarity private fun publishTickIfChanged( - controller: MediaController, current: PlayerUiState, trackChanged: Boolean, desiredIdx: Int, @@ -579,11 +578,14 @@ class PlayerController @Inject constructor( durationMs = newDur, bufferedPositionMs = newBuf, ) - if (trackChanged && controller.currentMediaItemIndex != desiredIdx) { - // Defense in depth: keep wrapped player aligned even when - // maybeSyncLocalCursor's seekTo didn't fire a transition event. - controller.seekTo(desiredIdx, 0L) - } + // Intentionally do NOT call controller.seekTo here. That would route + // through MinstrelForwardingPlayer's seekTo override and re-issue + // AVTransport.SeekToTrack to Sonos -- which seeks Sonos back to the + // start of the same track it's already playing, restarting the song. + // The wrapped player's index is kept in sync by maybeSyncLocalCursor's + // delegate.seekTo (which bypasses the override). If it lags briefly, + // the next pollOnce catches up; the uiState above already reflects + // Sonos's truth for the user. } private fun desiredQueueIndex(controller: MediaController, upnpActive: Boolean): Int =