mirror of
https://git.quad4.io/RNS-Things/MeshChatX.git
synced 2026-04-26 19:35:38 +00:00
feat(android): update meshchat_wrapper with server loop control and improve error handling for Android notification bridge
This commit is contained in:
@@ -3,6 +3,11 @@
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
import threading
|
||||
|
||||
# Prevents a second meshchat main() if Java starts two threads (e.g. activity edge cases).
|
||||
_server_loop_lock = threading.Lock()
|
||||
_server_loop_active = False
|
||||
|
||||
|
||||
def _ensure_android_reticulum_config(reticulum_config_dir):
|
||||
@@ -67,6 +72,12 @@ def _patch_aiohttp_run_app_for_android():
|
||||
|
||||
|
||||
def start_server(port=8000, app_files_dir=None):
|
||||
global _server_loop_active
|
||||
with _server_loop_lock:
|
||||
if _server_loop_active:
|
||||
print("meshchat_wrapper: start_server ignored (server loop already active)")
|
||||
return
|
||||
_server_loop_active = True
|
||||
try:
|
||||
storage_dir = None
|
||||
reticulum_config_dir = None
|
||||
@@ -91,10 +102,14 @@ def start_server(port=8000, app_files_dir=None):
|
||||
signal.signal = _safe_signal
|
||||
asyncio_signal_patch = _patch_asyncio_signal_handlers_for_android()
|
||||
aiohttp_run_app_patch = _patch_aiohttp_run_app_for_android()
|
||||
from meshchatx.android_push_bridge import install_websocket_hook
|
||||
from meshchatx.meshchat import ReticulumMeshChat, main
|
||||
|
||||
install_websocket_hook(ReticulumMeshChat)
|
||||
try:
|
||||
from meshchatx.android_push_bridge import install_websocket_hook
|
||||
|
||||
install_websocket_hook(ReticulumMeshChat)
|
||||
except Exception as hook_exc:
|
||||
print(f"meshchat_wrapper: install_websocket_hook skipped: {hook_exc}")
|
||||
|
||||
sys.argv = [
|
||||
"meshchat",
|
||||
@@ -125,3 +140,6 @@ def start_server(port=8000, app_files_dir=None):
|
||||
|
||||
traceback.print_exc()
|
||||
raise
|
||||
finally:
|
||||
with _server_loop_lock:
|
||||
_server_loop_active = False
|
||||
|
||||
@@ -73,6 +73,42 @@ def _notify_java(title: str, body: str, dedupe_hex: str | None) -> None:
|
||||
logger.debug("showInboundMessage failed: %s", exc)
|
||||
|
||||
|
||||
def _notify_incoming_call_java(caller_name: str, dedupe_hex: str | None) -> None:
|
||||
try:
|
||||
from com.meshchatx import AndroidNotificationBridge # type: ignore[import-not-found,import-untyped]
|
||||
except Exception as exc:
|
||||
logger.debug("Android notification bridge unavailable: %s", exc)
|
||||
return
|
||||
try:
|
||||
AndroidNotificationBridge.showIncomingCall(caller_name, dedupe_hex)
|
||||
except Exception as exc:
|
||||
logger.debug("showIncomingCall failed: %s", exc)
|
||||
|
||||
|
||||
def _notify_missed_call_java(title: str, body: str, dedupe_hex: str | None) -> None:
|
||||
try:
|
||||
from com.meshchatx import AndroidNotificationBridge # type: ignore[import-not-found,import-untyped]
|
||||
except Exception as exc:
|
||||
logger.debug("Android notification bridge unavailable: %s", exc)
|
||||
return
|
||||
try:
|
||||
AndroidNotificationBridge.showMissedCall(title, body, dedupe_hex)
|
||||
except Exception as exc:
|
||||
logger.debug("showMissedCall failed: %s", exc)
|
||||
|
||||
|
||||
def _cancel_incoming_call_notification_java() -> None:
|
||||
try:
|
||||
from com.meshchatx import AndroidNotificationBridge # type: ignore[import-not-found,import-untyped]
|
||||
except Exception as exc:
|
||||
logger.debug("Android notification bridge unavailable: %s", exc)
|
||||
return
|
||||
try:
|
||||
AndroidNotificationBridge.cancelIncomingCallNotification()
|
||||
except Exception as exc:
|
||||
logger.debug("cancelIncomingCallNotification failed: %s", exc)
|
||||
|
||||
|
||||
def _after_websocket_broadcast(data: object) -> None:
|
||||
if not isinstance(data, str):
|
||||
return
|
||||
@@ -82,6 +118,32 @@ def _after_websocket_broadcast(data: object) -> None:
|
||||
return
|
||||
if not isinstance(payload, dict):
|
||||
return
|
||||
t = payload.get("type")
|
||||
if t in ("telephone_call_ended", "telephone_call_established"):
|
||||
_cancel_incoming_call_notification_java()
|
||||
return
|
||||
if t == "telephone_ringing":
|
||||
ch = payload.get("remote_identity_hash")
|
||||
name = (payload.get("remote_identity_name") or "").strip() or "Mesh"
|
||||
ded = ch if isinstance(ch, str) and len(ch) >= 8 else None
|
||||
_notify_incoming_call_java(name, ded)
|
||||
return
|
||||
if t == "telephone_missed_call":
|
||||
sender = (payload.get("remote_identity_name") or "").strip() or "Mesh"
|
||||
ch = payload.get("remote_identity_hash")
|
||||
h = ch if isinstance(ch, str) and len(ch) >= 8 else None
|
||||
if sender and sender != "Mesh":
|
||||
title = "Missed call"
|
||||
body = f"Missed call from {sender}"
|
||||
elif isinstance(ch, str) and ch:
|
||||
short_h = f"{ch[:6]}" if len(ch) > 6 else ch
|
||||
title = "Missed call"
|
||||
body = f"From {short_h}..."
|
||||
else:
|
||||
title = "Missed call"
|
||||
body = "Missed call"
|
||||
_notify_missed_call_java(title, body, h)
|
||||
return
|
||||
pair = lxmf_delivery_notification_text(payload)
|
||||
if not pair:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user