UpnpServiceHolder.kt
Each line, with the release that last changed it.
| 0.5.0 | 1 | package dev.stave.upnp |
| 2 | ||
| 3 | import dev.stave.domain.model.MediaServer | |
| 4 | import dev.stave.domain.model.RemoteRenderer | |
| 5 | import kotlinx.coroutines.flow.StateFlow | |
| 6 | import org.jupnp.controlpoint.ControlPoint | |
| 7 | import org.jupnp.model.meta.LocalDevice | |
| 8 | import org.jupnp.model.meta.RemoteDevice | |
| 9 | ||
| 10 | /** | |
| 11 | * Platform-agnostic UPnP service surface. | |
| 12 | * | |
| 13 | * Android and Desktop holders differ in *how* they start jUPnP: | |
| 14 | * - Android binds to [org.jupnp.android.AndroidUpnpServiceImpl] through a bound Service and | |
| 15 | * holds a WifiManager MulticastLock while the app is foregrounded. | |
| 16 | * - Desktop constructs a plain [org.jupnp.UpnpServiceImpl] directly and doesn't need any | |
| 17 | * multicast lock — stock Linux networking handles SSDP fine. | |
| 18 | * | |
| 19 | * Everything downstream of this (ContentDirectoryClient, MediaCollector, viewmodels) | |
| 20 | * depends on this interface, not the platform-specific class. | |
| 21 | */ | |
| 22 | interface UpnpServiceHolder { | |
| 23 | ||
| 24 | /** UPnP MediaServer devices discovered on the LAN — what we BROWSE from. */ | |
| 25 | val servers: StateFlow<List<MediaServer>> | |
| 26 | ||
| 27 | /** UPnP MediaRenderer devices discovered on the LAN — what we can DRIVE to. | |
| 28 | * Other Earhorn instances with broadcast on, plus third-party renderers. | |
| 29 | * Used by the (future) renderer-picker UI. */ | |
| 30 | val renderers: StateFlow<List<RemoteRenderer>> | |
| 31 | ||
| 32 | val controlPoint: ControlPoint? | |
| 33 | ||
| 34 | fun findDevice(udn: String): RemoteDevice? | |
| 35 | ||
| 36 | /** Start the jUPnP stack and begin SSDP discovery. Idempotent. */ | |
| 37 | fun start() | |
| 38 | ||
| 39 | /** Shut the jUPnP stack down cleanly. Sends BYEBYE messages. */ | |
| 40 | fun stop() | |
| 41 | ||
| 42 | /** Force an SSDP M-SEARCH. Called from pull-to-refresh / "Rescan" / window focus. */ | |
| 43 | fun rescan() | |
| 44 | ||
| 45 | /** Register a [LocalDevice] with the registry so this machine advertises itself | |
| 46 | * on the LAN. Used by [dev.stave.upnp.renderer.EarhornRendererService] when the | |
| 47 | * user toggles "act as renderer" on. Returns true on success; false if the stack | |
| 48 | * isn't up or registration failed. Calling with an already-registered device | |
| 49 | * (same UDN) is a no-op. */ | |
| 50 | fun registerLocalDevice(device: LocalDevice): Boolean | |
| 51 | ||
| 52 | /** Remove a previously-registered [LocalDevice]. Sends ssdp:byebye so remote | |
| 53 | * control points know we've gone away. No-op if the device isn't registered. */ | |
| 54 | fun unregisterLocalDevice(device: LocalDevice) | |
| 55 | } |


