303e68331a
When a peer rejects a group call, CallManager updated its state but never notified CallController to dispose the peer's PeerSession. This caused two issues: 1. The rejected peer's PeerConnection lingered in HAVE_LOCAL_OFFER state until the entire call ended (resource leak visible as "disposing 2 peer sessions" when only 1 should exist). 2. In onPeerDisconnected, the allDisconnected check required ALL sessions to be CLOSED. The stale session blocked this check, preventing automatic hangup when ICE failed — meaning the remote peer never received a hangup event and kept ringing. Fix: invoke onPeerLeft when a peer rejects in Offering/Connecting/Connected states, and make onPeerDisconnected treat sessions without a remote description as inactive. https://claude.ai/code/session_01UXaFKmHVPDyTzfHL8fkSw1