UpnpServiceHolder.kt
55 lines · 2.3 KB
Changed in: 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 | } |


