fix(ble): stop BLE scan on background and downgrade connection priority#5644
Conversation
Two battery-drain fixes: 1. ConnectionsScreen: Replace DisposableEffect + LaunchedEffect with LifecycleStartEffect for both BLE and network scanning. Scans now stop on ON_STOP (app backgrounded) and restart on ON_START, preventing continuous background BLE radio usage when the user leaves the app while on the Connections tab with auto-scan enabled. 2. BleRadioTransport: Downgrade from High to Balanced BLE connection priority 10 seconds after the initial handshake completes. High priority (~7.5 ms connection interval) is only needed for the initial config drain burst; sustaining it indefinitely drains battery on both phone and radio. Adds requestBalancedConnectionPriority() to the BleConnection interface with platform implementations (Android actual, JVM/iOS no-op stubs). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🖼️ Preview staleness check — advisoryThis PR modifies UI composables but does not update any
Changed UI files: What to check:
Adding previews checklist:
If this PR does not require preview updates (e.g., logic-only change, non-visual refactor), add the |
📄 Docs staleness check — advisoryThis PR modifies user-facing UI source files but does not update any page under
Changed source files: What to check:
New page checklist (if adding a new doc page):
If this PR does not require a doc update (e.g., internal refactor, bug fix, test change), add the
|
Extract requestHighPriorityAndScheduleDowngrade() from discoverServicesAndSetupCharacteristics() to bring function length back under the 60-line detekt threshold. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Reports of increased battery drain prompted an investigation into the BLE scanning and connection lifecycle. Two compounding issues were identified and fixed:
1. BLE scan continues when app is backgrounded
The Connections screen used
DisposableEffect(Unit)to stop scanning on composable disposal, but this only fires when the composable leaves composition (tab switch). When the user backgrounds the app while on the Connections tab with auto-scan enabled, the composable stays composed and the infinite-duration BLE scan continues in the background indefinitely.Fix: Replace
DisposableEffect+LaunchedEffectwithLifecycleStartEffect, which stops scanning onON_STOP(app backgrounded) and restarts onON_START. The same pattern is applied to network (NSD) scanning.2. High BLE connection priority never downgrades
Since #5222 (April 22),
BleRadioTransportrequestsPriority.High(~7.5 ms connection interval) on connect for faster initial config drain, but never downgrades back toBalanced(~30-50 ms). This increases battery draw on both the phone and the radio for the entire connection lifetime.Fix: Launch a delayed coroutine that downgrades to
Priority.Balanced30 seconds after the handshake completes. This gives ample time for the initial config burst while avoiding sustained high-frequency radio wakeups.Changes
ConnectionsScreen-- lifecycle-aware scan start/stop viaLifecycleStartEffectBleConnection-- newrequestBalancedConnectionPriority()interface methodKablePlatformSetup(Android/JVM/iOS) --requestBalancedConnectionPriority()expect/actual implementationsBleRadioTransport-- delayed priority downgrade afteronConnect()