fix(transport): improve BLE / TCP / USB reconnect and handshake resilience (#5196)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
James Rich 2026-04-20 12:34:16 -05:00 committed by GitHub
parent a90cb2d89e
commit f21d8af9ae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
14 changed files with 124 additions and 46 deletions

View file

@ -59,6 +59,7 @@ import org.meshtastic.app.node.metrics.getTracerouteMapOverlayInsets
import org.meshtastic.app.ui.MainScreen
import org.meshtastic.core.barcode.rememberBarcodeScanner
import org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
import org.meshtastic.core.network.repository.UsbRepository
import org.meshtastic.core.nfc.NfcScannerEffect
import org.meshtastic.core.resources.Res
import org.meshtastic.core.resources.channel_invalid
@ -91,6 +92,8 @@ import org.meshtastic.feature.node.metrics.TracerouteMapScreen
class MainActivity : ComponentActivity() {
private val model: UIViewModel by viewModel()
private val usbRepository: UsbRepository by inject()
/**
* Activity-lifecycle-aware client that binds to the mesh service. Note: This is used implicitly as it registers
* itself as a LifecycleObserver in its init block.
@ -166,6 +169,16 @@ class MainActivity : ComponentActivity() {
handleIntent(intent)
}
override fun onResume() {
super.onResume()
// Belt-and-suspenders for the Android 12+ attach-intent quirk: if the activity is
// resumed while a USB device is already attached (e.g. process restart, returning
// from another app), the manifest-declared attach intent may have already fired
// before UsbRepository was constructed. Re-poll deviceList here so the UI reflects
// reality without requiring the user to physically replug.
usbRepository.refreshState()
}
@Composable
private fun AppCompositionLocals(content: @Composable () -> Unit) {
CompositionLocalProvider(
@ -257,6 +270,11 @@ class MainActivity : ComponentActivity() {
UsbManager.ACTION_USB_DEVICE_ATTACHED -> {
Logger.d { "USB device attached" }
// Android 12+ delivers ACTION_USB_DEVICE_ATTACHED only to manifest-declared
// receivers, so the runtime-registered UsbBroadcastReceiver inside UsbRepository
// never sees this event. Forward it explicitly so the serialDevices StateFlow
// refreshes and the device shows up in the Connect → Serial tab.
usbRepository.refreshState()
showSettingsPage()
}