03cdff547d
android / Build + lint + test (push) Successful in 3m52s
UpnpDiscoveryController - Hilt singleton that owns the SSDP listener, follows each discovered LOCATION URL to fetch + parse the device description, projects MediaRenderers into a StateFlow<List<UpnpRoute>>. OutputPickerController now combines system routes with the UPnP Flow into a unified RouteSnapshot. select() branches by protocol: SYSTEM goes through MediaRouter as before; UPNP requests a signed stream token via POST /api/cast/stream-token then calls AVTransport.SetAVTransportURI + Play against the discovered device. Local playback pauses on UPnP selection. OutputPickerSheet gains a MulticastHintRow shown when no UPnP devices appear after a 3s grace period - the 'your router may be blocking multicast' footer hint per the spec. Closes the UPnP slice spec'd in docs/superpowers/specs/2026-06-03-android-output-picker-upnp-design.md. On-device verification pending: pair a Sonos / UPnP speaker, confirm discovery + selection + playback + the multicast-blocked hint.