kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
Refactor NsdManager and improve service display (#2292)
Signed-off-by: James Rich <2199651+jamesarich@users.noreply.github.com>pull/2309/head
rodzic
ec74bbfe19
commit
8b095aba09
|
|
@ -68,8 +68,9 @@ class BTScanModel @Inject constructor(
|
|||
val devices = MutableLiveData<MutableMap<String, DeviceListEntry>>(mutableMapOf())
|
||||
val errorText = MutableLiveData<String?>(null)
|
||||
|
||||
private val showMockInterface: StateFlow<Boolean> get() =
|
||||
MutableStateFlow(radioInterfaceService.isMockInterface()).asStateFlow()
|
||||
private val showMockInterface: StateFlow<Boolean>
|
||||
get() =
|
||||
MutableStateFlow(radioInterfaceService.isMockInterface()).asStateFlow()
|
||||
|
||||
init {
|
||||
combine(
|
||||
|
|
@ -84,7 +85,13 @@ class BTScanModel @Inject constructor(
|
|||
}
|
||||
|
||||
// Include a placeholder for "None"
|
||||
addDevice(DeviceListEntry(context.getString(R.string.none), NO_DEVICE_SELECTED, true))
|
||||
addDevice(
|
||||
DeviceListEntry(
|
||||
context.getString(R.string.none),
|
||||
NO_DEVICE_SELECTED,
|
||||
true
|
||||
)
|
||||
)
|
||||
|
||||
if (showMockInterface) {
|
||||
addDevice(DeviceListEntry("Demo Mode", "m", true))
|
||||
|
|
@ -97,7 +104,19 @@ class BTScanModel @Inject constructor(
|
|||
// Include Network Service Discovery
|
||||
tcp.forEach { service ->
|
||||
val address = service.toAddressString()
|
||||
addDevice(DeviceListEntry(address, "t$address", true))
|
||||
val txtRecords = service.attributes // Map<String, ByteArray?>
|
||||
val shortNameBytes = txtRecords["shortname"]
|
||||
val idBytes = txtRecords["id"]
|
||||
|
||||
val shortName = shortNameBytes?.let { String(it, Charsets.UTF_8) }
|
||||
?: context.getString(R.string.meshtastic)
|
||||
val deviceId =
|
||||
idBytes?.let { String(it, Charsets.UTF_8) }?.replace("!", "")
|
||||
var displayName = shortName
|
||||
if (deviceId != null) {
|
||||
displayName += "_$deviceId"
|
||||
}
|
||||
addDevice(DeviceListEntry(displayName, "t$address", true))
|
||||
}
|
||||
|
||||
usb.forEach { (_, d) ->
|
||||
|
|
@ -160,10 +179,6 @@ class BTScanModel @Inject constructor(
|
|||
|
||||
private var scanJob: Job? = null
|
||||
|
||||
val selectedAddress get() = radioInterfaceService.getDeviceAddress()
|
||||
val selectedBluetooth: Boolean get() = selectedAddress?.getOrNull(0) == 'x'
|
||||
|
||||
// / Use the string for the NopInterface
|
||||
val selectedAddressFlow: StateFlow<String?> = radioInterfaceService.currentDeviceAddressFlow
|
||||
|
||||
val selectedNotNullFlow: StateFlow<String> = selectedAddressFlow
|
||||
|
|
|
|||
|
|
@ -41,16 +41,13 @@ class NetworkRepository @Inject constructor(
|
|||
.conflate()
|
||||
|
||||
val resolvedList: Flow<List<NsdServiceInfo>>
|
||||
get() = nsdManagerLazy.get().serviceList(SERVICE_TYPES, SERVICE_NAME)
|
||||
get() = nsdManagerLazy.get().serviceList(SERVICE_TYPE)
|
||||
.flowOn(dispatchers.io)
|
||||
.conflate()
|
||||
|
||||
companion object {
|
||||
// To find all available services use SERVICE_TYPE = "_services._dns-sd._udp"
|
||||
internal const val SERVICE_NAME = "Meshtastic"
|
||||
internal const val SERVICE_PORT = 4403
|
||||
private const val SERVICE_TYPE = "_meshtastic._tcp"
|
||||
internal val SERVICE_TYPES = setOf("_http._tcp", SERVICE_TYPE)
|
||||
|
||||
fun NsdServiceInfo.toAddressString() = buildString {
|
||||
append(@Suppress("DEPRECATION") host.toString().substring(1))
|
||||
|
|
|
|||
|
|
@ -24,27 +24,16 @@ import kotlinx.coroutines.cancel
|
|||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
import kotlin.coroutines.resume
|
||||
|
||||
internal fun NsdManager.serviceList(
|
||||
serviceTypes: Set<String>,
|
||||
serviceName: String,
|
||||
): Flow<List<NsdServiceInfo>> {
|
||||
val flows = serviceTypes.map { serviceType -> serviceList(serviceType, serviceName) }
|
||||
return combine(flows) { lists -> lists.flatMap { it } }
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
internal fun NsdManager.serviceList(
|
||||
serviceType: String,
|
||||
serviceName: String,
|
||||
): Flow<List<NsdServiceInfo>> = discoverServices(serviceType).mapLatest { serviceList ->
|
||||
serviceList
|
||||
.filter { it.serviceName.contains(serviceName) }
|
||||
.mapNotNull { resolveService(it) }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -81,6 +81,11 @@ fun DeviceListItem(
|
|||
contentDescription
|
||||
)
|
||||
},
|
||||
supportingContent = {
|
||||
if (device.isTCP) {
|
||||
Text(device.address)
|
||||
}
|
||||
},
|
||||
trailingContent = {
|
||||
if (selected) {
|
||||
Icon(
|
||||
|
|
|
|||
|
|
@ -705,4 +705,5 @@
|
|||
<string name="no_network_devices">No Network devices found.</string>
|
||||
<string name="no_usb_devices">No USB Serial devices found.</string>
|
||||
<string name="scroll_to_bottom">Scroll to bottom</string>
|
||||
<string name="meshtastic">Meshtastic</string>
|
||||
</resources>
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue