865c71e0e2
Bug fixes: - Fix RemoteVideoMonitor killing group monitor job when primary track switches - Add mutex protection to CallManager.initiateCall() to prevent state races - Fix ICE restart offer never being sent to remote peer (was immediately replaced by a second offer from onRenegotiationNeeded) - Fix duplicate duration timer in PiP connected call UI - Fix error snackbar dismiss button not clearing the error - Make PeerSessionManager thread-safe with synchronized blocks (accessed from WebRTC native threads and coroutine dispatchers concurrently) - Make CallManager event handlers private (only called from onSignalingEvent) Improvements: - Replace fragile ICE candidate regex parsing with kotlinx.serialization JSON - Respect DND/silent mode: only ring in NORMAL mode, only vibrate in VIBRATE - Signal camera-off to remote peer by removing video track sender (instead of sending frozen/black frame) - Clear CallSessionBridge on AccountViewModel.onCleared() to prevent stale references on account switch - Custom TURN servers now replace defaults (instead of appending) so credentials can be rotated without an app update New features: - Front/back camera switch button (visible when video is enabled) - Network transition handling: ConnectivityManager.NetworkCallback triggers ICE restart on all peers when network changes (WiFi/cellular handoff) https://claude.ai/code/session_01JHn7skAibTrkVqsoWutgYe