mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
refactor(transport): complete transport architecture overhaul — extract callback, wire BleReconnectPolicy, fix safety issues (#5080)
This commit is contained in:
parent
962c619c4c
commit
e85300531e
64 changed files with 1184 additions and 1018 deletions
|
|
@ -54,8 +54,8 @@ open class ScannerViewModel(
|
|||
private val dispatchers: org.meshtastic.core.di.CoroutineDispatchers,
|
||||
private val bleScanner: org.meshtastic.core.ble.BleScanner? = null,
|
||||
) : ViewModel() {
|
||||
private val _showMockInterface = MutableStateFlow(false)
|
||||
val showMockInterface: StateFlow<Boolean> = _showMockInterface.asStateFlow()
|
||||
private val _showMockTransport = MutableStateFlow(false)
|
||||
val showMockTransport: StateFlow<Boolean> = _showMockTransport.asStateFlow()
|
||||
|
||||
private val _errorText = MutableStateFlow<String?>(null)
|
||||
val errorText: StateFlow<String?> = _errorText.asStateFlow()
|
||||
|
|
@ -68,7 +68,7 @@ open class ScannerViewModel(
|
|||
private var scanJob: kotlinx.coroutines.Job? = null
|
||||
|
||||
init {
|
||||
_showMockInterface.value = radioInterfaceService.isMockInterface()
|
||||
_showMockTransport.value = radioInterfaceService.isMockTransport()
|
||||
}
|
||||
|
||||
fun startBleScan() {
|
||||
|
|
@ -77,25 +77,26 @@ open class ScannerViewModel(
|
|||
isBleScanningState.value = true
|
||||
scannedBleDevices.value = emptyMap()
|
||||
|
||||
scanJob = viewModelScope.launch {
|
||||
try {
|
||||
bleScanner
|
||||
.scan(
|
||||
timeout = kotlin.time.Duration.INFINITE,
|
||||
serviceUuid = org.meshtastic.core.ble.MeshtasticBleConstants.SERVICE_UUID,
|
||||
)
|
||||
.flowOn(dispatchers.io)
|
||||
.collect { device ->
|
||||
if (!scannedBleDevices.value.containsKey(device.address)) {
|
||||
scannedBleDevices.update { current -> current + (device.address to device) }
|
||||
scanJob =
|
||||
viewModelScope.launch {
|
||||
try {
|
||||
bleScanner
|
||||
.scan(
|
||||
timeout = kotlin.time.Duration.INFINITE,
|
||||
serviceUuid = org.meshtastic.core.ble.MeshtasticBleConstants.SERVICE_UUID,
|
||||
)
|
||||
.flowOn(dispatchers.io)
|
||||
.collect { device ->
|
||||
if (!scannedBleDevices.value.containsKey(device.address)) {
|
||||
scannedBleDevices.update { current -> current + (device.address to device) }
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
|
||||
co.touchlab.kermit.Logger.w(e) { "BLE scan failed" }
|
||||
} finally {
|
||||
isBleScanningState.value = false
|
||||
} catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
|
||||
co.touchlab.kermit.Logger.w(e) { "BLE scan failed" }
|
||||
} finally {
|
||||
isBleScanningState.value = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stopBleScan() {
|
||||
|
|
@ -105,7 +106,7 @@ open class ScannerViewModel(
|
|||
}
|
||||
|
||||
private val discoveredDevicesFlow =
|
||||
showMockInterface
|
||||
showMockTransport
|
||||
.flatMapLatest { showMock -> getDiscoveredDevicesUseCase.invoke(showMock) }
|
||||
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000), null)
|
||||
|
||||
|
|
|
|||
|
|
@ -167,17 +167,19 @@ fun ConnectionsScreen(
|
|||
Spacer(modifier = Modifier.height(4.dp))
|
||||
val uiState =
|
||||
when {
|
||||
connectionState is ConnectionState.Connected && ourNode != null -> 2
|
||||
connectionState is ConnectionState.Connected && ourNode != null ->
|
||||
ConnectionUiState.CONNECTED_WITH_NODE
|
||||
|
||||
connectionState is ConnectionState.Connected ||
|
||||
connectionState == ConnectionState.Connecting ||
|
||||
selectedDevice != NO_DEVICE_SELECTED -> 1
|
||||
selectedDevice != NO_DEVICE_SELECTED -> ConnectionUiState.CONNECTING
|
||||
|
||||
else -> 0
|
||||
else -> ConnectionUiState.NO_DEVICE
|
||||
}
|
||||
|
||||
Crossfade(targetState = uiState, label = "connection_state") { state ->
|
||||
when (state) {
|
||||
2 ->
|
||||
ConnectionUiState.CONNECTED_WITH_NODE ->
|
||||
ConnectedDeviceContent(
|
||||
ourNode = ourNode,
|
||||
regionUnset = regionUnset,
|
||||
|
|
@ -191,7 +193,7 @@ fun ConnectionsScreen(
|
|||
},
|
||||
)
|
||||
|
||||
1 ->
|
||||
ConnectionUiState.CONNECTING ->
|
||||
ConnectingDeviceContent(
|
||||
connectionState = connectionState,
|
||||
selectedDevice = selectedDevice,
|
||||
|
|
@ -208,7 +210,9 @@ fun ConnectionsScreen(
|
|||
}
|
||||
|
||||
var selectedDeviceType by remember { mutableStateOf(DeviceType.BLE) }
|
||||
LaunchedEffect(Unit) { DeviceType.fromAddress(selectedDevice)?.let { selectedDeviceType = it } }
|
||||
LaunchedEffect(selectedDevice) {
|
||||
DeviceType.fromAddress(selectedDevice)?.let { selectedDeviceType = it }
|
||||
}
|
||||
|
||||
val supportedDeviceTypes = scanModel.supportedDeviceTypes
|
||||
|
||||
|
|
@ -369,3 +373,15 @@ private fun NoDeviceContent() {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
/** Visual state for the connection screen's [Crossfade] animation. */
|
||||
private enum class ConnectionUiState {
|
||||
/** No device is selected. */
|
||||
NO_DEVICE,
|
||||
|
||||
/** A device is selected or we are actively connecting. */
|
||||
CONNECTING,
|
||||
|
||||
/** Connected with node info available. */
|
||||
CONNECTED_WITH_NODE,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ import org.meshtastic.core.resources.connecting
|
|||
import org.meshtastic.core.resources.disconnect
|
||||
import org.meshtastic.core.ui.theme.StatusColors.StatusRed
|
||||
|
||||
/**
|
||||
* Displays the currently connecting (or connected) device with its name, address, connection status, and a disconnect
|
||||
* button.
|
||||
*/
|
||||
@Composable
|
||||
fun ConnectingDeviceInfo(
|
||||
connectionState: ConnectionState,
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class ScannerViewModelTest {
|
|||
|
||||
@BeforeTest
|
||||
fun setUp() {
|
||||
every { radioInterfaceService.isMockInterface() } returns false
|
||||
every { radioInterfaceService.isMockTransport() } returns false
|
||||
every { radioInterfaceService.currentDeviceAddressFlow } returns MutableStateFlow(null)
|
||||
every { radioInterfaceService.supportedDeviceTypes } returns emptyList()
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue