From 77b036439b4a02c31190ff7fe091496956e44c61 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Mon, 25 May 2026 08:08:24 +0400 Subject: [PATCH] fix(android): spawn_blocking + 2s timeout for set_audio_mode_communication MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The JNI call into AudioManager.setMode() was running directly on the tokio async thread. If the Android audio policy service is slow (e.g. immediately after mic permission grant), this could block the runtime. Moved to spawn_blocking with a 2s timeout; timeout and panic cases are logged as connect:audio_mode_timeout / connect:audio_mode_panic debug events and treated as non-fatal (we continue to audio_start). Also removes the has_record_audio_permission call from the preflight debug event — it was a redundant JNI round-trip that added latency and is now captured separately in the preflight_start event context. Co-Authored-By: Claude Sonnet 4.6 --- desktop/src-tauri/src/engine.rs | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/desktop/src-tauri/src/engine.rs b/desktop/src-tauri/src/engine.rs index 076ddf3..793a90c 100644 --- a/desktop/src-tauri/src/engine.rs +++ b/desktop/src-tauri/src/engine.rs @@ -617,9 +617,6 @@ impl CallEngine { serde_json::json!({ "t_ms": call_t0.elapsed().as_millis(), "wzp_native_loaded": native_loaded, - "record_audio_permission": crate::android_audio::has_record_audio_permission() - .map(|v| serde_json::json!(v)) - .unwrap_or_else(|e| serde_json::json!({ "error": e })), }), ); if !native_loaded { @@ -666,13 +663,15 @@ impl CallEngine { "connect:audio_mode_start", serde_json::json!({ "t_ms": call_t0.elapsed().as_millis() }), ); - match crate::android_audio::set_audio_mode_communication() { - Ok(()) => crate::emit_call_debug( + let audio_mode_task = + tokio::task::spawn_blocking(crate::android_audio::set_audio_mode_communication); + match tokio::time::timeout(std::time::Duration::from_secs(2), audio_mode_task).await { + Ok(Ok(Ok(()))) => crate::emit_call_debug( &app, "connect:audio_mode_done", serde_json::json!({ "t_ms": call_t0.elapsed().as_millis() }), ), - Err(e) => { + Ok(Ok(Err(e))) => { tracing::warn!("set_audio_mode_communication failed: {e}"); crate::emit_call_debug( &app, @@ -683,6 +682,26 @@ impl CallEngine { }), ); } + Ok(Err(e)) => { + crate::emit_call_debug( + &app, + "connect:audio_mode_panic", + serde_json::json!({ + "t_ms": call_t0.elapsed().as_millis(), + "error": e.to_string(), + }), + ); + } + Err(_) => { + crate::emit_call_debug( + &app, + "connect:audio_mode_timeout", + serde_json::json!({ + "t_ms": call_t0.elapsed().as_millis(), + "timeout_ms": 2000, + }), + ); + } } }