fix(android): UPnP - clean Sonos friendlyName for picker display
android / Build + lint + test (push) Successful in 4m28s
android / Build + lint + test (push) Successful in 4m28s
Sonos uses the friendlyName format 'Room - Device Type - RINCON_<UDN>' The picker was showing it verbatim, so the user saw rows like 'Living Room - Sonos Play:1 Media Renderer - RINCON_5CAAFD79...' Now strips on the first ' - ' for Sonos manufacturer matches, so the chip shows just 'Living Room' / 'Kitchen' / etc. Subtitle (manufacturer + model) still renders below per the existing sheet design, so the device-type info isn't lost. Generic UPnP devices that append a '(192.168.x.x)' IP suffix get that stripped too via an end-of-string-anchored regex. Empty / blank friendlyName still falls back to 'Network speaker'.
This commit is contained in:
+32
-1
@@ -106,7 +106,7 @@ class UpnpDiscoveryController @Inject constructor(
|
||||
?.let { desc ->
|
||||
UpnpRoute(
|
||||
id = desc.udn,
|
||||
name = desc.friendlyName.ifBlank { "Network speaker" },
|
||||
name = displayName(desc.friendlyName, desc.manufacturer),
|
||||
manufacturer = desc.manufacturer,
|
||||
modelName = desc.modelName,
|
||||
avTransportControlUrl = desc.avTransportControlUrl,
|
||||
@@ -115,6 +115,30 @@ class UpnpDiscoveryController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean the raw UPnP friendlyName for picker display. Sonos uses
|
||||
* the format `Room - Device Type - RINCON_<UDN>`; we strip
|
||||
* everything after the first " - " so the chip shows just "Living
|
||||
* Room" / "Kitchen" / etc. Generic UPnP devices (Yamaha, Samsung
|
||||
* TV, etc.) often append a "(192.168.x.x)" IP suffix; strip that
|
||||
* too. Empty / blank → "Network speaker" fallback.
|
||||
*
|
||||
* Device subtitle (manufacturer + model) is rendered separately
|
||||
* by the picker sheet, so room-only here doesn't lose information.
|
||||
*/
|
||||
private fun displayName(friendlyName: String, manufacturer: String): String {
|
||||
val trimmed = friendlyName.trim()
|
||||
if (trimmed.isBlank()) return "Network speaker"
|
||||
val byVendor = when {
|
||||
manufacturer.contains("Sonos", ignoreCase = true) -> {
|
||||
trimmed.substringBefore(" - ", trimmed)
|
||||
}
|
||||
else -> trimmed
|
||||
}
|
||||
val withoutIpSuffix = byVendor.replace(IP_SUFFIX_REGEX, "").trim()
|
||||
return withoutIpSuffix.ifBlank { "Network speaker" }
|
||||
}
|
||||
|
||||
private fun fetchBody(url: HttpUrl): String? {
|
||||
val body = runCatching {
|
||||
okHttp.newCall(Request.Builder().url(url).build()).execute().use {
|
||||
@@ -123,4 +147,11 @@ class UpnpDiscoveryController @Inject constructor(
|
||||
}.getOrNull().orEmpty()
|
||||
return body.ifEmpty { null }
|
||||
}
|
||||
|
||||
private companion object {
|
||||
// " (192.168.0.77)" trailing host suffix some generic UPnP
|
||||
// devices append. Anchored to end-of-string so it never eats
|
||||
// a legitimate parenthetical inside a name.
|
||||
val IP_SUFFIX_REGEX = Regex("""\s*\(\d+\.\d+\.\d+\.\d+\)$""")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user