Skip to content

[FCE-3435] Handle common VoIP patterns#67

Open
Magmusacy wants to merge 24 commits into
FCE-3434from
FCE-3435
Open

[FCE-3435] Handle common VoIP patterns#67
Magmusacy wants to merge 24 commits into
FCE-3434from
FCE-3435

Conversation

@Magmusacy

@Magmusacy Magmusacy commented Jul 16, 2026

Copy link
Copy Markdown

Call setup correctness

  • Answer→connect handshake (iOS + Android) — the answer action is parked and
    fulfilled/failed once media actually connects (FulfillRequestManager), instead
    of instant-fulfill, so a failed room-join can't leave a phantom "connected" call.
  • Connecting state before streaming media is up.
  • Configurable timeouts — incoming / outgoing / fulfill-answer, from
    manifest / Info.plist (Voip*Timeout, defaults 45 / 60 / 10 s).

Call lifecycle

  • End reasons (CallEndedReason, iOS + Android) mapped to CXCallEndedReason /
    DisconnectCause — correct missed vs declined vs remote-ended.
  • Hold / resume (+ fix held-notification duration reset on Android).
  • Call waiting — a second incoming call while one is active (iOS + Android
    native).
  • iOS Recents + call-intent redial (incl. deprecated call-intent handling).

Identity & polish

  • Caller avatar / app-icon capabilities — downloaded avatar on the Android
    CallStyle notification + full-screen UI; customizable notification small icon
    (VoipNotificationIcon); avatarUrl carried in the incoming payload.
  • Outgoing ringback (dialtone) — Android ToneGenerator, iOS synthesized tone.

Mute

  • System→app mute surfaced to JS via onMuteChanged (CallKit
    performSetMutedCallAction / Telecom mute state), so a headset/OS/CarPlay mute
    can be mirrored onto the WebRTC mic.

Fixes / cleanup

  • Only emit telecomActionPerformed on Android; drop unused
    endpoint/available/mute jobs in CallManager; useTelecom Platform.select
    refactor.

Magmusacy and others added 19 commits July 10, 2026 15:56
They were assigned but never read or cancelled — structured
concurrency already tears them down with the parent addCall scope,
so launching without storing a reference is equivalent.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Telecom.ts already guards every function body with an Android check, so
useTelecom's own Platform.select + emptyResult was defense duplicated on
top of defense already in place. useCallKit keeps its split since CallKit
has no Android native module to fall back to.
INStartAudioCallIntent/INStartVideoCallIntent are deprecated in favour of
INStartCallIntent, but the Phone app's Recents redial still delivers them.
Matching only INStartCallIntent made handleContinueUserActivity return NO
for those, silently dropping the intent so tapping a Recents entry never
started a call.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@linear

linear Bot commented Jul 16, 2026

Copy link
Copy Markdown

FCE-3435

@Magmusacy
Magmusacy changed the base branch from master to feature/voip-calls July 16, 2026 14:21
@Magmusacy
Magmusacy changed the base branch from feature/voip-calls to FCE-3434 July 16, 2026 14:21

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR expands the React Native WebRTC module’s native VoIP integration to better match common system call UX on iOS (CallKit) and Android (Telecom), including delayed “answer→connected” fulfillment, connecting/hold states, call waiting, ended reasons, and optional caller identity polish (handle, avatar, ringback).

Changes:

  • Adds a cross-platform “parked answer” handshake (requestId-based) plus outgoing “connected” reporting, hold state controls, and ended-reason mapping.
  • Introduces call intent handling (iOS Recents redial), call waiting flows, and configurable timeouts (Info.plist / Android manifest meta-data).
  • Improves Android call UI/notifications with connecting/held variants, optional avatar download, and ringback tone playback.

Reviewed changes

Copilot reviewed 33 out of 33 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/VoIP.ts Adds higher-level, cross-platform VoIP helpers (call intent, fulfill/fail answer, outgoing connected, hold state).
src/useVoIPEvents.ts Extends JS event surface (requestId-based answer, ended reason, held/mute changes, call intent, waiting-call declined).
src/useTelecom.ts Updates Telecom hook API to support ended reasons and hold state.
src/useCallKit.ts Updates CallKit hook API to support ended reasons and hold state.
src/Telecom.ts Extends Android bridge API (handle, answered fulfillment, hold, ended reasons, pending answer requestId).
src/index.ts Re-exports new VoIP/CallKit/Telecom APIs and types.
src/CallKit.ts Extends iOS bridge API (handle, answered fulfillment, outgoing connected, hold, ended reasons, pending answer requestId).
ios/RCTWebRTC/WebRTCModule+PushKit.m Adds push events for waiting-call declined and call intent; exports pending call intent getters/clearers.
ios/RCTWebRTC/WebRTCModule+CallKit.m Adds CallKit bridging for handle, ended reasons, fulfill/fail answer, outgoing connected, hold, pending answer requestId.
ios/RCTWebRTC/VoipManager.m Adds call intent buffering and call waiting payload buffering/dispatch; forwards handle from payload.
ios/RCTWebRTC/VoipManager.h Exposes pending call intent and call-waiting related callbacks/APIs.
ios/RCTWebRTC/FulfillRequestManager.m Implements iOS fulfill/cancel/timeout request tracking for parked CallKit answer actions.
ios/RCTWebRTC/FulfillRequestManager.h Declares iOS fulfill request manager interface and result enum.
ios/RCTWebRTC/DialtonePlayer.m Implements iOS ringback tone synthesis/playback for outgoing calls.
ios/RCTWebRTC/DialtonePlayer.h Declares iOS ringback player interface.
ios/RCTWebRTC/CallKitManager.m Adds call waiting, timeouts, parked answer fulfillment, ended reasons, hold state, and ringback integration.
ios/RCTWebRTC/CallKitManager.h Updates CallKit manager interface for new callbacks/state and call-waiting slot reporting.
android/src/main/java/com/oney/WebRTCModule/WebRTCModule.java Updates RN methods for Telecom (handle, fulfill/fail answer, end reason, hold, pending answer requestId).
android/src/main/java/com/oney/WebRTCModule/VoipController.java Extends VoIP push payload mapping with handle/avatarUrl; adds waiting-call declined event emission.
android/src/main/java/com/oney/WebRTCModule/voip/VoipPushRegistry.kt Extends push registry model (handle/avatarUrl) and buffers/reveals/discards waiting incoming calls.
android/src/main/java/com/oney/WebRTCModule/voip/VoipForegroundServiceController.kt Bridges call lifecycle into a unified foreground-service request object.
android/src/main/java/com/oney/WebRTCModule/voip/VoipForegroundRequest.java Defines immutable VoIP foreground-service state snapshot (connecting/connected/held).
android/src/main/java/com/oney/WebRTCModule/voip/PushNotificationService.kt Updates FCM parsing to include handle/avatarUrl and routes calls into current/waiting/rejected slots.
android/src/main/java/com/oney/WebRTCModule/voip/IncomingCallActivity.kt Adds waiting-call UI mode and avatar-refresh support.
android/src/main/java/com/oney/WebRTCModule/voip/FulfillRequestManager.kt Implements Android fulfill/cancel/timeout request tracking for parked answer actions.
android/src/main/java/com/oney/WebRTCModule/voip/EndCallNotificationReceiver.kt Adds waiting-call answer/decline actions and maps decline/hangup to DisconnectCause.
android/src/main/java/com/oney/WebRTCModule/voip/DialtonePlayer.kt Implements Android ringback tone playback during outgoing connect.
android/src/main/java/com/oney/WebRTCModule/voip/CallNotificationManager.kt Adds connecting/held/waiting notification variants, configurable small icon, and avatar support.
android/src/main/java/com/oney/WebRTCModule/voip/CallManager.kt Major lifecycle updates: connecting state, timeouts, waiting call flow, fulfill-answer handshake, ringback, avatar loading.
android/src/main/java/com/oney/WebRTCModule/voip/AvatarLoader.kt Adds off-main-thread avatar download and circular crop for notifications/full-screen UI.
android/src/main/java/com/oney/WebRTCModule/TelecomController.java Wires new Telecom operations/events (handle, fulfill/fail, end reason, hold, pending requestId).
android/src/main/java/com/oney/WebRTCModule/foregroundService/WebRTCForegroundService.java Switches VoIP foreground notification rendering to VoipForegroundRequest state.
android/src/main/java/com/oney/WebRTCModule/foregroundService/ForegroundServiceController.java Replaces ad-hoc call state with VoipForegroundRequest and adds held tracking.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ios/RCTWebRTC/VoipManager.m
Comment thread ios/RCTWebRTC/WebRTCModule+CallKit.m
@Magmusacy Magmusacy changed the title Handle common VoIP patterns [FCE-3435] Handle common VoIP patterns Jul 16, 2026
Magmusacy and others added 2 commits July 17, 2026 11:43
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@Magmusacy
Magmusacy marked this pull request as ready for review July 17, 2026 14:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants