bvandeusen
4021938046
fix(android): polling tick no longer force-syncs controller -- avoids Sonos seek-to-0
android / Build + lint + test (push) Successful in 3m26s
2026-06-04 07:06:07 -04:00
bvandeusen
7486bc2444
fix(android): split tickPositionPoll into helpers for detekt complexity
android / Build + lint + test (push) Has been cancelled
2026-06-04 07:04:01 -04:00
bvandeusen
ee8a1fdc93
fix(android): event-driven pending-transport clear (Sonos ack OR 5s safety)
android / Build + lint + test (push) Failing after 1m12s
2026-06-04 07:00:22 -04:00
bvandeusen
8e578d2068
fix(android): 2s transport-ack lockout so Prev/Next isn't undone by stale poll
android / Build + lint + test (push) Successful in 3m25s
2026-06-04 06:55:39 -04:00
bvandeusen
cacb280832
fix(android): polling tick track update is forward-only so user Next isn't undone
android / Build + lint + test (push) Successful in 3m27s
2026-06-04 06:50:35 -04:00
bvandeusen
36054506c2
fix(android): polling tick owns track-change updates when delegate.seekTo silent
android / Build + lint + test (push) Successful in 3m26s
2026-06-04 06:46:38 -04:00
bvandeusen
5db90844cb
fix(android): DIDL-Lite includes Rincon namespace + cdudn desc for Sonos
android / Build + lint + test (push) Successful in 3m39s
2026-06-04 06:34:00 -04:00
bvandeusen
d5437d517e
fix(android): single break in extend loop for detekt LoopWithTooManyJumpStatements
android / Build + lint + test (push) Successful in 3m52s
2026-06-04 01:07:57 -04:00
bvandeusen
3085d6f409
fix(android): DIDL-Lite restricted=true / id=-1 so Sonos accepts metadata
android / Build + lint + test (push) Failing after 1m33s
2026-06-04 00:59:31 -04:00
bvandeusen
c5b326c620
fix(android): UPnP extend captures SOAP fault, aborts after 3 failures
android / Build + lint + test (push) Has been cancelled
2026-06-04 00:56:48 -04:00
bvandeusen
389c896d65
fix(android): force poll on ON_RESUME + cap interpolation drift at 5s
android / Build + lint + test (push) Has been cancelled
2026-06-04 00:55:10 -04:00
bvandeusen
41230b5afb
fix(android): single jump per polling loop for detekt LoopWithTooManyJumpStatements
android / Build + lint + test (push) Successful in 4m0s
2026-06-04 00:42:35 -04:00
bvandeusen
c245b1ef0b
fix(android): hold UI patch until cursor sync lands; reanchor on track flip
android / Build + lint + test (push) Failing after 1m21s
2026-06-04 00:37:34 -04:00
bvandeusen
2425a305eb
fix(android): interpolate UPnP position between polls + suppress post-seek race
android / Build + lint + test (push) Successful in 4m5s
2026-06-04 00:16:57 -04:00
bvandeusen
88b161193d
fix(android): TrackRef.durationSec is final fallback so duration is never 0
android / Build + lint + test (push) Successful in 5m54s
2026-06-04 00:03:48 -04:00
bvandeusen
9628ed1749
fix(android): duration falls back to local while Sonos hasn't reported one
android / Build + lint + test (push) Has been cancelled
2026-06-04 00:00:45 -04:00
bvandeusen
85926f4ec0
fix(android): keep service alive when UPnP is playing -- override playWhenReady
android / Build + lint + test (push) Successful in 3m53s
2026-06-03 23:51:54 -04:00
bvandeusen
47b0894ad6
test(android): update RemotePlayerState threshold expectation to 30
android / Build + lint + test (push) Has been cancelled
2026-06-03 23:50:37 -04:00
bvandeusen
e62fac3a0e
fix(android): onEvents reads UPnP state so resume keeps duration
android / Build + lint + test (push) Has been cancelled
2026-06-03 23:48:52 -04:00
bvandeusen
eae5dcad23
fix(android): correct ErrorCopy import path in PlaylistPlayback
android / Build + lint + test (push) Failing after 6m2s
2026-06-03 23:42:18 -04:00
bvandeusen
3576e241c0
fix(android): split playPlaylistShuffled to satisfy detekt ReturnCount
android / Build + lint + test (push) Failing after 3m42s
2026-06-03 23:37:30 -04:00
bvandeusen
8f89279fa4
fix(android): UPnP survives screen-off + cursor catches up to Sonos
android / Build + lint + test (push) Has been cancelled
2026-06-03 23:36:43 -04:00
bvandeusen
b1a66f18bd
feat(android): shuffle on system playlist tile play -- Home + Playlists list
android / Build + lint + test (push) Failing after 1m30s
2026-06-03 23:29:42 -04:00
bvandeusen
6a7958c921
fix(android): debounce non-PLAYING poll to suppress UPnP track-change flicker
android / Build + lint + test (push) Successful in 4m13s
2026-06-03 23:19:29 -04:00
bvandeusen
33285b53c6
fix(android): refresh uiState.isPlaying from remoteState during UPnP
android / Build + lint + test (push) Successful in 4m1s
2026-06-03 23:08:32 -04:00
bvandeusen and Claude Sonnet 4.6
87ad7f4dc2
feat(android): lazy queue activation + loading spinner during UPnP load
...
android / Build + lint + test (push) Successful in 3m55s
Part A: split loadQueueOnSonos into an initial phase (tracks[0..currentIndex]
only, then SetAV+Seek+Play) plus a background extendQueueOnSonos coroutine
that appends the remainder after activation. Reduces the UPnP activation
block from ~17s (100 tracks serial) to ~200ms (1 track at currentIndex=0).
Background extension cancels cleanly when activeUpnpHolder.active changes.
Part B: add PlayerUiState.isUpnpLoading (target set, active null). Projected
inline in onEvents so it stays consistent with the rest of the snapshot, plus
a separate combine(target, active) collector that updates uiState between
player-event fires. NowPlayingScreen.TransportRow and MiniPlayer.MiniRow
replace the play/pause icon with a CircularProgressIndicator while loading
and disable the button tap to prevent premature commands to the Sonos queue.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 22:56:06 -04:00
bvandeusen and Claude Sonnet 4.6
9c0013f4b6
fix(android): defer holder.active until SOAP wired -- drop transport during load
...
android / Build + lint + test (push) Successful in 4m34s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 22:46:57 -04:00
bvandeusen
6129536153
diag(android): log ForwardingPlayer transport overrides on entry
android / Build + lint + test (push) Successful in 3m50s
2026-06-03 22:32:33 -04:00
bvandeusen
e6c3c959fa
fix(android): handleZeroDurationIfNeeded ReturnCount within cap
android / Build + lint + test (push) Successful in 3m45s
2026-06-03 22:25:53 -04:00
bvandeusen
e011b04e04
fix(android): remove pollLoop cursor sync -- races with queue load and SOAP
android / Build + lint + test (push) Has been cancelled
2026-06-03 22:24:34 -04:00
bvandeusen
e2866795ef
fix(android): skip zero-duration auto-advance during UPnP playback
android / Build + lint + test (push) Failing after 1m26s
2026-06-03 22:18:11 -04:00
bvandeusen
e20d7b1438
fix(android): correct SOAPACTION assertions in next/previous tests
android / Build + lint + test (push) Successful in 3m58s
2026-06-03 22:06:54 -04:00
bvandeusen and Claude Sonnet 4.6
2a098a78fe
feat(android): Sonos queue mode -- ClearQueue + AddURIToQueue + x-rincon-queue
...
android / Build + lint + test (push) Failing after 9m9s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 21:55:03 -04:00
bvandeusen and Claude Sonnet 4.6
ece37e9a92
fix(android): remove pollLoop natural-advance -- races with selectUpnp and skip
...
android / Build + lint + test (push) Successful in 4m1s
Polling alone cannot distinguish Sonos auto-advancing via SetNextAVTransportURI
from URI changes we made ourselves via syncCurrentItemToRemote. This produced
two races: (1) activation race -- first poll returns stale URI from prior
session, second returns new URI, false-positive fires and double-advances the
cursor; (2) user-skip race -- skip's syncCurrentItemToRemote changes the URI,
next poll sees the change and fires again. Remove the detection block and
previousTrackUri capture from pollOnce entirely. pollLoop is now a pure
state-tracker (position + transport state) plus the one-shot initial pre-queue
gate. GENA event subscriptions to AVTransport LastChange are the correct fix;
deferred to its own slice (see parity-map).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 21:42:01 -04:00
bvandeusen and Claude Sonnet 4.6
8a1203c4a1
fix(android): revert x-rincon-mp3radio Sonos URI -- plain https for music tracks
...
android / Build + lint + test (push) Successful in 4m13s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 21:31:31 -04:00
bvandeusen and Claude Sonnet 4.6
487d1bd430
fix(android): SOAP/UPnP parsers enable processNamespaces -- correct name extraction
...
android / Build + lint + test (push) Successful in 4m4s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 20:58:59 -04:00
bvandeusen and Claude Sonnet 4.6
5c99341b34
fix(android): test assertions use JUnit Jupiter for lazy-message Supplier<String>
...
android / Build + lint + test (push) Failing after 3m31s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 20:51:28 -04:00
bvandeusen and Claude Sonnet 4.6
8fe3308afd
fix(android): detekt -- parseHhMmSs ReturnCount/MagicNumber + readUntilEndTag jumps
...
android / Build + lint + test (push) Failing after 3m5s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 20:45:00 -04:00
bvandeusen
96594ba52b
fix(android): Sonos ZGT robust extraction -- escaped + nested element fallback + diag
android / Build + lint + test (push) Failing after 1m29s
2026-06-03 20:40:52 -04:00
bvandeusen and Claude Sonnet 4.6
2c61d7a333
fix(android): Sonos UDN comparison strips _MR/_MS suffix -- coordinator routing
...
android / Build + lint + test (push) Failing after 2m41s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 20:29:08 -04:00
bvandeusen and Claude Sonnet 4.6
8652b86f40
fix(android): Sonos x-rincon-mp3radio URI transform for SetAVTransportURI
...
android / Build + lint + test (push) Failing after 1m20s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 20:20:25 -04:00
bvandeusen and Claude Sonnet 4.6
75132a2afe
diag(android): log raw SOAP response body for first 3 UPnP polls
...
android / Build + lint + test (push) Failing after 1m22s
Add optional onRawResponse callback to SoapClient; loggingSoapClient
factory emits the first 6 GetPositionInfo/GetTransportInfo bodies
(3 poll cycles) at WARN so release logs capture them. Wire into
transportFor so every AVTransportClient for a new UPnP session logs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 20:12:15 -04:00
bvandeusen and Claude Sonnet 4.6
673f98487f
fix(android): UPnP local pause via delegate -- no SOAP race
...
android / Build + lint + test (push) Failing after 1m30s
Move local ExoPlayer pause from OutputPickerController.selectUpnp
into MinstrelForwardingPlayer.onActiveChanged (handler.post { delegate.pause() }).
This guarantees the pause hits ExoPlayer before the holder is live, eliminating
the async race that caused SOAP fault 701 on Sonos when pause() was dispatched
via playerController after holder.active was already set.
Also adds per-poll Timber.w before initialPreQueueDone for diagnostics.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 19:53:41 -04:00
bvandeusen and Claude Sonnet 4.6
c556388a6b
fix(android): UPnP activation order -- pause local before holder.set; sync+preQueue sequential; diagnostic Timber.w
...
android / Build + lint + test (push) Failing after 1m28s
- OutputPickerController.selectUpnp: pause ExoPlayer BEFORE setting
activeUpnpHolder so ForwardingPlayer.pause() routes to ExoPlayer,
not SOAP; remove now-redundant playerController.pause() from inside
runCatching; bump activation Timber.i -> Timber.w for release logcat
- MinstrelForwardingPlayer: remove Player.Listener onMediaItemTransition
that raced with seekToNext/Prev override's syncCurrentItemToRemote;
seekToNext/Prev now launch sync -> preQueueNext sequentially in one
coroutine; remove early preQueueNext from onActiveChanged (raced with
selectUpnp SOAP); move initial pre-queue to pollLoop, fires once
trackUri lands confirming Sonos accepted SetAV+Play
- Extract pollOnce from pollLoop to stay within detekt LongMethod=60;
natural-advance branch now calls preQueueNext explicitly (no listener)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 19:47:19 -04:00
bvandeusen and Claude Sonnet 4.6
edffdec2b2
fix(android): UPnP drop falls back to local; pollLoop detects natural advance
...
android / Build + lint + test (push) Failing after 1m10s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 18:07:20 -04:00
bvandeusen and Claude Sonnet 4.6
1ab21d81ca
feat(android): SetNextAVTransportURI pre-queue for gap-free UPnP advance
...
android / Build + lint + test (push) Failing after 1m35s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 17:53:10 -04:00
bvandeusen
81794e2475
fix(android): UPnP volume cache keyed to active route id
android / Build + lint + test (push) Has been cancelled
2026-06-03 17:52:00 -04:00
bvandeusen and Claude Sonnet 4.6
29309d9bfb
ui(android): drop snackbar + hardware volume keys when UPnP route active
...
android / Build + lint + test (push) Failing after 1m24s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 17:43:55 -04:00
bvandeusen and Claude Sonnet 4.6
70b29567fb
refactor(android): service holds Player not ExoPlayer for ForwardingPlayer wrap
...
android / Build + lint + test (push) Failing after 1m25s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 17:36:35 -04:00
bvandeusen and Claude Sonnet 4.6
2f4d67d3c8
feat(android): PlayerFactory wraps ExoPlayer in ForwardingPlayer + drop events
...
android / Build + lint + test (push) Failing after 1m35s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com >
2026-06-03 17:34:35 -04:00