mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
fix(ble): never give up while user has device selected
The reconnect policy previously capped at 10 consecutive failures and emitted a permanent disconnect, which terminated the reconnect loop and required the user to manually re-select the device. BleRadioTransport is only ever instantiated for the user-selected address (verified via SharedRadioInterfaceService.startTransportLocked), so the only legitimate permanent-disconnect path is explicit close() owned by the service layer. - BleRadioTransport: pass maxFailures = Int.MAX_VALUE; backoff still caps at 60 s so battery impact remains bounded. - BleExceptionClassifier: flip UnmetRequirementException (BT off / permission missing) to non-permanent — both can resolve without the user re-selecting the device. - Test: replace the old 'gives up after DEFAULT_MAX_FAILURES' test with an inverted contract test that runs past the legacy threshold and asserts the policy never emits isPermanent=true on its own.
This commit is contained in:
parent
a6f3a6b4a5
commit
2137ef3410
3 changed files with 28 additions and 14 deletions
|
|
@ -26,7 +26,9 @@ import com.juul.kable.UnmetRequirementException
|
|||
/**
|
||||
* Classification of a BLE-layer exception for the transport layer to act on.
|
||||
*
|
||||
* @property isPermanent `true` if the condition won't resolve without user intervention (e.g. Bluetooth disabled).
|
||||
* @property isPermanent `true` if the condition cannot resolve without explicit user re-selection of the device.
|
||||
* Currently always `false` — all known BLE exceptions can resolve without user intervention (BT toggling, permission
|
||||
* grants, transient GATT errors). Reserved for future use.
|
||||
* @property gattStatus the platform GATT status code when available (Android-specific).
|
||||
* @property message a human-readable description of the failure.
|
||||
*/
|
||||
|
|
@ -50,6 +52,9 @@ fun Throwable.classifyBleException(): BleExceptionInfo? = when (this) {
|
|||
is GattRequestRejectedException ->
|
||||
BleExceptionInfo(isPermanent = false, message = "GATT request rejected (busy)")
|
||||
is UnmetRequirementException ->
|
||||
BleExceptionInfo(isPermanent = true, message = message ?: "Bluetooth LE unavailable")
|
||||
// Bluetooth disabled or runtime permission missing. Both can resolve without re-selecting the
|
||||
// device (user re-enables BT, or grants permission). Surface as transient so the transport keeps
|
||||
// retrying; UI can show a hint based on the message.
|
||||
BleExceptionInfo(isPermanent = false, message = message ?: "Bluetooth LE unavailable")
|
||||
else -> null
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue