Files
minstrel/android
bvandeusen dabca3ad24
android / Build + lint + test (push) Successful in 3m44s
fix(android): stop single SOAP failure from dropping Sonos to local
When the phone was locked, a transport command (lock-screen/Bluetooth/
watch media button, or queue-resync play) issued during a WiFi power-save
stall would hit the 2s connect timeout and throw. handleSoapFailure then
cancelled the poll loop and fired onDrop on that single failure -- showing
"Disconnected from <Sonos>" and reverting to local playback, even though
the renderer was perfectly reachable. This bypassed the poll loop's
deliberate 30-consecutive-failure tolerance (DROP_THRESHOLD, bumped from 3
precisely for screen-off WiFi sleep / Doze).

Make the 1 Hz poll loop the sole drop arbiter:
- Transport SOAP commands retry transient IO failures (retryTransientIo:
  3 attempts, 400ms backoff) so a brief WiFi stall lands the command once
  WiFi wakes instead of abandoning it. A SoapFaultException (renderer
  answered, rejected the action) is not retried -- the device is alive.
- handleTransportFailure no longer cancels the poll loop or fires onDrop;
  it logs and nudges an immediate poll so the UI reconciles to Sonos's
  actual state. If the renderer is truly gone, the poll loop trips the
  drop on its own via DROP_THRESHOLD.

Extract retryTransientIo as an internal top-level fn + unit test covering
first-success, retry-then-succeed, exhaust-and-rethrow, and no-retry-on-
SoapFault. Refresh now-stale drop-heuristic comments.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 10:54:14 -04:00
..