fix(ble): enable Kable preConflate to prevent scan-callback ANRs (#6652)

This commit is contained in:
James Rich authored and GitHub committed 2026-08-12 19:13:59 +00:00
1 parent 9fa9f1e341
commit 212bc596e3
5 files changed
+22

No files matched your search

@@ -21,9 +21,16 @@ import com.juul.kable.AndroidPeripheral
import com.juul.kable.Peripheral
import com.juul.kable.PeripheralBuilder
import com.juul.kable.PooledThreadingStrategy
import com.juul.kable.ScannerBuilder
import com.juul.kable.toIdentifier
import org.meshtastic.core.model.util.anonymize
// Kable's default trySendBlocking can park the scan-callback (sometimes main) thread in dense BLE
// environments, causing ANRs; preConflate drops excess advertisements instead (kable#654).
internal actual fun ScannerBuilder.platformScanConfig() {
preConflate = true
}
/** Android's scanner filters on address in hardware, so Kable's `Filter.Address` works natively here. */
internal actual val supportsNativeAddressScanFilter: Boolean = true
@@ -75,6 +75,7 @@ open class KableBleScanner(private val loggingConfig: BleLoggingConfig) : BleSca
internal open fun advertisements(filter: KableScanFilter): Flow<KableScanResult> {
val scanner = Scanner {
platformScanConfig()
logging { applyConfig(loggingConfig) }
when (filter) {
KableScanFilter.None -> Unit
@@ -18,6 +18,10 @@ package org.meshtastic.core.ble
import com.juul.kable.Peripheral
import com.juul.kable.PeripheralBuilder
import com.juul.kable.ScannerBuilder
/** Platform-specific configuration for the Scanner builder (e.g. Android's `preConflate`). */
internal expect fun ScannerBuilder.platformScanConfig()
/**
* Whether Kable honours a scan filter on device address here. Android only: `Filter.Address` throws on Apple/JS, and
@@ -18,10 +18,15 @@ package org.meshtastic.core.ble
import com.juul.kable.Peripheral
import com.juul.kable.PeripheralBuilder
import com.juul.kable.ScannerBuilder
// Kable's `Filter.Address` throws UnsupportedOperationException on Apple.
internal actual val supportsNativeAddressScanFilter: Boolean = false
internal actual fun ScannerBuilder.platformScanConfig() {
// No-op: preConflate is Android-only.
}
/** No-op stubs for iOS target in core:ble. */
internal actual fun PeripheralBuilder.platformConfig(device: BleDevice, autoConnect: () -> Boolean) {
// No-op for stubs
@@ -18,8 +18,13 @@ package org.meshtastic.core.ble
import com.juul.kable.Peripheral
import com.juul.kable.PeripheralBuilder
import com.juul.kable.ScannerBuilder
import com.juul.kable.toIdentifier
internal actual fun ScannerBuilder.platformScanConfig() {
// No-op: preConflate is Android-only.
}
// Kable's btleplug backend evaluates scan filters with a hardcoded `address = null`, so an address filter matches
// nothing and the scan yields no advertisements at all.
internal actual val supportsNativeAddressScanFilter: Boolean = false