AeroToss: строгая фильтрация NSD + app=aerotoss в TXT

- Android NSD: строгая проверка serviceType (точное совпадение)
- Android NSD: проверка TXT record на app=aerotoss для идентификации
- Чужие устройства (TV, мониторы) больше не показываются
- Desktop TXT record: добавлен app=aerotoss для идентификации
- Исправлен type=phone → type из TXT record
This commit is contained in:
2026-08-19 23:03:15 +03:00
parent 817e8f09aa
commit 6eeda61ad3
2 changed files with 24 additions and 8 deletions
@@ -39,6 +39,7 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
setAttribute("name", deviceName) setAttribute("name", deviceName)
setAttribute("port", port.toString()) setAttribute("port", port.toString())
setAttribute("type", "phone") setAttribute("type", "phone")
setAttribute("app", "aerotoss")
} }
registrationListener = object : NsdManager.RegistrationListener { registrationListener = object : NsdManager.RegistrationListener {
@@ -67,9 +68,13 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
override fun onServiceFound(serviceInfo: NsdServiceInfo) { override fun onServiceFound(serviceInfo: NsdServiceInfo) {
Log.d(TAG, "Found: ${serviceInfo.serviceName} type=${serviceInfo.serviceType}") Log.d(TAG, "Found: ${serviceInfo.serviceName} type=${serviceInfo.serviceType}")
if (serviceInfo.serviceName != SERVICE_NAME &&
resolvingServices.add(serviceInfo.serviceName) // Strict filter: must be our exact service type AND not our own service
) { if (serviceInfo.serviceName == SERVICE_NAME) return
if (serviceInfo.serviceType != SERVICE_TYPE &&
serviceInfo.serviceType != "${SERVICE_TYPE}local.") return
if (resolvingServices.add(serviceInfo.serviceName)) {
nsdManager?.resolveService(serviceInfo, object : NsdManager.ResolveListener { nsdManager?.resolveService(serviceInfo, object : NsdManager.ResolveListener {
override fun onResolveFailed(info: NsdServiceInfo, errorCode: Int) { override fun onResolveFailed(info: NsdServiceInfo, errorCode: Int) {
resolvingServices.remove(info.serviceName) resolvingServices.remove(info.serviceName)
@@ -80,13 +85,17 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
resolvingServices.remove(info.serviceName) resolvingServices.remove(info.serviceName)
val host = info.host?.hostAddress ?: return val host = info.host?.hostAddress ?: return
// Try to get device name from TXT records // Check TXT record for our app identifier
var name = info.serviceName var name = info.serviceName
var id = info.serviceName var id = info.serviceName
var deviceType = DeviceType.PHONE var deviceType = DeviceType.PHONE
var isAeroToss = false
try { try {
val attributes = info.attributes val attributes = info.attributes
attributes["app"]?.let { app ->
if (String(app) == "aerotoss") isAeroToss = true
}
attributes["name"]?.let { name = String(it) } attributes["name"]?.let { name = String(it) }
attributes["id"]?.let { id = String(it) } attributes["id"]?.let { id = String(it) }
attributes["type"]?.let { type -> attributes["type"]?.let { type ->
@@ -96,6 +105,13 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
} }
} catch (_: Exception) {} } catch (_: Exception) {}
// Only add if it's actually an AeroToss service
if (!isAeroToss) {
Log.d(TAG, "Skipping non-AeroToss service: ${info.serviceName}")
return
}
Log.d(TAG, "Resolved AeroToss: $name ($id) at $host:${info.port}")
val device = Device( val device = Device(
id = id, id = id,
name = name, name = name,
@@ -103,8 +119,6 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
hostAddress = host, hostAddress = host,
port = info.port port = info.port
) )
Log.d(TAG, "Resolved: $name ($id) at $host:${info.port}")
discoveredDevices[id] = device discoveredDevices[id] = device
_devices.value = discoveredDevices.values.toList() _devices.value = discoveredDevices.values.toList()
} }
@@ -114,7 +128,8 @@ class AndroidNsdDiscovery(context: Context) : DiscoveryManager {
override fun onServiceLost(serviceInfo: NsdServiceInfo) { override fun onServiceLost(serviceInfo: NsdServiceInfo) {
Log.d(TAG, "Lost: ${serviceInfo.serviceName}") Log.d(TAG, "Lost: ${serviceInfo.serviceName}")
discoveredDevices.remove(serviceInfo.serviceName) // Find and remove by service name
discoveredDevices.entries.removeAll { it.value.name == serviceInfo.serviceName }
resolvingServices.remove(serviceInfo.serviceName) resolvingServices.remove(serviceInfo.serviceName)
_devices.value = discoveredDevices.values.toList() _devices.value = discoveredDevices.values.toList()
} }
@@ -279,7 +279,8 @@ class JmdnsDiscovery : DiscoveryManager {
"id=$deviceId", "id=$deviceId",
"name=$deviceName", "name=$deviceName",
"port=$servicePort", "port=$servicePort",
"type=desktop" "type=desktop",
"app=aerotoss"
) )
for (entry in entries) { for (entry in entries) {
val bytes = entry.toByteArray(Charsets.UTF_8) val bytes = entry.toByteArray(Charsets.UTF_8)