Attach the runtime threads to the JVM, or nothing scans
Every scan on the phone failed with "bluetooth error: JNI call failed", which is the entire symptom: jni's Display for JniCall drops the source that says what actually went wrong. It was ThreadDetached. droidplug reaches the JVM through JavaVM::get_env(), which does not attach — it fails outright on any thread the JVM has never seen. Every BLE call in this app is made from a Tauri task, and Tauri's default runtime spawns plain Rust worker threads, so on Android no BLE call could ever have worked. This was invisible until it ran on hardware: the desktop build shares the code and does not care. Attaching inside the tasks would not have fixed it. A Tokio task can move to another worker at any .await, so the thread that starts a scan is not necessarily the one that polls it next — the attachment has to belong to the threads, not the work. on_thread_start is the hook that gets that right, and it covers the blocking pool too. Permanent rather than scoped, because a scoped attachment detaches at the end of the guard, which for a worker thread means after the first task it runs. Ordering is load-bearing at both ends. The JVM is stashed in initBtleplug, which runs before the super chain that starts us, so it is there when the runtime is built; and the runtime is installed before tauri::Builder, because async_runtime::set only affects later spawns. The scan log now carries the Debug form as well as Display. The chain read `Bluetooth(Other(JniCall(ThreadDetached)))` all along and would have named this in the first minute rather than the last. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -52,6 +52,12 @@ fn init_tracing() {
|
||||
pub fn run() {
|
||||
init_tracing();
|
||||
|
||||
// Before anything spawns: every BLE call is made from a Tauri task, and on
|
||||
// Android a task running on a thread the JVM has never seen cannot reach
|
||||
// droidplug at all. See `android::install_async_runtime`.
|
||||
#[cfg(target_os = "android")]
|
||||
android::install_async_runtime();
|
||||
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.manage(AppState::new())
|
||||
|
||||
Reference in New Issue
Block a user