EARHORNMUSIC UPnP · Android TV · Phones · Android Auto · GNU/Linux
Release 0.5.0

RemoteRenderer.kt

package dev.stave.domain.model

/**
 * A UPnP/DLNA MediaRenderer discovered on the LAN that advertises an AVTransport
 * service — the kind of device we can DRIVE playback on, as opposed to a
 * [MediaServer] which is the kind we BROWSE content from.
 *
 * Members include any other Earhorn instance with "LAN broadcast" enabled
 * (recognizable by [isEarhorn]) plus third-party renderers like BubbleUPnP's
 * receiver, Linn/Naim streamers, gmediarender, OpenHome-friendly speakers, etc.
 *
 * Keyed by [udn] — stable across IP changes and process restarts on the remote
 * side because each renderer persists its own UDN (see [dev.stave.upnp.renderer.
 * EarhornRendererService] for our equivalent).
 */
data class RemoteRenderer(
    val udn: String,
    val friendlyName: String,
    val manufacturer: String?,
    val modelName: String?,
    val modelDescription: String?,
    val baseUrl: String,
    val iconUrl: String? = null,
) {
    /**
     * True if this renderer was advertised by another Earhorn instance — used
     * for badging in the picker UI so "Earhorn on a room-laptop" reads as a
     * peer of "this Earhorn" rather than as a generic third-party device.
     *
     * Detection is by manufacturer string set in [dev.stave.upnp.renderer.
     * EarhornMediaRendererDevice.build]. If we ever rename or expand to other
     * branded variants, update both ends together — the check is naïve string
     * match, no model-number lookup.
     */
    val isEarhorn: Boolean
        get() = manufacturer?.equals("Faveat Software", ignoreCase = true) == true ||
            modelName?.contains("Earhorn", ignoreCase = true) == true
}