fix: stop call ringing when Ended state is missed due to StateFlow conflation
The state collector in CallController was blocking on showIncomingCallNotification() which downloads the caller's profile picture over the network. Because StateFlow is conflated, if the call ended (peer hangup, reject, timeout) while the collector was suspended, the Ended→Idle transition would cause the Ended emission to be lost. Since cleanup/stopRinging only ran in the Ended handler, the ringtone and vibration would continue indefinitely. Two fixes: 1. Launch showIncomingCallNotification in a separate coroutine so the collector is never blocked by network I/O. 2. Add a safety-net Idle handler that stops ringing, ringback tone, and cancels the call notification. https://claude.ai/code/session_01NfyLNgR4d8yjnxaQJ6FUt5
This commit is contained in:
@@ -155,7 +155,13 @@ class CallController(
|
||||
when (state) {
|
||||
is CallState.IncomingCall -> {
|
||||
withContext(Dispatchers.IO) { audioManager.startRinging() }
|
||||
showIncomingCallNotification(state.callerPubKey)
|
||||
// Launch notification in a separate coroutine so that
|
||||
// long-running network I/O (profile picture download)
|
||||
// does not block the state collector. StateFlow is
|
||||
// conflated — if the collector is suspended when the
|
||||
// state transitions Ended → Idle, the Ended emission
|
||||
// is lost and cleanup/stopRinging never runs.
|
||||
scope.launch { showIncomingCallNotification(state.callerPubKey) }
|
||||
}
|
||||
|
||||
is CallState.Offering -> {
|
||||
@@ -178,7 +184,14 @@ class CallController(
|
||||
cleanup()
|
||||
}
|
||||
|
||||
else -> {}
|
||||
is CallState.Idle -> {
|
||||
// Safety net: ensure ringing and notifications are
|
||||
// stopped even if the Ended state was missed due to
|
||||
// StateFlow conflation.
|
||||
audioManager.stopRinging()
|
||||
audioManager.stopRingbackTone()
|
||||
NotificationUtils.cancelCallNotification(context)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user