Repository navigation
Enhancement: Decouple WebRTC Call Engine from CallActivity into a Foreground Service #6929
Description
Currently, the entire WebRTC engine (Signaling, PeerConnectionFactory, socket management) is deeply coupled to the lifecycle of CallActivity. This 3,600+ line class acts as a God Object, handling everything from raw socket messages to UI visibility toggles. During my recent work on Telecom integration, it became evident that tying OS-level telecom events and active WebRTC sessions to an Activity lifecycle creates fragile edge cases.
Is your feature request related to a problem? Please describe.
Yes. Because the WebRTC connection lives in the UI layer (CallActivity), it is vulnerable to Android's Activity lifecycle events and causes severe performance bottlenecks. This causes several frustrating problems:
- Slow Call Loading & Missed Calls: The massive God Class makes the app progressively slower to initialize. When receiving a call, the UI has to inflate a huge layout, request permissions, and initialize the native WebRTC C++ library simultaneously. This latency can cause impatient callers to hang up before the receiving device manages to signal and respond to the call.
- Dropped Background Calls: If a user minimizes the app to multitask, Android's memory management can kill the Activity, dropping the call unexpectedly.
- Rotation Glitches & Wasted Resources: Rotating the phone destroys and recreates the Activity, requiring the device to do massive amounts of initialization work all over again. This requires fragile workarounds to keep video streams alive and causes temporary black screens or audio stutters.
- Missed Telecom Signals: Tying Core-Telecom events to specific Activity instances (like
CallNotificationActivityor a backgroundedCallActivity) creates race conditions. For example, pressing "Hang up" on a smartwatch might end the call in the system UI but fail to terminate the actual WebRTC session if the target Activity was destroyed.
Describe the solution you'd like
I propose an architectural refactor to extract the call business logic into a dedicated, UI-independent ForegroundService (leveraging our existing CallForegroundService) or a CallManager singleton.
The implementation would happen in phases:
- Phase 1 (State Extraction): Extract call state variables (
currentCallStatus, etc.) into a reactiveCallSessionManager(StateFlow). - Phase 2 (Decoupling WebRTC): Move
PeerConnectionFactory, WebSockets, and audio routing logic into a headlessCallEngine. The Activity will only passSurfaceViewRendererinstances to the engine for drawing. - Phase 3 (Service Migration): Move the execution of the
CallEngineintoCallForegroundService.CallActivitywill usebindService()to connect to the active call engine.
Describe alternatives you've considered
- Headless Fragment/Retained ViewModel: Moving the engine to a retained ViewModel that survives rotation. While this fixes the rotation issue, it does not solve the background-execution limits, as the ViewModel still dies when the Activity is fully destroyed by the OS memory manager.
Additional context
This refactoring will heavily reduce boilerplate in CallActivity (removing hundreds of runOnUiThread blocks) and separate business logic from the presentation layer. Decoupling the WebRTC logic from the View system is also a crucial stepping stone to make the ongoing Jetpack Compose migration of the call screens significantly easier.
(Note: The idea for this refactor originated during the Telecom fixes applied in PR #6821).
Activity