Make the Android BLE backend fail loudly and recoverably

Three defects on the path between MainActivity and the scan loop, all of
which presented as "no trainer found".

initBtleplug ran after super.onCreate, which is a race rather than a
clean ordering bug: the super chain dispatches Rust.create(), and tao's
ndk_glue spawns a thread to run `run()` on. That thread builds the
AppState and starts the scan loop concurrently. Reaching btleplug first
hits droidplug's global_adapter(), which is an `expect` — the scan task
panics and scanning is dead for the process, silently and only on some
phones. Initialising before super.onCreate means the race cannot be lost.

The same panic was reachable without any race, because init failure was
logged and shrugged off while every later call still went through to
`expect`. Failing soft is right; it just needed READY, so the call sites
can produce an ordinary "no adapter" instead of taking the task down
(NFR-4). MainActivity retries the init on resume, which is idempotent, so
a rider who launched with Bluetooth off recovers by going to Settings.

Neither of those covers a radio the rider switches off, which btleplug
does not model at all: getDefaultAdapter() returns a disabled adapter
whose scans just find nothing. MainActivity now watches
ACTION_STATE_CHANGED — the quick-settings shade never fires onResume —
and pushes the state to Rust, with requestBluetoothEnable coming back the
other way so the connection screen can offer the system dialog rather
than describing an empty room. Tri-state on purpose: unknown is not off,
or a rider with a working radio gets told to switch it on at launch.

Also: the adapter hint told Android riders to check BlueZ.

Verified on debug and release APKs for aarch64. Release matters
separately here — every one of these classes is reached only by name over
JNI, so R8 would strip or rename the lot and the failure would appear
only in a shipped build.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-05 20:06:03 +02:00
co-authored by Claude Opus 5
parent 8fcee06d84
commit aa99b83c40
6 changed files with 234 additions and 11 deletions
+1
View File
@@ -98,6 +98,7 @@ pub fn run() {
commands::disconnect_device,
commands::forget_device,
commands::trainer_controllable,
commands::request_bluetooth_enable,
// controller
commands::controller_status,
commands::connect_controller,