mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor: extract NsdManager methods
This commit is contained in:
parent
f29d4e2309
commit
e5a20c9665
3 changed files with 72 additions and 66 deletions
|
|
@ -154,9 +154,6 @@ class BTScanModel @Inject constructor(
|
|||
}
|
||||
|
||||
fun stopScan() {
|
||||
// Stop Network Service Discovery (for TCP)
|
||||
networkDiscovery?.cancel()
|
||||
|
||||
if (scanJob != null) {
|
||||
debug("stopping scan")
|
||||
try {
|
||||
|
|
@ -170,14 +167,9 @@ class BTScanModel @Inject constructor(
|
|||
} else _spinner.value = false
|
||||
}
|
||||
|
||||
private var networkDiscovery: Job? = null
|
||||
fun startScan(context: Context?) {
|
||||
_spinner.value = true
|
||||
|
||||
// Start Network Service Discovery (find TCP devices)
|
||||
networkDiscovery = networkRepository.networkDiscoveryFlow()
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
if (context != null) startCompanionScan(context) else startClassicScan()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,19 +5,23 @@ import android.net.Network
|
|||
import android.net.NetworkRequest
|
||||
import android.net.nsd.NsdManager
|
||||
import android.net.nsd.NsdServiceInfo
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.coroutineScope
|
||||
import com.geeksville.mesh.android.Logging
|
||||
import com.geeksville.mesh.CoroutineDispatchers
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.sync.Semaphore
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class NetworkRepository @Inject constructor(
|
||||
dispatchers: CoroutineDispatchers,
|
||||
processLifecycle: Lifecycle,
|
||||
private val nsdManagerLazy: dagger.Lazy<NsdManager?>,
|
||||
private val connectivityManager: dagger.Lazy<ConnectivityManager>,
|
||||
) : Logging {
|
||||
|
|
@ -43,66 +47,16 @@ class NetworkRepository @Inject constructor(
|
|||
private val _resolvedList = MutableStateFlow<List<NsdServiceInfo>>(emptyList())
|
||||
val resolvedList: StateFlow<List<NsdServiceInfo>> get() = _resolvedList
|
||||
|
||||
private val _networkDiscovery: Flow<NsdServiceInfo> = callbackFlow {
|
||||
val resolveQueue = Semaphore(1)
|
||||
val hostsList = mutableListOf<NsdServiceInfo>()
|
||||
val discoveryListener = object : NsdManager.DiscoveryListener {
|
||||
override fun onDiscoveryStarted(serviceType: String) {
|
||||
debug("Service discovery started: $serviceType")
|
||||
}
|
||||
|
||||
override fun onServiceFound(service: NsdServiceInfo) {
|
||||
debug("Service discovery success: $service")
|
||||
if (service.serviceName.contains(SERVICE_NAME)) {
|
||||
val resolveListener = object : NsdManager.ResolveListener {
|
||||
override fun onServiceResolved(service: NsdServiceInfo) {
|
||||
debug("Resolve Succeeded: $service")
|
||||
hostsList.add(service)
|
||||
_resolvedList.value = hostsList
|
||||
trySend(service)
|
||||
}
|
||||
|
||||
override fun onResolveFailed(service: NsdServiceInfo, errorCode: Int) {
|
||||
debug("Resolve failed: $service - Error code: $errorCode")
|
||||
}
|
||||
}
|
||||
// one resolveService at a time to avoid: Error Code 3: Failure Already active
|
||||
launch {
|
||||
try {
|
||||
resolveQueue.acquire()
|
||||
nsdManagerLazy.get()?.resolveService(service, resolveListener)
|
||||
} finally {
|
||||
resolveQueue.release()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug("Not our Service - Name: ${service.serviceName}, Type: ${service.serviceType}")
|
||||
init {
|
||||
processLifecycle.coroutineScope.launch(dispatchers.default) {
|
||||
nsdManagerLazy.get()?.let { manager ->
|
||||
manager.discoverServices(SERVICE_TYPE).collect { serviceList ->
|
||||
_resolvedList.value = serviceList
|
||||
.filter { it.serviceName == SERVICE_NAME }
|
||||
.mapNotNull { manager.resolveService(it) }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onServiceLost(service: NsdServiceInfo) {
|
||||
debug("Service lost: $service")
|
||||
}
|
||||
|
||||
override fun onDiscoveryStopped(serviceType: String) {
|
||||
debug("Discovery stopped: $serviceType")
|
||||
}
|
||||
|
||||
override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
|
||||
debug("Start Discovery failed: Error code: $errorCode")
|
||||
}
|
||||
|
||||
override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
|
||||
debug("Stop Discovery failed: Error code: $errorCode")
|
||||
}
|
||||
}
|
||||
nsdManagerLazy.get()
|
||||
?.discoverServices(SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, discoveryListener)
|
||||
awaitClose { nsdManagerLazy.get()?.stopServiceDiscovery(discoveryListener) }
|
||||
}
|
||||
|
||||
fun networkDiscoveryFlow(): Flow<NsdServiceInfo> {
|
||||
return _networkDiscovery
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,60 @@
|
|||
package com.geeksville.mesh.repository.network
|
||||
|
||||
import android.net.nsd.NsdManager
|
||||
import android.net.nsd.NsdServiceInfo
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
internal fun NsdManager.discoverServices(
|
||||
serviceType: String,
|
||||
protocolType: Int = NsdManager.PROTOCOL_DNS_SD,
|
||||
): Flow<List<NsdServiceInfo>> = callbackFlow {
|
||||
val serviceList = mutableListOf<NsdServiceInfo>()
|
||||
val discoveryListener = object : NsdManager.DiscoveryListener {
|
||||
override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
|
||||
cancel("Start Discovery failed: Error code: $errorCode")
|
||||
}
|
||||
|
||||
override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
|
||||
cancel("Stop Discovery failed: Error code: $errorCode")
|
||||
}
|
||||
|
||||
override fun onDiscoveryStarted(serviceType: String) {
|
||||
}
|
||||
|
||||
override fun onDiscoveryStopped(serviceType: String) {
|
||||
close()
|
||||
}
|
||||
|
||||
override fun onServiceFound(serviceInfo: NsdServiceInfo) {
|
||||
serviceList += serviceInfo
|
||||
trySend(serviceList)
|
||||
}
|
||||
|
||||
override fun onServiceLost(serviceInfo: NsdServiceInfo) {
|
||||
serviceList -= serviceInfo
|
||||
trySend(serviceList)
|
||||
}
|
||||
}
|
||||
discoverServices(serviceType, protocolType, discoveryListener)
|
||||
awaitClose { stopServiceDiscovery(discoveryListener) }
|
||||
}
|
||||
|
||||
internal suspend fun NsdManager.resolveService(
|
||||
serviceInfo: NsdServiceInfo,
|
||||
): NsdServiceInfo? = suspendCancellableCoroutine { continuation ->
|
||||
val listener = object : NsdManager.ResolveListener {
|
||||
override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {
|
||||
continuation.resume(null)
|
||||
}
|
||||
|
||||
override fun onServiceResolved(serviceInfo: NsdServiceInfo) {
|
||||
continuation.resume(serviceInfo)
|
||||
}
|
||||
}
|
||||
resolveService(serviceInfo, listener)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue