From 286685c0bd72a985fbeda959d74feafbf3d23bfe Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 3 Apr 2026 18:11:22 +0000 Subject: [PATCH] fix: stop ringback tone when Connecting state is skipped by StateFlow conflation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StateFlow is conflated — when the state transitions rapidly from Offering → Connecting → Connected, the collector may skip Connecting entirely and only see Connected. Since stopRingbackTone() was only called in the Connecting handler, the ringback tone would keep playing through the entire call. Fix: duplicate the ringing/notification cleanup in the Connected handler so the tone is always stopped regardless of which state the collector sees first. Also make switchToCallAudioMode() idempotent and clean up the previous ToneGenerator in startRingbackTone() to prevent leaks. https://claude.ai/code/session_01GWRdrVAa29BsDkv8R7Z3Y9 --- .../amethyst/service/call/CallAudioManager.kt | 2 ++ .../vitorpamplona/amethyst/service/call/CallController.kt | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/call/CallAudioManager.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/call/CallAudioManager.kt index 087914550..1823bfeb0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/call/CallAudioManager.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/call/CallAudioManager.kt @@ -107,6 +107,7 @@ class CallAudioManager( } fun startRingbackTone() { + stopRingbackTone() try { ringbackTone = ToneGenerator(AudioManager.STREAM_VOICE_CALL, 80).also { @@ -123,6 +124,7 @@ class CallAudioManager( } fun switchToCallAudioMode() { + if (audioManager.mode == AudioManager.MODE_IN_COMMUNICATION) return previousAudioMode = audioManager.mode audioManager.mode = AudioManager.MODE_IN_COMMUNICATION diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/call/CallController.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/call/CallController.kt index c1f63332f..1c86493d9 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/service/call/CallController.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/service/call/CallController.kt @@ -177,7 +177,15 @@ class CallController( } is CallState.Connected -> { + // Stop ringing/ringback in case the Connecting state + // was skipped due to StateFlow conflation (the value + // can change Offering → Connecting → Connected before + // the collector processes Connecting). + audioManager.stopRinging() + audioManager.stopRingbackTone() + withContext(Dispatchers.IO) { audioManager.switchToCallAudioMode() } audioManager.acquireProximityWakeLock() + NotificationUtils.cancelCallNotification(context) } is CallState.Ended -> {