diff --git a/android/app/src/main/java/com/wzp/ui/call/CallViewModel.kt b/android/app/src/main/java/com/wzp/ui/call/CallViewModel.kt
index c38bdf7..4b9b34d 100644
--- a/android/app/src/main/java/com/wzp/ui/call/CallViewModel.kt
+++ b/android/app/src/main/java/com/wzp/ui/call/CallViewModel.kt
@@ -690,12 +690,12 @@ class CallViewModel : ViewModel(), WzpCallback {
val s = CallStats.fromJson(json)
lastCallDuration = s.durationSecs
_stats.value = s
- if (s.state != 0) {
- _callState.value = s.state
- }
// Track signal state changes for direct calling
if (s.state in 5..7) {
_signalState.value = s.state
+ // Don't update callState for signal-only states
+ } else if (s.state != 0) {
+ _callState.value = s.state
}
// Incoming call detection
if (s.state == 7) { // IncomingCall
diff --git a/crates/wzp-android/src/engine.rs b/crates/wzp-android/src/engine.rs
index ff7212d..53db861 100644
--- a/crates/wzp-android/src/engine.rs
+++ b/crates/wzp-android/src/engine.rs
@@ -97,6 +97,10 @@ pub(crate) struct EngineState {
/// QUIC transport handle — stored so stop_call() can close it immediately,
/// triggering relay-side leave + RoomUpdate broadcast.
pub quic_transport: Mutex