Skip to content

Enhancement: Decouple WebRTC Call Engine from CallActivity into a Foreground Service #6929

Open

Description

@thecyberd3m0n

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:

  1. 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.
  2. Dropped Background Calls: If a user minimizes the app to multitask, Android's memory management can kill the Activity, dropping the call unexpectedly.
  3. 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.
  4. Missed Telecom Signals: Tying Core-Telecom events to specific Activity instances (like CallNotificationActivity or a backgrounded CallActivity) 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 reactive CallSessionManager (StateFlow).
  • Phase 2 (Decoupling WebRTC): Move PeerConnectionFactory, WebSockets, and audio routing logic into a headless CallEngine. The Activity will only pass SurfaceViewRenderer instances to the engine for drawing.
  • Phase 3 (Service Migration): Move the execution of the CallEngine into CallForegroundService. CallActivity will use bindService() 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions