Merge pull request #2163 from vitorpamplona/claude/fix-webrtc-ringing-bug-pNe68

Fix audio cleanup and call state handling on Activity destroy
This commit is contained in:
Vitor Pamplona
2026-04-06 15:30:45 -04:00
committed by GitHub
3 changed files with 37 additions and 5 deletions
@@ -118,8 +118,11 @@ class CallAudioManager(
} }
fun stopRingbackTone() { fun stopRingbackTone() {
ringbackTone?.stopTone() try {
ringbackTone?.release() ringbackTone?.stopTone()
ringbackTone?.release()
} catch (_: Exception) {
}
ringbackTone = null ringbackTone = null
} }
@@ -355,7 +358,10 @@ class CallAudioManager(
} }
private fun stopRingtone() { private fun stopRingtone() {
ringtone?.stop() try {
ringtone?.stop()
} catch (_: Exception) {
}
ringtone = null ringtone = null
} }
@@ -376,7 +382,10 @@ class CallAudioManager(
} }
private fun stopVibration() { private fun stopVibration() {
vibrator?.cancel() try {
vibrator?.cancel()
} catch (_: Exception) {
}
vibrator = null vibrator = null
} }
} }
@@ -207,8 +207,28 @@ class CallActivity : AppCompatActivity() {
} }
} }
@OptIn(DelicateCoroutinesApi::class)
override fun onDestroy() { override fun onDestroy() {
unregisterPipReceiver() unregisterPipReceiver()
// Safety net: if the Activity is destroyed while a call is still
// ringing/offering, ensure the call is hung up so audio stops.
val manager = ActiveCallHolder.callManager
when (manager?.state?.value) {
is CallState.IncomingCall -> {
GlobalScope.launch { manager.rejectCall() }
}
is CallState.Offering,
is CallState.Connecting,
is CallState.Connected,
-> {
GlobalScope.launch { manager.hangup() }
}
else -> {}
}
super.onDestroy() super.onDestroy()
} }
@@ -505,9 +505,12 @@ class CallManager(
} }
} }
// Transition immediately so the UI stops ringing/ringback before
// the (potentially slow) signing + relay publish completes.
transitionToEnded(callId, peerPubKeys, EndReason.HANGUP)
val result = factory.createGroupHangup(peerPubKeys, callId, signer = signer) val result = factory.createGroupHangup(peerPubKeys, callId, signer = signer)
result.wraps.forEach { publishEvent(it) } result.wraps.forEach { publishEvent(it) }
transitionToEnded(callId, peerPubKeys, EndReason.HANGUP)
} }
fun onPeerHangup(event: CallHangupEvent) { fun onPeerHangup(event: CallHangupEvent) {