From 2460e810d6b6a317edb25628f84b808e26c32d4e Mon Sep 17 00:00:00 2001 From: evgeny Date: Thu, 29 Oct 2026 13:59:14 +0100 Subject: [PATCH] Document asynchronous BLE detach and report probe cleanup failures --- .../java/com/utun/chat/BlePeerProbe.kt | 18 +++++++++++++++--- tools/chatgui-android/jni_bridge/android_ble.h | 3 +++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/tools/chatgui-android/app/src/androidTest/java/com/utun/chat/BlePeerProbe.kt b/tools/chatgui-android/app/src/androidTest/java/com/utun/chat/BlePeerProbe.kt index a01fa929..2b793cae 100644 --- a/tools/chatgui-android/app/src/androidTest/java/com/utun/chat/BlePeerProbe.kt +++ b/tools/chatgui-android/app/src/androidTest/java/com/utun/chat/BlePeerProbe.kt @@ -7,6 +7,7 @@ import android.os.Bundle import android.os.SystemClock import com.utun.chat.data.BleRadio import com.utun.chat.data.NativeLib +import com.utun.chat.data.LogManager import com.utun.chat.headless.HeadlessService /** Только ручной тест на физическом устройстве: временный echo общего C API. */ @@ -24,10 +25,21 @@ class BlePeerProbe : Instrumentation() { Thread.sleep(1000) // Дождаться обычной политики SERVICE_STARTED перед тестовой. check(BleRadio.permitted()) { "Bluetooth permissions missing" } check(BleRadio.nativeConfigure(15 or if (args.getString("initiator") == "true") 16 else 0)) { "configure refused" } - Thread.sleep((args.getString("seconds") ?: "100").toLong() * 1000) + val seconds = (args.getString("seconds") ?: "100").toLong() + require(seconds in 1..600) { "seconds must be in 1..600" } + Thread.sleep(seconds * 1000) result.putString("stream", "BLE echo session completed; verify desktop RESULT\n") - } catch (e: Exception) { code = Activity.RESULT_CANCELED; result.putString("stream", "BLE FAIL: $e\n") } - finally { BleRadio.applySettings() } + } catch (e: Exception) { + code = Activity.RESULT_CANCELED; result.putString("stream", "BLE FAIL: $e\n") + LogManager.addLog("ERROR", "discovery", "BLE probe failed: $e") + } finally { + try { BleRadio.applySettings() } + catch (e: Exception) { + code = Activity.RESULT_CANCELED + result.putString("stream", result.getString("stream", "") + "BLE settings restore failed: $e\n") + LogManager.addLog("ERROR", "discovery", "BLE probe settings restore failed: $e") + } + } finish(code, result) } } diff --git a/tools/chatgui-android/jni_bridge/android_ble.h b/tools/chatgui-android/jni_bridge/android_ble.h index 711c5ac3..8d4b2d78 100644 --- a/tools/chatgui-android/jni_bridge/android_ble.h +++ b/tools/chatgui-android/jni_bridge/android_ble.h @@ -6,5 +6,8 @@ struct ble_transport; /* Заимствованный общий C handle либо NULL. Только поток ядра, действителен до detach. * TX/RX — ble_tx_put/ble_rx_get; потребитель освобождает извлечённые ll_entry. */ struct ble_transport* android_ble_transport(void); +/* Worker: уничтожить transport и mailbox до instance/uasync; повторный вызов безопасен. + * Android SDK stop асинхронно передаётся HandlerThread: поздние события отбрасываются по generation, + * неудачные SDK releases остаются у Kotlin cleanup owner до успешного повтора. */ void android_ble_detach(void); #endif