Skip to content

fix(android-ble): prevent ANR by moving blocking Bluetooth calls off main thread - #1186

Merged
torlando-tech merged 2 commits into
mainfrom
seer/fix/ble-anr
Oct 9, 2026
Merged

torlando-tech merged 2 commits into
mainfrom
seer/fix/ble-anr

Conversation

@sentry

@sentry sentry Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

This PR addresses a Background ANR issue (COLUMBA-DY) where blocking Android Bluetooth framework calls were executed on the main thread. On Android 13+, calls like startScan, stopScan, discoverServices, requestConnectionPriority, advertising, and GATT server responses can block synchronously for extended periods when the Bluetooth stack is congested, leading to ANRs.

The solution involves:

  1. Introducing BleDispatchers.ble: A dedicated single-threaded CoroutineDispatcher (Dispatchers.IO.limitedParallelism(1)) to handle all blocking Bluetooth framework calls. This maintains the serialized execution semantics previously provided by the main thread but prevents blocking the UI.
  2. Migrating calls: All withContext(Dispatchers.Main) blocks wrapping Bluetooth framework calls in BleScanner, BleGattClient, BleAdvertiser, and BleGattServer have been replaced with withContext(bleDispatcher).
  3. Improving testability: The bleDispatcher is now injected via the constructor in these classes, allowing tests to provide a TestDispatcher (e.g., UnconfinedTestDispatcher) for predictable timing and control, addressing feedback from code review.

This change prevents ANRs by ensuring that slow Bluetooth operations do not freeze the main thread, while preserving the intended sequential execution of these calls and improving test isolation.

Fixes COLUMBA-DY

@sentry <feedback>: Autofix iterates on these changes
@sentry stop iterating: Autofix stops iterating on this run

This PR was automatically generated by Sentry. You can adjust this setting at any time.

@greptile-apps

greptile-apps Bot commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Moves Bluetooth framework calls off the main thread.

The PR appears safe to merge; the test-timing concern is addressed without changing the production dispatcher.

Summary

This PR moves blocking Bluetooth calls off the main thread. The latest changes make the dispatcher injectable and update tests to control those calls.

  • Production keeps the shared Dispatchers.IO.limitedParallelism(1) dispatcher.
  • The previous test-timing finding is addressed.
  • No new actionable issues were found.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Caller[BLE caller] --> Classes[Scanner, advertiser, GATT client and server]
  Classes --> Dispatcher[Injected BLE dispatcher]
  Dispatcher --> Default[Production: serialized IO work]
  Dispatcher --> Tests[Tests: controlled test dispatcher]
  Default --> Bluetooth[Android Bluetooth calls]
Loading

Reviews (2) · Last reviewed commit: "fix(ble): move blocking Bluetooth calls ..." · Reviewed by Greptile

@codecov

codecov Bot commented Oct 7, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@torlando-tech
torlando-tech merged commit a58e4ca into main Oct 9, 2026
15 checks passed
@torlando-tech
torlando-tech deleted the seer/fix/ble-anr branch October 9, 2026 18:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant