Improve discovery reliability for some devices (#2718)

- Some devices (most notably Google Pixels) require manually requesting a multicast lock in order for DNS-SD to work reliably
This commit is contained in:
Joris Pelgröm 2022-07-29 23:55:06 +02:00 committed by GitHub
parent d03eb74fa9
commit c7b4f229ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 19 additions and 0 deletions

View file

@ -7,6 +7,7 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />

View file

@ -30,6 +30,7 @@ class OnboardingViewModel @Inject constructor(
private val _homeAssistantSearcher = HomeAssistantSearcher(
nsdManager = app.getSystemService()!!,
wifiManager = app.getSystemService(),
onInstanceFound = { instance ->
if (foundInstances.none { it.url == instance.url }) {
foundInstances.add(instance)

View file

@ -2,6 +2,7 @@ package io.homeassistant.companion.android.onboarding.discovery
import android.net.nsd.NsdManager
import android.net.nsd.NsdServiceInfo
import android.net.wifi.WifiManager
import android.util.Log
import androidx.lifecycle.DefaultLifecycleObserver
import androidx.lifecycle.LifecycleOwner
@ -11,6 +12,7 @@ import java.util.concurrent.locks.ReentrantLock
class HomeAssistantSearcher constructor(
private val nsdManager: NsdManager,
private val wifiManager: WifiManager?,
private val onInstanceFound: (instance: HomeAssistantInstance) -> Unit,
private val onError: () -> Unit
) : NsdManager.DiscoveryListener, DefaultLifecycleObserver {
@ -25,6 +27,8 @@ class HomeAssistantSearcher constructor(
private var isSearching = false
private var multicastLock: WifiManager.MulticastLock? = null
fun beginSearch() {
if (isSearching)
return
@ -35,6 +39,17 @@ class HomeAssistantSearcher constructor(
Log.e(TAG, "Issue starting discover.", e)
isSearching = false
onError()
return
}
try {
if (wifiManager != null && multicastLock == null) {
multicastLock = wifiManager.createMulticastLock(TAG)
multicastLock?.setReferenceCounted(true)
multicastLock?.acquire()
}
} catch (e: Exception) {
Log.e(TAG, "Issue acquiring multicast lock", e)
// Discovery might still work so continue
}
}
@ -44,6 +59,8 @@ class HomeAssistantSearcher constructor(
isSearching = false
try {
nsdManager.stopServiceDiscovery(this)
multicastLock?.release()
multicastLock = null
} catch (e: Exception) {
Log.e(TAG, "Issue stopping discovery", e)
}