beacon: own-IP filter (shared-LAN fix) + wireless-debugging-off warning

Live multi-device test exposed two things:
- On a shared LAN, NsdManager discovers EVERY device's
  _adb-tls-connect._tcp advertisement, so a phone reported the tablet's
  port for its own IP (crossed). Now only accept the resolved service
  whose host matches this device's own wlan0 IP.
- When Wireless debugging is turned off, adbd drops its mDNS
  advertisement (onServiceLost) — the app now says so plainly in the
  status line and the ongoing notification ("Wireless debugging appears
  OFF — re-enable it"), instead of a vague "waiting".

Verified with phone + tablet on the same LAN: correct per-device ports,
both auto-connected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
mrambossek
2026-07-31 22:13:13 +02:00
co-authored by Claude Opus 5
parent 38d4440412
commit 7b9b312dcd
@@ -62,7 +62,13 @@ class BeaconService : Service() {
override fun onStopDiscoveryFailed(t: String?, code: Int) {} override fun onStopDiscoveryFailed(t: String?, code: Int) {}
override fun onDiscoveryStarted(t: String?) {} override fun onDiscoveryStarted(t: String?) {}
override fun onDiscoveryStopped(t: String?) {} override fun onDiscoveryStopped(t: String?) {}
override fun onServiceLost(s: NsdServiceInfo?) { currentPort = -1 } override fun onServiceLost(s: NsdServiceInfo?) {
// adbd stops advertising when Wireless debugging is turned off.
currentPort = -1
val warn = "⚠ Wireless debugging appears OFF (adb mDNS service gone) — re-enable it"
Status.set(warn)
updateNotification(warn)
}
override fun onServiceFound(s: NsdServiceInfo?) { override fun onServiceFound(s: NsdServiceInfo?) {
if (s == null) return if (s == null) return
resolve(s) resolve(s)
@@ -79,8 +85,14 @@ class BeaconService : Service() {
nsd.resolveService(info, object : NsdManager.ResolveListener { nsd.resolveService(info, object : NsdManager.ResolveListener {
override fun onResolveFailed(s: NsdServiceInfo?, code: Int) {} override fun onResolveFailed(s: NsdServiceInfo?, code: Int) {}
override fun onServiceResolved(s: NsdServiceInfo?) { override fun onServiceResolved(s: NsdServiceInfo?) {
val port = s?.port ?: return s ?: return
currentPort = port // On a shared LAN, NsdManager discovers EVERY device's adb
// advertisement — accept only the one whose host is THIS device's
// own IP, else we'd report a neighbour's port for our IP.
val host = s.host?.hostAddress
val mine = wifiIpv4()
if (host != null && mine != null && host != mine) return
currentPort = s.port
scope.launch { report() } scope.launch { report() }
} }
}) })
@@ -89,7 +101,13 @@ class BeaconService : Service() {
private fun report() { private fun report() {
val ip = wifiIpv4() ?: run { Status.set("no wlan0 IPv4 (is wifi up?)"); return } val ip = wifiIpv4() ?: run { Status.set("no wlan0 IPv4 (is wifi up?)"); return }
val port = currentPort val port = currentPort
if (port <= 0) { Status.set("$ip — waiting for wireless-debug port"); return } if (port <= 0) {
// No adb advertisement: either discovery hasn't landed yet, or (usually) Wireless
// debugging is off. Say so plainly.
val warn = "$ip — no wireless-debug port. Is Wireless debugging ON?"
Status.set(warn); updateNotification(warn)
return
}
val device = android.os.Build.MODEL.replace(Regex("[^A-Za-z0-9_.-]"), "_") val device = android.os.Build.MODEL.replace(Regex("[^A-Za-z0-9_.-]"), "_")
val body = """{"device":"$device","ip":"$ip","port":$port}""" val body = """{"device":"$device","ip":"$ip","port":$port}"""
// Send over a VALIDATED internet network — the wireless-debug wifi is often a restricted // Send over a VALIDATED internet network — the wireless-debug wifi is often a restricted